# HG changeset patch # User Mychaela Falconia # Date 1615936957 0 # Node ID ca8a6f95826a8f1850d0b219c2d55fc9104acf71 # Parent 322f6fcdc36ef69856866a3395b8eb14528a14d8 implemented sws-card-lookup and underlying libutil functions diff -r 322f6fcdc36e -r ca8a6f95826a .hgignore --- a/.hgignore Tue Mar 16 00:40:10 2021 +0000 +++ b/.hgignore Tue Mar 16 23:22:37 2021 +0000 @@ -15,4 +15,5 @@ ^utils/sim-iccid-mkfull$ ^utils/sim-iccid-mkrange$ +^utils/sws-card-lookup$ ^utils/sws-email2db$ diff -r 322f6fcdc36e -r ca8a6f95826a libutil/Makefile --- a/libutil/Makefile Tue Mar 16 00:40:10 2021 +0000 +++ b/libutil/Makefile Tue Mar 16 23:22:37 2021 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -OBJS= alpha_decode.o alpha_fromfile.o alpha_valid.o decimal_incr.o \ +OBJS= alpha_decode.o alpha_fromfile.o alpha_valid.o dbread.o decimal_incr.o \ decimal_str.o filesearch.o gsm7_decode.o gsm7_encode.o \ gsm7_encode_table.o gsm7_pack.o gsm7_unpack.o hexdigits.o hexread.o \ hexstr.o iccid_luhn.o nibbles2asc.o number_decode.o number_encode.o \ diff -r 322f6fcdc36e -r ca8a6f95826a libutil/dbread.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libutil/dbread.c Tue Mar 16 23:22:37 2021 +0000 @@ -0,0 +1,110 @@ +/* + * This module implements functions for reading key=value database files. + */ + +#include +#include +#include +#include +#include +#include "dbread.h" + +static +parse_read_line(dbs, filename_for_errs, lineno_for_errs) + struct dbread_state *dbs; + char *filename_for_errs; + int lineno_for_errs; +{ + unsigned n; + char *cp, *np; + + n = 0; + for (cp = dbs->linebuf; ; ) { + while (isspace(*cp)) + cp++; + if (!*cp) + break; + if (*cp == '=') { +inv_syntax: fprintf(stderr, "%s line %d: invalid syntax\n", + filename_for_errs, lineno_for_errs); + return(-1); + } + for (np = cp; ; cp++) { + if (*cp == '=') + break; + if (!*cp || isspace(*cp)) + goto inv_syntax; + } + *cp++ = '\0'; + if (n >= DBREAD_MAX_KV_PAIRS) { + fprintf(stderr, + "%s line %d: too many key=value pairs\n", + filename_for_errs, lineno_for_errs); + return(-1); + } + dbs->kv_pairs[n].key = np; + dbs->kv_pairs[n].value = cp; + n++; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + } + dbs->num_kv_pairs = n; + return(0); +} + +char * +dbread_find_key(dbs, sought_key) + struct dbread_state *dbs; + char *sought_key; +{ + unsigned n; + + for (n = 0; n < dbs->num_kv_pairs; n++) + if (!strcasecmp(dbs->kv_pairs[n].key, sought_key)) + return dbs->kv_pairs[n].value; + return 0; +} + +dbread_find_record(filename, dbs, sought_key, sought_value) + char *filename, *sought_key, *sought_value; + struct dbread_state *dbs; +{ + FILE *inf; + int lineno; + char *cp; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + return(-1); + } + for (lineno = 1; fgets(dbs->linebuf, DBREAD_LINEBUF_SIZE, inf); + lineno++) { + if (!index(dbs->linebuf, '\n')) { + fprintf(stderr, + "%s line %d: too long or missing newline\n", + filename, lineno); + fclose(inf); + return(-1); + } + if (parse_read_line(dbs, filename, lineno) < 0) { + /* error msg already printed */ + fclose(inf); + return(-1); + } + cp = dbread_find_key(dbs, sought_key); + if (!cp) + continue; + if (strcmp(cp, sought_value)) + continue; + /* found our record: struct dbread_state is our return */ + fclose(inf); + return(0); + } + fclose(inf); + fprintf(stderr, "error: %s=%s not found in %s\n", sought_key, + sought_value, filename); + return(-1); +} diff -r 322f6fcdc36e -r ca8a6f95826a libutil/dbread.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libutil/dbread.h Tue Mar 16 23:22:37 2021 +0000 @@ -0,0 +1,20 @@ +/* + * This header file defines the structure used for reading + * key=value database files. + */ + +#define DBREAD_LINEBUF_SIZE 1024 +#define DBREAD_MAX_KV_PAIRS 32 + +struct dbread_kv { + char *key; + char *value; +}; + +struct dbread_state { + char linebuf[DBREAD_LINEBUF_SIZE]; + struct dbread_kv kv_pairs[DBREAD_MAX_KV_PAIRS]; + unsigned num_kv_pairs; +}; + +extern char *dbread_find_key(); diff -r 322f6fcdc36e -r ca8a6f95826a utils/Makefile --- a/utils/Makefile Tue Mar 16 00:40:10 2021 +0000 +++ b/utils/Makefile Tue Mar 16 23:22:37 2021 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -PROGS= sim-iccid-mkfull sim-iccid-mkrange sws-email2db +PROGS= sim-iccid-mkfull sim-iccid-mkrange sws-card-lookup sws-email2db LIBUTIL=../libutil/libutil.a INSTALL_PREFIX= /opt/freecalypso @@ -15,6 +15,9 @@ sim-iccid-mkrange: sim-iccid-mkrange.o ${LIBUTIL} ${CC} ${CFLAGS} -o $@ $@.o ${LIBUTIL} +sws-card-lookup: sws-card-lookup.o ${LIBUTIL} + ${CC} ${CFLAGS} -o $@ $@.o ${LIBUTIL} + sws-email2db: sws-email2db.c ${CC} ${CFLAGS} -o $@ $@.c diff -r 322f6fcdc36e -r ca8a6f95826a utils/sws-card-lookup.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/sws-card-lookup.c Tue Mar 16 23:22:37 2021 +0000 @@ -0,0 +1,101 @@ +/* + * This program is a simple command line utility for looking up a card + * in sws-card-db (database generated with sws-email2db) by either + * ICCID or IMSI and retrieving other associated database fields. + */ + +#include +#include +#include +#include +#include +#include "../libutil/dbread.h" + +static char sws_card_db_file[] = "/opt/freecalypso/sim-data/sws-card-db"; + +static char *match_key, match_value[20]; +static struct dbread_state dbs; + +static void +preen_iccid(arg) + char *arg; +{ + u_char nibbles[19]; + + if (parse_decimal_shorthand(arg, nibbles, 19) < 0) + exit(1); /* error msg already printed */ + if (nibbles[18] != compute_iccid_luhn(nibbles)) { + fprintf(stderr, "error: Luhn check digit mismatch\n"); + exit(1); + } + nibbles_to_ascii(nibbles, 19, match_value); +} + +static void +preen_imsi(arg) + char *arg; +{ + u_char nibbles[15]; + + if (parse_decimal_shorthand(arg, nibbles, 15) < 0) + exit(1); /* error msg already printed */ + nibbles_to_ascii(nibbles, 15, match_value); +} + +static void +lookup_one_key(key) + char *key; +{ + char *val; + + val = dbread_find_key(&dbs, key); + if (!val) { + fprintf(stderr, "error: card record has no %s field\n", key); + exit(1); + } + puts(val); +} + +static void +lookup_mult_keys(keys) + char **keys; +{ + char *key, *val; + + for (; *keys; keys++) { + key = *keys; + val = dbread_find_key(&dbs, key); + if (val) + printf("%s=%s\n", key, val); + } +} + +main(argc, argv) + char **argv; +{ + int rc; + + if (argc < 4) { + fprintf(stderr, + "usage: %s {iccid|imsi} card-number retrieve-key\n", + argv[0]); + exit(1); + } + match_key = argv[1]; + if (!strcmp(match_key, "iccid")) + preen_iccid(argv[2]); + else if (!strcmp(match_key, "imsi")) + preen_imsi(argv[2]); + else { + fprintf(stderr, "error: look-up key must be iccid or imsi\n"); + exit(1); + } + rc = dbread_find_record(sws_card_db_file, &dbs, match_key, match_value); + if (rc < 0) + exit(1); /* error msg already printed */ + if (argc == 4) + lookup_one_key(argv[3]); + else + lookup_mult_keys(argv + 3); + exit(0); +}