FreeCalypso > hg > fc-pcsc-tools
changeset 13:d4f8c511affe
simtool: pbupdate.c split into separate modules for each command
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 12 Feb 2021 01:28:53 +0000 |
parents | 8a34f5b7c812 |
children | c34ecbbdf05e |
files | simtool/Makefile simtool/pbupd_file.c simtool/pbupd_imm.c simtool/pbupd_immhex.c simtool/pbupdate.c |
diffstat | 5 files changed, 404 insertions(+), 380 deletions(-) [+] |
line wrap: on
line diff
--- a/simtool/Makefile Fri Feb 12 01:15:22 2021 +0000 +++ b/simtool/Makefile Fri Feb 12 01:28:53 2021 +0000 @@ -2,8 +2,9 @@ CFLAGS= -O2 -I/usr/include/PCSC -I../libcommon PROG= fc-simtool OBJS= a38.o chv.o curfile.o dispatch.o dumpdir.o grcard1.o grcard2.o hlread.o\ - main.o pbcommon.o pbdump.o pberase.o pbupdate.o readcmd.o readops.o \ - saverestore.o script.o select.o sysmo.o telsum.o writecmd.o writeops.o + main.o pbcommon.o pbdump.o pberase.o pbupd_file.o pbupd_imm.o \ + pbupd_immhex.o readcmd.o readops.o saverestore.o script.o select.o \ + sysmo.o telsum.o writecmd.o writeops.o LIBS= ../libcommon/libcommon.a INSTBIN=/opt/freecalypso/bin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simtool/pbupd_file.c Fri Feb 12 01:28:53 2021 +0000 @@ -0,0 +1,236 @@ +/* + * 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 u_char gsm7_encode_table[256]; + +static char * +decode_qstring_alpha(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); +} + +static char * +decode_hex_alpha(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); +} + +static +process_record(line, pb_record_len, pb_record_count, filename_for_errs, + lineno_for_errs) + char *line, *filename_for_errs; + unsigned pb_record_len, pb_record_count; +{ + 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 > pb_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, pb_record_len); + fixp = record + pb_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 = decode_qstring_alpha(cp, record, pb_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 = decode_hex_alpha(cp, record, pb_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, pb_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, curfile_record_len, + curfile_record_count, argv[2], lineno); + if (rc < 0) { + fclose(inf); + return(rc); + } + } + fclose(inf); + return(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simtool/pbupd_imm.c Fri Feb 12 01:28:53 2021 +0000 @@ -0,0 +1,99 @@ +/* + * This module implements the pb-update-imm command. + */ + +#include <sys/types.h> +#include <string.h> +#include <strings.h> +#include <stdio.h> +#include <stdlib.h> +#include "curfile.h" + +extern u_char gsm7_encode_table[256]; + +static +decode_alphatag_arg(arg, record, maxlen) + char *arg; + u_char *record; + unsigned maxlen; +{ + unsigned acclen, nadd; + char *cp; + int c; + + cp = arg; + for (acclen = 0; *cp; ) { + c = *cp++; + if (c == '\\') { + if (*cp == '\0') { + fprintf(stderr, + "error: dangling backslash escape\n"); + return(-1); + } + c = *cp++; + switch (c) { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case '"': + case '\\': + break; + default: + fprintf(stderr, + "error: non-understood backslash escape\n"); + return(-1); + } + } + c = gsm7_encode_table[c]; + if (c == 0xFF) { + fprintf(stderr, + "error: character in alpha tag string cannot be encoded in GSM7\n"); + return(-1); + } + if (c & 0x80) + nadd = 2; + else + nadd = 1; + if (acclen + nadd > maxlen) { + fprintf(stderr, + "error: alpha tag string is longer than SIM limit\n"); + return(-1); + } + if (c & 0x80) + record[acclen++] = 0x1B; + record[acclen++] = c & 0x7F; + } + return(0); +} + +cmd_pb_update_imm(argc, argv) + char **argv; +{ + int rc; + unsigned recno; + u_char record[255], *fixp; + + rc = phonebook_op_common(argv[1]); + if (rc < 0) + return(rc); + recno = strtoul(argv[2], 0, 0); + if (recno < 1 || recno > curfile_record_count) { + fprintf(stderr, "error: specified record number is invalid\n"); + return(-1); + } + memset(record, 0xFF, curfile_record_len); + fixp = record + curfile_record_len - 14; + rc = encode_phone_number_arg(argv[3], fixp); + if (rc < 0) + return(rc); + if (argv[4]) { + rc = decode_alphatag_arg(argv[4], record, + curfile_record_len - 14); + if (rc < 0) + return(rc); + } + return update_rec_op(recno, 0x04, record, curfile_record_len); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simtool/pbupd_immhex.c Fri Feb 12 01:28:53 2021 +0000 @@ -0,0 +1,66 @@ +/* + * This module implements the pb-update-imm-hex command. + */ + +#include <sys/types.h> +#include <ctype.h> +#include <string.h> +#include <strings.h> +#include <stdio.h> +#include <stdlib.h> +#include "curfile.h" + +static +decode_alphatag_arg_hex(arg, record, maxlen) + char *arg; + u_char *record; + unsigned maxlen; +{ + unsigned acclen; + + for (acclen = 0; ; acclen++) { + while (isspace(*arg)) + arg++; + if (!*arg) + break; + if (!isxdigit(arg[0]) || !isxdigit(arg[1])) { + fprintf(stderr, "error: invalid hex string input\n"); + return(-1); + } + if (acclen >= maxlen) { + fprintf(stderr, + "error: alpha tag string is longer than SIM limit\n"); + return(-1); + } + record[acclen] = (decode_hex_digit(arg[0]) << 4) | + decode_hex_digit(arg[1]); + arg += 2; + } + return(0); +} + +cmd_pb_update_imm_hex(argc, argv) + char **argv; +{ + int rc; + unsigned recno; + u_char record[255], *fixp; + + rc = phonebook_op_common(argv[1]); + if (rc < 0) + return(rc); + recno = strtoul(argv[2], 0, 0); + if (recno < 1 || recno > curfile_record_count) { + fprintf(stderr, "error: specified record number is invalid\n"); + return(-1); + } + memset(record, 0xFF, curfile_record_len); + fixp = record + curfile_record_len - 14; + rc = encode_phone_number_arg(argv[3], fixp); + if (rc < 0) + return(rc); + rc = decode_alphatag_arg_hex(argv[4], record, curfile_record_len - 14); + if (rc < 0) + return(rc); + return update_rec_op(recno, 0x04, record, curfile_record_len); +}
--- a/simtool/pbupdate.c Fri Feb 12 01:15:22 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,378 +0,0 @@ -/* - * This module implements the pb-update family of commands. - */ - -#include <sys/types.h> -#include <ctype.h> -#include <string.h> -#include <strings.h> -#include <stdio.h> -#include <stdlib.h> -#include "curfile.h" - -extern u_char gsm7_encode_table[256]; - -static char * -decode_qstring_alpha(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); -} - -static char * -decode_hex_alpha(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); -} - -static -process_record(line, pb_record_len, pb_record_count, filename_for_errs, - lineno_for_errs) - char *line, *filename_for_errs; - unsigned pb_record_len, pb_record_count; -{ - 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 > pb_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, pb_record_len); - fixp = record + pb_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 = decode_qstring_alpha(cp, record, pb_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 = decode_hex_alpha(cp, record, pb_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, pb_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, curfile_record_len, - curfile_record_count, argv[2], lineno); - if (rc < 0) { - fclose(inf); - return(rc); - } - } - fclose(inf); - return(0); -} - -static -decode_alphatag_arg(arg, record, maxlen) - char *arg; - u_char *record; - unsigned maxlen; -{ - unsigned acclen, nadd; - char *cp; - int c; - - cp = arg; - for (acclen = 0; *cp; ) { - c = *cp++; - if (c == '\\') { - if (*cp == '\0') { - fprintf(stderr, - "error: dangling backslash escape\n"); - return(-1); - } - c = *cp++; - switch (c) { - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case '"': - case '\\': - break; - default: - fprintf(stderr, - "error: non-understood backslash escape\n"); - return(-1); - } - } - c = gsm7_encode_table[c]; - if (c == 0xFF) { - fprintf(stderr, - "error: character in alpha tag string cannot be encoded in GSM7\n"); - return(-1); - } - if (c & 0x80) - nadd = 2; - else - nadd = 1; - if (acclen + nadd > maxlen) { - fprintf(stderr, - "error: alpha tag string is longer than SIM limit\n"); - return(-1); - } - if (c & 0x80) - record[acclen++] = 0x1B; - record[acclen++] = c & 0x7F; - } - return(0); -} - -cmd_pb_update_imm(argc, argv) - char **argv; -{ - int rc; - unsigned recno; - u_char record[255], *fixp; - - rc = phonebook_op_common(argv[1]); - if (rc < 0) - return(rc); - recno = strtoul(argv[2], 0, 0); - if (recno < 1 || recno > curfile_record_count) { - fprintf(stderr, "error: specified record number is invalid\n"); - return(-1); - } - memset(record, 0xFF, curfile_record_len); - fixp = record + curfile_record_len - 14; - rc = encode_phone_number_arg(argv[3], fixp); - if (rc < 0) - return(rc); - if (argv[4]) { - rc = decode_alphatag_arg(argv[4], record, - curfile_record_len - 14); - if (rc < 0) - return(rc); - } - return update_rec_op(recno, 0x04, record, curfile_record_len); -} - -static -decode_alphatag_arg_hex(arg, record, maxlen) - char *arg; - u_char *record; - unsigned maxlen; -{ - unsigned acclen; - - for (acclen = 0; ; acclen++) { - while (isspace(*arg)) - arg++; - if (!*arg) - break; - if (!isxdigit(arg[0]) || !isxdigit(arg[1])) { - fprintf(stderr, "error: invalid hex string input\n"); - return(-1); - } - if (acclen >= maxlen) { - fprintf(stderr, - "error: alpha tag string is longer than SIM limit\n"); - return(-1); - } - record[acclen] = (decode_hex_digit(arg[0]) << 4) | - decode_hex_digit(arg[1]); - arg += 2; - } - return(0); -} - -cmd_pb_update_imm_hex(argc, argv) - char **argv; -{ - int rc; - unsigned recno; - u_char record[255], *fixp; - - rc = phonebook_op_common(argv[1]); - if (rc < 0) - return(rc); - recno = strtoul(argv[2], 0, 0); - if (recno < 1 || recno > curfile_record_count) { - fprintf(stderr, "error: specified record number is invalid\n"); - return(-1); - } - memset(record, 0xFF, curfile_record_len); - fixp = record + curfile_record_len - 14; - rc = encode_phone_number_arg(argv[3], fixp); - if (rc < 0) - return(rc); - rc = decode_alphatag_arg_hex(argv[4], record, curfile_record_len - 14); - if (rc < 0) - return(rc); - return update_rec_op(recno, 0x04, record, curfile_record_len); -}