changeset 27:ca8a6f95826a

implemented sws-card-lookup and underlying libutil functions
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 16 Mar 2021 23:22:37 +0000
parents 322f6fcdc36e
children fa81221ac9b6
files .hgignore libutil/Makefile libutil/dbread.c libutil/dbread.h utils/Makefile utils/sws-card-lookup.c
diffstat 6 files changed, 237 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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$
--- 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 \
--- /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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#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);
+}
--- /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();
--- 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
 
--- /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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#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);
+}