FreeCalypso > hg > sipout-test-utils
diff test-voice/readconf.c @ 0:35c0d9f03c0a
beginning with sipout-test-voice,
a copy of sip-manual-out from themwi-system-sw
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Mar 2024 23:20:19 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-voice/readconf.c Sun Mar 03 23:20:19 2024 -0800 @@ -0,0 +1,159 @@ +/* + * In this module we implement the reading of destination configuration + * for sip-manual-out. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +struct in_addr sip_bind_ip, sip_dest_ip; +unsigned sip_bind_port, sip_dest_port = 5060; +char sip_dest_domain[64]; + +struct parse_state { + char *filename; + int lineno; + int set_mask; +}; + +static void +handle_ip(st, kw, var, arg) + struct parse_state *st; + char *kw, *arg; + struct in_addr *var; +{ + var->s_addr = inet_addr(arg); + if (var->s_addr == INADDR_NONE) { + fprintf(stderr, + "%s line %d: invalid IP address argument \"%s\"\n", + st->filename, st->lineno, arg); + exit(1); + } +} + +static void +handle_num(st, kw, var, arg) + struct parse_state *st; + char *kw, *arg; + unsigned *var; +{ + char *endp; + + *var = strtoul(arg, &endp, 10); + if (*endp) { + fprintf(stderr, "%s line %d: invalid numeric argument \"%s\"\n", + st->filename, st->lineno, arg); + exit(1); + } +} + +static void +handle_str(st, kw, var, arg) + struct parse_state *st; + char *kw, *arg, *var; +{ + strcpy(var, arg); +} + +static void +process_line(st, line) + struct parse_state *st; + char *line; +{ + char *cp, *np, *arg; + void (*handler)(), *var; + int set_id; + + if (!index(line, '\n')) { + fprintf(stderr, "%s line %d: too long or missing newline\n", + st->filename, 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, "bind-ip")) { + handler = handle_ip; + var = &sip_bind_ip; + set_id = 1; + } else if (!strcmp(np, "bind-port")) { + handler = handle_num; + var = &sip_bind_port; + set_id = 2; + } else if (!strcmp(np, "dest-ip")) { + handler = handle_ip; + var = &sip_dest_ip; + set_id = 4; + } else if (!strcmp(np, "dest-port")) { + handler = handle_num; + var = &sip_dest_port; + set_id = 0; + } else if (!strcmp(np, "dest-domain")) { + handler = handle_str; + var = sip_dest_domain; + set_id = 8; + } else { + fprintf(stderr, "%s line %d: non-understood keyword \"%s\"\n", + st->filename, st->lineno, np); + exit(1); + } + if (st->set_mask & set_id) { + fprintf(stderr, "%s line %d: duplicate %s setting\n", + st->filename, st->lineno, np); + exit(1); + } + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') { +inv_syntax: fprintf(stderr, + "%s line %d: %s setting requires one argument\n", + st->filename, st->lineno, np); + exit(1); + } + for (arg = cp; *cp && !isspace(*cp); cp++) + ; + if (*cp) + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp != '\0' && *cp != '#') + goto inv_syntax; + handler(st, np, var, arg); + st->set_mask |= set_id; +} + +read_config_file(filename) + char *filename; +{ + FILE *inf; + struct parse_state pst; + char linebuf[256]; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + exit(1); + } + pst.set_mask = 0; + pst.filename = filename; + 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", + filename); + exit(1); + } +}