FreeCalypso > hg > themwi-rtp-mgr
view 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 source
/* * 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); } }