view libcommon/alpha_fromfile.c @ 19:72a24b8538eb

meaty function of pb-dump moved back into simtool, out of libcommon Upon further reflection, I am not going to keep any of the pb-* commands in the new version of fc-uicc-tool: they are logically incorrect for UICC/USIM anyway, as they access phonebook files via old classic SIM paths, rather than their USIM paths. OTOH, I am going to implement new SMSP commands in fc-simtool, and I do not plan to replicate them in fc-uicc-tool either. Guts of fc-simtool pb-dump belong in simtool/pbdump.c, not in libcommon, just like the guts of the future smsp-dump command will belong in its own respective implementation module.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 12 Feb 2021 03:33:26 +0000
parents 2ef261371347
children 90e7020df08a
line wrap: on
line source

/*
 * This module implements functions for parsing alpha tag strings
 * from input data files, to be used by commands like pb-update
 * and smsp-restore.
 */

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>

extern u_char gsm7_encode_table[256];

char *
alpha_from_file_qstring(cp, record, maxlen, filename_for_errs, lineno_for_errs)
	char *cp, *filename_for_errs;
	u_char *record;
	unsigned maxlen;
{
	unsigned acclen, nadd;
	int c;

	for (acclen = 0; ; ) {
		if (*cp == '\0') {
unterm_qstring:		fprintf(stderr,
				"%s line %d: unterminated quoted string\n",
				filename_for_errs, lineno_for_errs);
			return(0);
		}
		if (*cp == '"')
			break;
		c = *cp++;
		if (c == '\\') {
			if (*cp == '\0')
				goto unterm_qstring;
			c = *cp++;
			switch (c) {
			case 'n':
				c = '\n';
				break;
			case 'r':
				c = '\r';
				break;
			case '"':
			case '\\':
				break;
			default:
				fprintf(stderr,
				"%s line %d: non-understood backslash escape\n",
					filename_for_errs, lineno_for_errs);
				return(0);
			}
		}
		c = gsm7_encode_table[c];
		if (c == 0xFF) {
			fprintf(stderr,
	"%s line %d: character in quoted string cannot be encoded in GSM7\n",
				filename_for_errs, lineno_for_errs);
			return(0);
		}
		if (c & 0x80)
			nadd = 2;
		else
			nadd = 1;
		if (acclen + nadd > maxlen) {
			fprintf(stderr,
		"%s line %d: alpha tag string is longer than SIM limit\n",
				filename_for_errs, lineno_for_errs);
			return(0);
		}
		if (c & 0x80)
			record[acclen++] = 0x1B;
		record[acclen++] = c & 0x7F;
	}
	return(cp + 1);
}

char *
alpha_from_file_hex(cp, record, maxlen, filename_for_errs, lineno_for_errs)
	char *cp, *filename_for_errs;
	u_char *record;
	unsigned maxlen;
{
	unsigned acclen;

	for (acclen = 0; ; ) {
		if (!isxdigit(cp[0]) || !isxdigit(cp[1]))
			break;
		if (acclen >= maxlen) {
			fprintf(stderr,
		"%s line %d: alpha tag string is longer than SIM limit\n",
				filename_for_errs, lineno_for_errs);
			return(0);
		}
		record[acclen++] = (decode_hex_digit(cp[0]) << 4) |
				    decode_hex_digit(cp[1]);
		cp += 2;
	}
	return(cp);
}