diff libutil/alpha_fromfile.c @ 157:f064dbcc5f41

libutil split from libcommon
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 26 Feb 2021 20:19:58 +0000
parents libcommon/alpha_fromfile.c@90e7020df08a
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libutil/alpha_fromfile.c	Fri Feb 26 20:19:58 2021 +0000
@@ -0,0 +1,107 @@
+/*
+ * 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++;
+			if (c >= '0' && c <= '7' && isxdigit(*cp)) {
+				c = ((c - '0') << 4) | decode_hex_digit(*cp++);
+				goto bypass_encoding;
+			}
+			switch (c) {
+			case 'n':
+				c = '\n';
+				goto bypass_encoding;
+			case 'r':
+				c = '\r';
+				goto bypass_encoding;
+			case 'e':
+				c = 0x1B;
+				goto bypass_encoding;
+			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);
+		}
+bypass_encoding:
+		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);
+}