FreeCalypso > hg > themwi-system-sw
comparison mgw/readconf.c @ 32:b3f74df7b808
beginning of themwi-mgw
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Sat, 09 Jul 2022 22:51:44 -0800 | 
| parents | |
| children | f280328e7e2e | 
   comparison
  equal
  deleted
  inserted
  replaced
| 31:08d7794cdd0a | 32:b3f74df7b808 | 
|---|---|
| 1 /* | |
| 2 * In this module we implement the reading of /var/gsm/themwi-mgw.cfg: | |
| 3 * we parse and save the configured IP address and port range for each | |
| 4 * of our two sides, GSM and PSTN. | |
| 5 */ | |
| 6 | |
| 7 #include <sys/types.h> | |
| 8 #include <sys/socket.h> | |
| 9 #include <netinet/in.h> | |
| 10 #include <arpa/inet.h> | |
| 11 #include <ctype.h> | |
| 12 #include <stdio.h> | |
| 13 #include <stdlib.h> | |
| 14 #include <string.h> | |
| 15 #include <strings.h> | |
| 16 #include "struct.h" | |
| 17 | |
| 18 struct bind_range_cfg bind_range_gsm, bind_range_pstn; | |
| 19 | |
| 20 static char config_file_pathname[] = "/var/gsm/themwi-mgw.cfg"; | |
| 21 | |
| 22 struct parse_state { | |
| 23 int lineno; | |
| 24 int set_mask; | |
| 25 }; | |
| 26 | |
| 27 static void | |
| 28 handle_bind_ip(st, kw, brc, line) | |
| 29 struct parse_state *st; | |
| 30 char *kw, *line; | |
| 31 struct bind_range_cfg *brc; | |
| 32 { | |
| 33 char *cp, *np; | |
| 34 | |
| 35 for (cp = line; isspace(*cp); cp++) | |
| 36 ; | |
| 37 if (*cp == '\0' || *cp == '#') { | |
| 38 inv_syntax: fprintf(stderr, | |
| 39 "%s line %d: %s setting requires one argument\n", | |
| 40 config_file_pathname, st->lineno, kw); | |
| 41 exit(1); | |
| 42 } | |
| 43 for (np = cp; *cp && !isspace(*cp); cp++) | |
| 44 ; | |
| 45 if (*cp) | |
| 46 *cp++ = '\0'; | |
| 47 while (isspace(*cp)) | |
| 48 cp++; | |
| 49 if (*cp != '\0' && *cp != '#') | |
| 50 goto inv_syntax; | |
| 51 brc->bind_ip.s_addr = inet_addr(np); | |
| 52 if (brc->bind_ip.s_addr == INADDR_NONE) { | |
| 53 fprintf(stderr, | |
| 54 "%s line %d: invalid IP address argument \"%s\"\n", | |
| 55 config_file_pathname, st->lineno, np); | |
| 56 exit(1); | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 static void | |
| 61 handle_port_range(st, kw, brc, line) | |
| 62 struct parse_state *st; | |
| 63 char *kw, *line; | |
| 64 struct bind_range_cfg *brc; | |
| 65 { | |
| 66 char *cp, *np1, *np2; | |
| 67 | |
| 68 for (cp = line; isspace(*cp); cp++) | |
| 69 ; | |
| 70 if (!isdigit(*cp)) { | |
| 71 inv_syntax: fprintf(stderr, | |
| 72 "%s line %d: %s setting requires two numeric arguments\n", | |
| 73 config_file_pathname, st->lineno, kw); | |
| 74 exit(1); | |
| 75 } | |
| 76 for (np1 = cp; isdigit(*cp); cp++) | |
| 77 ; | |
| 78 if (!isspace(*cp)) | |
| 79 goto inv_syntax; | |
| 80 while (isspace(*cp)) | |
| 81 cp++; | |
| 82 if (!isdigit(*cp)) | |
| 83 goto inv_syntax; | |
| 84 for (np2 = cp; isdigit(*cp); cp++) | |
| 85 ; | |
| 86 if (*cp && !isspace(*cp)) | |
| 87 goto inv_syntax; | |
| 88 while (isspace(*cp)) | |
| 89 cp++; | |
| 90 if (*cp != '\0' && *cp != '#') | |
| 91 goto inv_syntax; | |
| 92 brc->port_range_start = atoi(np1); | |
| 93 brc->port_range_end = atoi(np2); | |
| 94 if (brc->port_range_start & 1) { | |
| 95 fprintf(stderr, "%s line %d: start port must be even\n", | |
| 96 config_file_pathname, st->lineno); | |
| 97 exit(1); | |
| 98 } | |
| 99 if (!(brc->port_range_end & 1)) { | |
| 100 fprintf(stderr, "%s line %d: end port must be odd\n", | |
| 101 config_file_pathname, st->lineno); | |
| 102 exit(1); | |
| 103 } | |
| 104 if (brc->port_range_end <= brc->port_range_start) { | |
| 105 fprintf(stderr, | |
| 106 "%s line %d: end port must be greater than start port\n", | |
| 107 config_file_pathname, st->lineno); | |
| 108 exit(1); | |
| 109 } | |
| 110 brc->port_next = brc->port_range_start; | |
| 111 brc->port_tries = (brc->port_range_end - brc->port_range_start + 1) / 2; | |
| 112 } | |
| 113 | |
| 114 static void | |
| 115 process_line(st, line) | |
| 116 struct parse_state *st; | |
| 117 char *line; | |
| 118 { | |
| 119 char *cp, *np; | |
| 120 void (*handler)(); | |
| 121 struct bind_range_cfg *ipside; | |
| 122 int set_id; | |
| 123 | |
| 124 if (!index(line, '\n')) { | |
| 125 fprintf(stderr, "%s line %d: too long or missing newline\n", | |
| 126 config_file_pathname, st->lineno); | |
| 127 exit(1); | |
| 128 } | |
| 129 for (cp = line; isspace(*cp); cp++) | |
| 130 ; | |
| 131 if (*cp == '\0' || *cp == '#') | |
| 132 return; | |
| 133 for (np = cp; *cp && !isspace(*cp); cp++) | |
| 134 ; | |
| 135 if (*cp) | |
| 136 *cp++ = '\0'; | |
| 137 if (!strcmp(np, "gsm-ip-addr")) { | |
| 138 handler = handle_bind_ip; | |
| 139 ipside = &bind_range_gsm; | |
| 140 set_id = 1; | |
| 141 } else if (!strcmp(np, "gsm-port-range")) { | |
| 142 handler = handle_port_range; | |
| 143 ipside = &bind_range_gsm; | |
| 144 set_id = 2; | |
| 145 } else if (!strcmp(np, "pstn-ip-addr")) { | |
| 146 handler = handle_bind_ip; | |
| 147 ipside = &bind_range_pstn; | |
| 148 set_id = 4; | |
| 149 } else if (!strcmp(np, "pstn-port-range")) { | |
| 150 handler = handle_port_range; | |
| 151 ipside = &bind_range_pstn; | |
| 152 set_id = 8; | |
| 153 } else { | |
| 154 fprintf(stderr, "%s line %d: non-understood keyword \"%s\"\n", | |
| 155 config_file_pathname, st->lineno, np); | |
| 156 exit(1); | |
| 157 } | |
| 158 if (st->set_mask & set_id) { | |
| 159 fprintf(stderr, "%s line %d: duplicate %s setting\n", | |
| 160 config_file_pathname, st->lineno, np); | |
| 161 exit(1); | |
| 162 } | |
| 163 handler(st, np, ipside, cp); | |
| 164 st->set_mask |= set_id; | |
| 165 } | |
| 166 | |
| 167 read_config_file() | |
| 168 { | |
| 169 FILE *inf; | |
| 170 struct parse_state pst; | |
| 171 char linebuf[256]; | |
| 172 | |
| 173 inf = fopen(config_file_pathname, "r"); | |
| 174 if (!inf) { | |
| 175 perror(config_file_pathname); | |
| 176 exit(1); | |
| 177 } | |
| 178 pst.set_mask = 0; | |
| 179 for (pst.lineno = 1; fgets(linebuf, sizeof linebuf, inf); pst.lineno++) | |
| 180 process_line(&pst, linebuf); | |
| 181 fclose(inf); | |
| 182 if (pst.set_mask != 15) { | |
| 183 fprintf(stderr, "error: %s did not set all required settings\n", | |
| 184 config_file_pathname); | |
| 185 exit(1); | |
| 186 } | |
| 187 } | 
