FreeCalypso > hg > themwi-system-sw
view sip-manual-out/readconf.c @ 110:c1c94b7fc2e2
sip-in call clearing: DEAD_SIP transition implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 28 Sep 2022 18:37:19 -0800 |
parents | d74b545a3c2a |
children |
line wrap: on
line source
/* * 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); } }