FreeCalypso > hg > themwi-system-sw
view utils/themwi-update-numdb.c @ 124:7e04d28fae8b
sip-in: default use-100rel to no
BulkVS servers act badly when we send a reliable 180 Ringing response
to an incoming call, even though they advertise 100rel support in
the Supported header in the INVITE packet, and we probably won't be
implementing 100rel for outbound because doing per-the-spec PRACK
as a UAC is just too burdensome. Therefore, we need to consider
100rel extension as not-really-supported in themwi-system-sw.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 01 Oct 2022 15:54:50 -0800 |
parents | 4ad5deafaa87 |
children |
line wrap: on
line source
/* * This program reads (parses) ThemWi config file /var/gsm/number-db, * generates the compiled binary form of this database, and then makes * it live via atomic rename. */ #include <ctype.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include "../include/number_db_file.h" #define MAX_OWNED_NUMBERS 1000 #define MAX_SHORT_NUMBERS 1000 static uint64_t owned_number_buf[MAX_OWNED_NUMBERS]; static struct short_number_map short_number_buf[MAX_SHORT_NUMBERS]; static unsigned owned_number_count, short_number_count; static char *system_dir; static FILE *inf; static int lineno; static char linebuf[256], prefix[7]; static int prefix_allows_abbrev; static uint32_t prefix_int; static void enter_owned_number(numstr) char *numstr; { if (owned_number_count >= MAX_OWNED_NUMBERS) { fprintf(stderr, "error: MAX_OWNED_NUMBERS exceeded\n"); exit(1); } owned_number_buf[owned_number_count++] = strtoull(numstr, 0, 10); } static void enter_short_number(numstr, prefix) char *numstr; uint32_t prefix; { if (short_number_count >= MAX_SHORT_NUMBERS) { fprintf(stderr, "error: MAX_SHORT_NUMBERS exceeded\n"); exit(1); } short_number_buf[short_number_count].short_code = strtoul(numstr, 0, 10); short_number_buf[short_number_count].prefix = prefix; short_number_count++; } static void handle_prefix_line(cp) char *cp; { char *np; for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (grok_number_string(np, 1) != 6) { fprintf(stderr, "number-db line %d: prefix requires 6-digit argument\n", lineno); exit(1); } dehyphen_number_string(np, prefix); if (!is_nanp_valid_prefix(prefix)) { fprintf(stderr, "number-db line %d: prefix violates NANP rules\n", lineno); exit(1); } while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') { prefix_allows_abbrev = 0; return; } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(np, "allow-abbrev")) { prefix_allows_abbrev = 1; prefix_int = strtoul(prefix, 0, 10); return; } fprintf(stderr, "number-db line %d: non-understood notation \"%s\" after prefix\n", lineno, np); exit(1); } static void handle_suffix_line(cp) char *cp; { char *np, full10[11]; if (!prefix[0]) { fprintf(stderr, "number-db line %d: suffix not valid without preceding prefix\n", lineno); exit(1); } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (grok_number_string(np, 0) != 4) { fprintf(stderr, "number-db line %d: suffix requires 4-digit argument\n", lineno); exit(1); } strcpy(full10, prefix); strcat(full10, np); enter_owned_number(full10); if (!prefix_allows_abbrev) return; enter_short_number(np, prefix_int); } static void handle_full10_line(cp) char *cp; { char *np, full10[11]; prefix[0] = '\0'; /* cancel any previous prefix line */ for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (grok_number_string(np, 1) != 10) { fprintf(stderr, "number-db line %d: full10 requires 10-digit argument\n", lineno); exit(1); } dehyphen_number_string(np, full10); if (!is_nanp_valid_prefix(full10)) { fprintf(stderr, "number-db line %d: number violates NANP rules\n", lineno); exit(1); } enter_owned_number(full10); } static void handle_itn_line(cp) char *cp; { char *np; prefix[0] = '\0'; /* cancel any previous prefix line */ for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (grok_number_string(np, 0) != 4) { fprintf(stderr, "number-db line %d: itn requires 4-digit argument\n", lineno); exit(1); } enter_short_number(np, 0); } static void process_line() { char *cp, *np; void (*handler)(); if (!index(linebuf, '\n')) { fprintf(stderr, "number-db line %d: too long or missing newline\n", lineno); exit(1); } for (cp = linebuf; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') return; for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(np, "prefix")) handler = handle_prefix_line; else if (!strcmp(np, "suffix")) handler = handle_suffix_line; else if (!strcmp(np, "full10")) handler = handle_full10_line; else if (!strcmp(np, "itn")) handler = handle_itn_line; else { fprintf(stderr, "number-db line %d: non-understood keyword \"%s\"\n", lineno, np); exit(1); } while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') { fprintf(stderr, "number-db line %d: missing argument after \"%s\" keyword\n", lineno, np); exit(1); } handler(cp); } static int compare_owned_num(p1, p2) uint64_t *p1, *p2; { if (*p1 < *p2) return(-1); else if (*p1 > *p2) return(1); else return(0); } static int compare_short_num(p1, p2) struct short_number_map *p1, *p2; { if (p1->short_code < p2->short_code) return(-1); else if (p1->short_code > p2->short_code) return(1); else return(0); } static void owned_num_check_dup() { uint64_t *p, *endp; endp = owned_number_buf + owned_number_count - 1; for (p = owned_number_buf; p < endp; p++) { if (p[0] == p[1]) { fprintf(stderr, "error: NANP number %llu appears more than once\n", (unsigned long long) *p); exit(1); } } } static void short_num_check_dup() { struct short_number_map *p, *endp; endp = short_number_buf + short_number_count - 1; for (p = short_number_buf; p < endp; p++) { if (p[0].short_code == p[1].short_code) { fprintf(stderr, "error: short number %04u appears more than once\n", (unsigned) p->short_code); exit(1); } } } static void emit_output() { FILE *outf; struct numdb_file_hdr hdr; outf = fopen("number-db.newbin", "w"); if (!outf) { perror("creating number-db.newbin"); exit(1); } hdr.owned_number_count = owned_number_count; hdr.short_number_count = short_number_count; if (fwrite(&hdr, sizeof hdr, 1, outf) != 1) { write_err: fprintf(stderr, "error writing to new binary file\n"); exit(1); } if (fwrite(owned_number_buf, sizeof(owned_number_buf[0]), owned_number_count, outf) != owned_number_count) goto write_err; if (fwrite(short_number_buf, sizeof(short_number_buf[0]), short_number_count, outf) != short_number_count) goto write_err; fclose(outf); } main(argc, argv) char **argv; { if (argc > 2) { fprintf(stderr, "usage: %s [directory]\n", argv[0]); exit(1); } if (argv[1]) system_dir = argv[1]; else system_dir = "/var/gsm"; if (chdir(system_dir) < 0) { perror(system_dir); exit(1); } inf = fopen("number-db", "r"); if (!inf) { perror("opening number-db"); exit(1); } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) process_line(); fclose(inf); if (owned_number_count >= 2) { qsort(owned_number_buf, owned_number_count, sizeof(owned_number_buf[0]), compare_owned_num); owned_num_check_dup(); } if (short_number_count >= 2) { qsort(short_number_buf, short_number_count, sizeof(short_number_buf[0]), compare_short_num); short_num_check_dup(); } emit_output(); /* make it live */ if (rename("number-db.newbin", "number-db.bin") < 0) { perror("rename"); exit(1); } exit(0); }