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