changeset 87:bc862d41f96b

pb-restore command implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 17 Feb 2021 07:04:05 +0000
parents bd19dc7591ec
children ae831b21ef77
files simtool/Makefile simtool/dispatch.c simtool/pbrestore.c simtool/pbupd_file.c
diffstat 4 files changed, 205 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/simtool/Makefile	Wed Feb 17 06:39:20 2021 +0000
+++ b/simtool/Makefile	Wed Feb 17 07:04:05 2021 +0000
@@ -3,7 +3,7 @@
 PROG=	fc-simtool
 OBJS=	a38.o chv.o chvext.o curfile.o dispatch.o dumpdir.o grcard1.o grcard2.o\
 	hlread.o lndwrite.o main.o miscadm.o opldump.o pbcommon.o pbdump.o \
-	pberase.o pbupd_file.o pbupd_imm.o pbupd_immhex.o plmnsel.o pnndump.o \
+	pberase.o pbrestore.o pbupd_imm.o pbupd_immhex.o plmnsel.o pnndump.o \
 	readcmd.o readops.o restorebin.o savebin.o script.o select.o smserase.o\
 	smsp_common.o smsp_dump.o smsp_erase.o smsp_restore.o smsp_set.o \
 	sstlist.o sysmo.o telsum.o usersum.o writecmd.o writeops.o
--- a/simtool/dispatch.c	Wed Feb 17 06:39:20 2021 +0000
+++ b/simtool/dispatch.c	Wed Feb 17 07:04:05 2021 +0000
@@ -34,6 +34,7 @@
 extern int cmd_pb_erase();
 extern int cmd_pb_erase_one();
 extern int cmd_pb_erase_range();
+extern int cmd_pb_restore();
 extern int cmd_pb_update();
 extern int cmd_pb_update_imm();
 extern int cmd_pb_update_imm_hex();
@@ -123,6 +124,7 @@
 	{"pb-erase", 1, 1, cmd_pb_erase},
 	{"pb-erase-one", 2, 2, cmd_pb_erase_one},
 	{"pb-erase-range", 3, 3, cmd_pb_erase_range},
+	{"pb-restore", 2, 2, cmd_pb_restore},
 	{"pb-update", 2, 2, cmd_pb_update},
 	{"pb-update-imm", 3, 4, cmd_pb_update_imm},
 	{"pb-update-imm-hex", 4, 4, cmd_pb_update_imm_hex},
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simtool/pbrestore.c	Wed Feb 17 07:04:05 2021 +0000
@@ -0,0 +1,202 @@
+/*
+ * This module implements pb-restore and pb-update commands.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "curfile.h"
+
+extern char *alpha_from_file_qstring();
+extern char *alpha_from_file_hex();
+
+static
+process_record(line, bin_file_buf, filename_for_errs, lineno_for_errs)
+	char *line, *filename_for_errs;
+	u_char *bin_file_buf;
+{
+	unsigned recno;
+	u_char record[255], *fixp;
+	u_char digits[20];
+	unsigned ndigits, num_digit_bytes;
+	char *cp;
+	int c;
+
+	recno = strtoul(line+1, 0, 10);
+	if (recno < 1 || recno > curfile_record_count) {
+		fprintf(stderr, "%s line %d: record number is out of range\n",
+			filename_for_errs, lineno_for_errs);
+		return(-1);
+	}
+	cp = line + 1;
+	while (isdigit(*cp))
+		cp++;
+	if (*cp++ != ':') {
+inv_syntax:	fprintf(stderr, "%s line %d: invalid syntax\n",
+			filename_for_errs, lineno_for_errs);
+		return(-1);
+	}
+	while (isspace(*cp))
+		cp++;
+	memset(record, 0xFF, curfile_record_len);
+	fixp = record + curfile_record_len - 14;
+	if (digit_char_to_gsm(*cp) < 0)
+		goto inv_syntax;
+	for (ndigits = 0; ; ndigits++) {
+		c = digit_char_to_gsm(*cp);
+		if (c < 0)
+			break;
+		cp++;
+		if (ndigits >= 20) {
+			fprintf(stderr, "%s line %d: too many number digits\n",
+				filename_for_errs, lineno_for_errs);
+			return(-1);
+		}
+		digits[ndigits] = c;
+	}
+	if (ndigits & 1)
+		digits[ndigits++] = 0xF;
+	num_digit_bytes = ndigits >> 1;
+	fixp[0] = num_digit_bytes + 1;
+	pack_digit_bytes(digits, fixp + 2, num_digit_bytes);
+	if (*cp++ != ',')
+		goto inv_syntax;
+	if (cp[0] != '0' || cp[1] != 'x' && cp[1] != 'X' || !isxdigit(cp[2]) ||
+	    !isxdigit(cp[3]) || !isspace(cp[4]))
+		goto inv_syntax;
+	fixp[1] = strtoul(cp, 0, 16);
+	cp += 5;
+	while (isspace(*cp))
+		cp++;
+	if (!strncasecmp(cp, "CCP=", 4)) {
+		cp += 4;
+		fixp[12] = strtoul(cp, 0, 0);
+		while (*cp && !isspace(*cp))
+			cp++;
+		while (isspace(*cp))
+			cp++;
+	}
+	if (!strncasecmp(cp, "EXT=", 4)) {
+		cp += 4;
+		fixp[13] = strtoul(cp, 0, 0);
+		while (*cp && !isspace(*cp))
+			cp++;
+		while (isspace(*cp))
+			cp++;
+	}
+	if (*cp == '"') {
+		cp++;
+		cp = alpha_from_file_qstring(cp, record,
+					     curfile_record_len - 14,
+					     filename_for_errs,
+					     lineno_for_errs);
+		if (!cp)
+			return(-1);
+	} else if (!strncasecmp(cp, "HEX", 3)) {
+		cp += 3;
+		while (isspace(*cp))
+			cp++;
+		cp = alpha_from_file_hex(cp, record, curfile_record_len - 14,
+					 filename_for_errs, lineno_for_errs);
+		if (!cp)
+			return(-1);
+	} else
+		goto inv_syntax;
+	while (isspace(*cp))
+		cp++;
+	if (*cp)
+		goto inv_syntax;
+	if (bin_file_buf) {
+		bcopy(record, bin_file_buf + (recno - 1) * curfile_record_len,
+			curfile_record_len);
+		return(0);
+	} else
+		return update_rec_op(recno, 0x04, record, curfile_record_len);
+}
+
+cmd_pb_restore(argc, argv)
+	char **argv;
+{
+	int rc;
+	FILE *inf;
+	int lineno;
+	char linebuf[1024];
+	u_char *databuf;
+
+	rc = phonebook_op_common(argv[1]);
+	if (rc < 0)
+		return(rc);
+	databuf = malloc(curfile_total_size);
+	if (!databuf) {
+		perror("malloc for full phonebook EF");
+		return(-1);
+	}
+	inf = fopen(argv[2], "r");
+	if (!inf) {
+		perror(argv[2]);
+		free(databuf);
+		return(-1);
+	}
+	memset(databuf, 0xFF, curfile_total_size);
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		if (!index(linebuf, '\n')) {
+			fprintf(stderr,
+				"%s line %d: too long or missing newline\n",
+				argv[2], lineno);
+			fclose(inf);
+			free(databuf);
+			return(-1);
+		}
+		if (linebuf[0] != '#' || !isdigit(linebuf[1]))
+			continue;
+		rc = process_record(linebuf, databuf, argv[2], lineno);
+		if (rc < 0) {
+			fclose(inf);
+			free(databuf);
+			return(rc);
+		}
+	}
+	fclose(inf);
+	rc = restore_bin_records(databuf);
+	free(databuf);
+	return(rc);
+}
+
+cmd_pb_update(argc, argv)
+	char **argv;
+{
+	int rc;
+	FILE *inf;
+	int lineno;
+	char linebuf[1024];
+
+	rc = phonebook_op_common(argv[1]);
+	if (rc < 0)
+		return(rc);
+	inf = fopen(argv[2], "r");
+	if (!inf) {
+		perror(argv[2]);
+		return(-1);
+	}
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		if (!index(linebuf, '\n')) {
+			fprintf(stderr,
+				"%s line %d: too long or missing newline\n",
+				argv[2], lineno);
+			fclose(inf);
+			return(-1);
+		}
+		if (linebuf[0] != '#' || !isdigit(linebuf[1]))
+			continue;
+		rc = process_record(linebuf, 0, argv[2], lineno);
+		if (rc < 0) {
+			fclose(inf);
+			return(rc);
+		}
+	}
+	fclose(inf);
+	return(0);
+}
--- a/simtool/pbupd_file.c	Wed Feb 17 06:39:20 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * This module implements the original read-from-file pb-update command.
- */
-
-#include <sys/types.h>
-#include <ctype.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "curfile.h"
-
-extern char *alpha_from_file_qstring();
-extern char *alpha_from_file_hex();
-
-static
-process_record(line, filename_for_errs, lineno_for_errs)
-	char *line, *filename_for_errs;
-{
-	unsigned recno;
-	u_char record[255], *fixp;
-	u_char digits[20];
-	unsigned ndigits, num_digit_bytes;
-	char *cp;
-	int c;
-
-	recno = strtoul(line+1, 0, 10);
-	if (recno < 1 || recno > curfile_record_count) {
-		fprintf(stderr, "%s line %d: record number is out of range\n",
-			filename_for_errs, lineno_for_errs);
-		return(-1);
-	}
-	cp = line + 1;
-	while (isdigit(*cp))
-		cp++;
-	if (*cp++ != ':') {
-inv_syntax:	fprintf(stderr, "%s line %d: invalid syntax\n",
-			filename_for_errs, lineno_for_errs);
-		return(-1);
-	}
-	while (isspace(*cp))
-		cp++;
-	memset(record, 0xFF, curfile_record_len);
-	fixp = record + curfile_record_len - 14;
-	if (digit_char_to_gsm(*cp) < 0)
-		goto inv_syntax;
-	for (ndigits = 0; ; ndigits++) {
-		c = digit_char_to_gsm(*cp);
-		if (c < 0)
-			break;
-		cp++;
-		if (ndigits >= 20) {
-			fprintf(stderr, "%s line %d: too many number digits\n",
-				filename_for_errs, lineno_for_errs);
-			return(-1);
-		}
-		digits[ndigits] = c;
-	}
-	if (ndigits & 1)
-		digits[ndigits++] = 0xF;
-	num_digit_bytes = ndigits >> 1;
-	fixp[0] = num_digit_bytes + 1;
-	pack_digit_bytes(digits, fixp + 2, num_digit_bytes);
-	if (*cp++ != ',')
-		goto inv_syntax;
-	if (cp[0] != '0' || cp[1] != 'x' && cp[1] != 'X' || !isxdigit(cp[2]) ||
-	    !isxdigit(cp[3]) || !isspace(cp[4]))
-		goto inv_syntax;
-	fixp[1] = strtoul(cp, 0, 16);
-	cp += 5;
-	while (isspace(*cp))
-		cp++;
-	if (!strncasecmp(cp, "CCP=", 4)) {
-		cp += 4;
-		fixp[12] = strtoul(cp, 0, 0);
-		while (*cp && !isspace(*cp))
-			cp++;
-		while (isspace(*cp))
-			cp++;
-	}
-	if (!strncasecmp(cp, "EXT=", 4)) {
-		cp += 4;
-		fixp[13] = strtoul(cp, 0, 0);
-		while (*cp && !isspace(*cp))
-			cp++;
-		while (isspace(*cp))
-			cp++;
-	}
-	if (*cp == '"') {
-		cp++;
-		cp = alpha_from_file_qstring(cp, record,
-					     curfile_record_len - 14,
-					     filename_for_errs,
-					     lineno_for_errs);
-		if (!cp)
-			return(-1);
-	} else if (!strncasecmp(cp, "HEX", 3)) {
-		cp += 3;
-		while (isspace(*cp))
-			cp++;
-		cp = alpha_from_file_hex(cp, record, curfile_record_len - 14,
-					 filename_for_errs, lineno_for_errs);
-		if (!cp)
-			return(-1);
-	} else
-		goto inv_syntax;
-	while (isspace(*cp))
-		cp++;
-	if (*cp)
-		goto inv_syntax;
-	return update_rec_op(recno, 0x04, record, curfile_record_len);
-}
-
-cmd_pb_update(argc, argv)
-	char **argv;
-{
-	int rc;
-	FILE *inf;
-	int lineno;
-	char linebuf[1024];
-
-	rc = phonebook_op_common(argv[1]);
-	if (rc < 0)
-		return(rc);
-	inf = fopen(argv[2], "r");
-	if (!inf) {
-		perror(argv[2]);
-		return(-1);
-	}
-	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
-		if (!index(linebuf, '\n')) {
-			fprintf(stderr,
-				"%s line %d: too long or missing newline\n",
-				argv[2], lineno);
-			fclose(inf);
-			return(-1);
-		}
-		if (linebuf[0] != '#' || !isdigit(linebuf[1]))
-			continue;
-		rc = process_record(linebuf, argv[2], lineno);
-		if (rc < 0) {
-			fclose(inf);
-			return(rc);
-		}
-	}
-	fclose(inf);
-	return(0);
-}