comparison 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
comparison
equal deleted inserted replaced
1:560a3765ab30 2:247f4bbde24c
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 <syslog.h>
19 #include "struct.h"
20
21 struct bind_range_cfg bind_range_gsm, bind_range_pstn;
22 int syslog_facility = LOG_USER;
23
24 static const char config_file_pathname[] = "/var/gsm/themwi-rtp.cfg";
25
26 struct parse_state {
27 int lineno;
28 int set_mask;
29 };
30
31 static void
32 handle_bind_ip(st, kw, brc, line)
33 struct parse_state *st;
34 char *kw, *line;
35 struct bind_range_cfg *brc;
36 {
37 char *cp, *np;
38
39 for (cp = line; isspace(*cp); cp++)
40 ;
41 if (*cp == '\0' || *cp == '#') {
42 inv_syntax: fprintf(stderr,
43 "%s line %d: %s setting requires one argument\n",
44 config_file_pathname, st->lineno, kw);
45 exit(1);
46 }
47 for (np = cp; *cp && !isspace(*cp); cp++)
48 ;
49 if (*cp)
50 *cp++ = '\0';
51 while (isspace(*cp))
52 cp++;
53 if (*cp != '\0' && *cp != '#')
54 goto inv_syntax;
55 brc->bind_ip.s_addr = inet_addr(np);
56 if (brc->bind_ip.s_addr == INADDR_NONE) {
57 fprintf(stderr,
58 "%s line %d: invalid IP address argument \"%s\"\n",
59 config_file_pathname, st->lineno, np);
60 exit(1);
61 }
62 }
63
64 static void
65 handle_port_range(st, kw, brc, line)
66 struct parse_state *st;
67 char *kw, *line;
68 struct bind_range_cfg *brc;
69 {
70 char *cp, *np1, *np2;
71
72 for (cp = line; isspace(*cp); cp++)
73 ;
74 if (!isdigit(*cp)) {
75 inv_syntax: fprintf(stderr,
76 "%s line %d: %s setting requires two numeric arguments\n",
77 config_file_pathname, st->lineno, kw);
78 exit(1);
79 }
80 for (np1 = cp; isdigit(*cp); cp++)
81 ;
82 if (!isspace(*cp))
83 goto inv_syntax;
84 while (isspace(*cp))
85 cp++;
86 if (!isdigit(*cp))
87 goto inv_syntax;
88 for (np2 = cp; isdigit(*cp); cp++)
89 ;
90 if (*cp && !isspace(*cp))
91 goto inv_syntax;
92 while (isspace(*cp))
93 cp++;
94 if (*cp != '\0' && *cp != '#')
95 goto inv_syntax;
96 brc->port_range_start = atoi(np1);
97 brc->port_range_end = atoi(np2);
98 if (brc->port_range_start & 1) {
99 fprintf(stderr, "%s line %d: start port must be even\n",
100 config_file_pathname, st->lineno);
101 exit(1);
102 }
103 if (!(brc->port_range_end & 1)) {
104 fprintf(stderr, "%s line %d: end port must be odd\n",
105 config_file_pathname, st->lineno);
106 exit(1);
107 }
108 if (brc->port_range_end <= brc->port_range_start) {
109 fprintf(stderr,
110 "%s line %d: end port must be greater than start port\n",
111 config_file_pathname, st->lineno);
112 exit(1);
113 }
114 brc->port_next = brc->port_range_start;
115 brc->port_tries = (brc->port_range_end - brc->port_range_start + 1) / 2;
116 }
117
118 static void
119 handle_syslog_facility(st, kw, dummy_ptr, line)
120 struct parse_state *st;
121 char *kw, *line;
122 void *dummy_ptr;
123 {
124 char *cp, *np;
125
126 for (cp = line; isspace(*cp); cp++)
127 ;
128 if (*cp == '\0' || *cp == '#') {
129 inv_syntax: fprintf(stderr,
130 "%s line %d: %s setting requires one argument\n",
131 config_file_pathname, st->lineno, kw);
132 exit(1);
133 }
134 for (np = cp; *cp && !isspace(*cp); cp++)
135 ;
136 if (*cp)
137 *cp++ = '\0';
138 while (isspace(*cp))
139 cp++;
140 if (*cp != '\0' && *cp != '#')
141 goto inv_syntax;
142 if (!strcmp(np, "authpriv"))
143 syslog_facility = LOG_AUTHPRIV;
144 else if (!strcmp(np, "cron"))
145 syslog_facility = LOG_CRON;
146 else if (!strcmp(np, "daemon"))
147 syslog_facility = LOG_DAEMON;
148 else if (!strcmp(np, "ftp"))
149 syslog_facility = LOG_FTP;
150 else if (!strcmp(np, "lpr"))
151 syslog_facility = LOG_LPR;
152 else if (!strcmp(np, "mail"))
153 syslog_facility = LOG_MAIL;
154 else if (!strcmp(np, "news"))
155 syslog_facility = LOG_NEWS;
156 else if (!strcmp(np, "user"))
157 syslog_facility = LOG_USER;
158 else if (!strcmp(np, "uucp"))
159 syslog_facility = LOG_UUCP;
160 else if (!strcmp(np, "local0"))
161 syslog_facility = LOG_LOCAL0;
162 else if (!strcmp(np, "local1"))
163 syslog_facility = LOG_LOCAL1;
164 else if (!strcmp(np, "local2"))
165 syslog_facility = LOG_LOCAL2;
166 else if (!strcmp(np, "local3"))
167 syslog_facility = LOG_LOCAL3;
168 else if (!strcmp(np, "local4"))
169 syslog_facility = LOG_LOCAL4;
170 else if (!strcmp(np, "local5"))
171 syslog_facility = LOG_LOCAL5;
172 else if (!strcmp(np, "local6"))
173 syslog_facility = LOG_LOCAL6;
174 else if (!strcmp(np, "local7"))
175 syslog_facility = LOG_LOCAL7;
176 else {
177 fprintf(stderr,
178 "%s line %d: \"%s\" is not a recognized syslog facility\n",
179 config_file_pathname, st->lineno, np);
180 exit(1);
181 }
182 }
183
184 static void
185 process_line(st, line)
186 struct parse_state *st;
187 char *line;
188 {
189 char *cp, *np;
190 void (*handler)();
191 struct bind_range_cfg *ipside;
192 int set_id;
193
194 if (!index(line, '\n')) {
195 fprintf(stderr, "%s line %d: too long or missing newline\n",
196 config_file_pathname, st->lineno);
197 exit(1);
198 }
199 for (cp = line; isspace(*cp); cp++)
200 ;
201 if (*cp == '\0' || *cp == '#')
202 return;
203 for (np = cp; *cp && !isspace(*cp); cp++)
204 ;
205 if (*cp)
206 *cp++ = '\0';
207 if (!strcmp(np, "gsm-ip-addr")) {
208 handler = handle_bind_ip;
209 ipside = &bind_range_gsm;
210 set_id = 1;
211 } else if (!strcmp(np, "gsm-port-range")) {
212 handler = handle_port_range;
213 ipside = &bind_range_gsm;
214 set_id = 2;
215 } else if (!strcmp(np, "pstn-ip-addr")) {
216 handler = handle_bind_ip;
217 ipside = &bind_range_pstn;
218 set_id = 4;
219 } else if (!strcmp(np, "pstn-port-range")) {
220 handler = handle_port_range;
221 ipside = &bind_range_pstn;
222 set_id = 8;
223 } else if (!strcmp(np, "syslog-facility")) {
224 handler = handle_syslog_facility;
225 ipside = NULL;
226 set_id = 0;
227 } else {
228 fprintf(stderr, "%s line %d: non-understood keyword \"%s\"\n",
229 config_file_pathname, st->lineno, np);
230 exit(1);
231 }
232 if (st->set_mask & set_id) {
233 fprintf(stderr, "%s line %d: duplicate %s setting\n",
234 config_file_pathname, st->lineno, np);
235 exit(1);
236 }
237 handler(st, np, ipside, cp);
238 st->set_mask |= set_id;
239 }
240
241 read_config_file()
242 {
243 FILE *inf;
244 struct parse_state pst;
245 char linebuf[256];
246
247 inf = fopen(config_file_pathname, "r");
248 if (!inf) {
249 perror(config_file_pathname);
250 exit(1);
251 }
252 pst.set_mask = 0;
253 for (pst.lineno = 1; fgets(linebuf, sizeof linebuf, inf); pst.lineno++)
254 process_line(&pst, linebuf);
255 fclose(inf);
256 if (pst.set_mask != 15) {
257 fprintf(stderr, "error: %s did not set all required settings\n",
258 config_file_pathname);
259 exit(1);
260 }
261 }