FreeCalypso > hg > themwi-rtp-mgr
diff rtp-mgr/readconf.c @ 2:247f4bbde24c
rtp-mgr: daemon ported over
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 27 May 2024 19:42:19 +0000 |
parents | |
children | 9499d41fc393 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtp-mgr/readconf.c Mon May 27 19:42:19 2024 +0000 @@ -0,0 +1,261 @@ +/* + * In this module we implement the reading of /var/gsm/themwi-rtp.cfg: + * we parse and save the configured IP address and port range for each + * of our two sides, GSM and PSTN. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <syslog.h> +#include "struct.h" + +struct bind_range_cfg bind_range_gsm, bind_range_pstn; +int syslog_facility = LOG_USER; + +static const char config_file_pathname[] = "/var/gsm/themwi-rtp.cfg"; + +struct parse_state { + int lineno; + int set_mask; +}; + +static void +handle_bind_ip(st, kw, brc, line) + struct parse_state *st; + char *kw, *line; + struct bind_range_cfg *brc; +{ + char *cp, *np; + + for (cp = line; isspace(*cp); cp++) + ; + if (*cp == '\0' || *cp == '#') { +inv_syntax: fprintf(stderr, + "%s line %d: %s setting requires one argument\n", + config_file_pathname, st->lineno, kw); + exit(1); + } + for (np = cp; *cp && !isspace(*cp); cp++) + ; + if (*cp) + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv_syntax; + brc->bind_ip.s_addr = inet_addr(np); + if (brc->bind_ip.s_addr == INADDR_NONE) { + fprintf(stderr, + "%s line %d: invalid IP address argument \"%s\"\n", + config_file_pathname, st->lineno, np); + exit(1); + } +} + +static void +handle_port_range(st, kw, brc, line) + struct parse_state *st; + char *kw, *line; + struct bind_range_cfg *brc; +{ + char *cp, *np1, *np2; + + for (cp = line; isspace(*cp); cp++) + ; + if (!isdigit(*cp)) { +inv_syntax: fprintf(stderr, + "%s line %d: %s setting requires two numeric arguments\n", + config_file_pathname, st->lineno, kw); + exit(1); + } + for (np1 = cp; isdigit(*cp); cp++) + ; + if (!isspace(*cp)) + goto inv_syntax; + while (isspace(*cp)) + cp++; + if (!isdigit(*cp)) + goto inv_syntax; + for (np2 = cp; isdigit(*cp); cp++) + ; + if (*cp && !isspace(*cp)) + goto inv_syntax; + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv_syntax; + brc->port_range_start = atoi(np1); + brc->port_range_end = atoi(np2); + if (brc->port_range_start & 1) { + fprintf(stderr, "%s line %d: start port must be even\n", + config_file_pathname, st->lineno); + exit(1); + } + if (!(brc->port_range_end & 1)) { + fprintf(stderr, "%s line %d: end port must be odd\n", + config_file_pathname, st->lineno); + exit(1); + } + if (brc->port_range_end <= brc->port_range_start) { + fprintf(stderr, + "%s line %d: end port must be greater than start port\n", + config_file_pathname, st->lineno); + exit(1); + } + brc->port_next = brc->port_range_start; + brc->port_tries = (brc->port_range_end - brc->port_range_start + 1) / 2; +} + +static void +handle_syslog_facility(st, kw, dummy_ptr, line) + struct parse_state *st; + char *kw, *line; + void *dummy_ptr; +{ + char *cp, *np; + + for (cp = line; isspace(*cp); cp++) + ; + if (*cp == '\0' || *cp == '#') { +inv_syntax: fprintf(stderr, + "%s line %d: %s setting requires one argument\n", + config_file_pathname, st->lineno, kw); + exit(1); + } + for (np = cp; *cp && !isspace(*cp); cp++) + ; + if (*cp) + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv_syntax; + if (!strcmp(np, "authpriv")) + syslog_facility = LOG_AUTHPRIV; + else if (!strcmp(np, "cron")) + syslog_facility = LOG_CRON; + else if (!strcmp(np, "daemon")) + syslog_facility = LOG_DAEMON; + else if (!strcmp(np, "ftp")) + syslog_facility = LOG_FTP; + else if (!strcmp(np, "lpr")) + syslog_facility = LOG_LPR; + else if (!strcmp(np, "mail")) + syslog_facility = LOG_MAIL; + else if (!strcmp(np, "news")) + syslog_facility = LOG_NEWS; + else if (!strcmp(np, "user")) + syslog_facility = LOG_USER; + else if (!strcmp(np, "uucp")) + syslog_facility = LOG_UUCP; + else if (!strcmp(np, "local0")) + syslog_facility = LOG_LOCAL0; + else if (!strcmp(np, "local1")) + syslog_facility = LOG_LOCAL1; + else if (!strcmp(np, "local2")) + syslog_facility = LOG_LOCAL2; + else if (!strcmp(np, "local3")) + syslog_facility = LOG_LOCAL3; + else if (!strcmp(np, "local4")) + syslog_facility = LOG_LOCAL4; + else if (!strcmp(np, "local5")) + syslog_facility = LOG_LOCAL5; + else if (!strcmp(np, "local6")) + syslog_facility = LOG_LOCAL6; + else if (!strcmp(np, "local7")) + syslog_facility = LOG_LOCAL7; + else { + fprintf(stderr, + "%s line %d: \"%s\" is not a recognized syslog facility\n", + config_file_pathname, st->lineno, np); + exit(1); + } +} + +static void +process_line(st, line) + struct parse_state *st; + char *line; +{ + char *cp, *np; + void (*handler)(); + struct bind_range_cfg *ipside; + int set_id; + + if (!index(line, '\n')) { + fprintf(stderr, "%s line %d: too long or missing newline\n", + config_file_pathname, st->lineno); + exit(1); + } + for (cp = line; isspace(*cp); cp++) + ; + if (*cp == '\0' || *cp == '#') + return; + for (np = cp; *cp && !isspace(*cp); cp++) + ; + if (*cp) + *cp++ = '\0'; + if (!strcmp(np, "gsm-ip-addr")) { + handler = handle_bind_ip; + ipside = &bind_range_gsm; + set_id = 1; + } else if (!strcmp(np, "gsm-port-range")) { + handler = handle_port_range; + ipside = &bind_range_gsm; + set_id = 2; + } else if (!strcmp(np, "pstn-ip-addr")) { + handler = handle_bind_ip; + ipside = &bind_range_pstn; + set_id = 4; + } else if (!strcmp(np, "pstn-port-range")) { + handler = handle_port_range; + ipside = &bind_range_pstn; + set_id = 8; + } else if (!strcmp(np, "syslog-facility")) { + handler = handle_syslog_facility; + ipside = NULL; + set_id = 0; + } else { + fprintf(stderr, "%s line %d: non-understood keyword \"%s\"\n", + config_file_pathname, st->lineno, np); + exit(1); + } + if (st->set_mask & set_id) { + fprintf(stderr, "%s line %d: duplicate %s setting\n", + config_file_pathname, st->lineno, np); + exit(1); + } + handler(st, np, ipside, cp); + st->set_mask |= set_id; +} + +read_config_file() +{ + FILE *inf; + struct parse_state pst; + char linebuf[256]; + + inf = fopen(config_file_pathname, "r"); + if (!inf) { + perror(config_file_pathname); + exit(1); + } + pst.set_mask = 0; + for (pst.lineno = 1; fgets(linebuf, sizeof linebuf, inf); pst.lineno++) + process_line(&pst, linebuf); + fclose(inf); + if (pst.set_mask != 15) { + fprintf(stderr, "error: %s did not set all required settings\n", + config_file_pathname); + exit(1); + } +}