FreeCalypso > hg > fc-pcsc-tools
view simtool/smsp_restore.c @ 41:8cb269f5a902
fc-simtool smsp-restore: forgot to set parameter indicator bits
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 12 Feb 2021 22:10:32 +0000 |
parents | 2467b7acad1f |
children | 9c10afbb745a |
line wrap: on
line source
/* * This module implements the smsp-restore 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 char * parse_da(cp, bina, filename_for_errs, lineno_for_errs) char *cp, *filename_for_errs; u_char *bina; { u_char digits[20]; unsigned ndigits, num_digit_bytes; int c; if (digit_char_to_gsm(*cp) < 0) { inv_syntax: fprintf(stderr, "%s line %d: DA= parameter invalid syntax\n", filename_for_errs, lineno_for_errs); return(0); } 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(0); } digits[ndigits] = c; } bina[0] = ndigits; if (ndigits & 1) digits[ndigits++] = 0xF; num_digit_bytes = ndigits >> 1; pack_digit_bytes(digits, bina + 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; bina[1] = strtoul(cp, 0, 16); cp += 5; while (isspace(*cp)) cp++; return(cp); } static char * parse_sc(cp, bina, filename_for_errs, lineno_for_errs) char *cp, *filename_for_errs; u_char *bina; { u_char digits[20]; unsigned ndigits, num_digit_bytes; int c; if (digit_char_to_gsm(*cp) < 0) { inv_syntax: fprintf(stderr, "%s line %d: SC= parameter invalid syntax\n", filename_for_errs, lineno_for_errs); return(0); } 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(0); } digits[ndigits] = c; } if (ndigits & 1) digits[ndigits++] = 0xF; num_digit_bytes = ndigits >> 1; bina[0] = num_digit_bytes + 1; pack_digit_bytes(digits, bina + 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; bina[1] = strtoul(cp, 0, 16); cp += 5; while (isspace(*cp)) cp++; return(cp); } static process_record(line, filename_for_errs, lineno_for_errs) char *line, *filename_for_errs; { unsigned recno; u_char record[255], *fixp; char *cp; 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 - 28; if (!strncasecmp(cp, "DA=", 3)) { cp += 3; cp = parse_da(cp, fixp + 1, filename_for_errs, lineno_for_errs); if (!cp) return(-1); fixp[0] &= 0xFE; } if (!strncasecmp(cp, "SC=", 3)) { cp += 3; cp = parse_sc(cp, fixp+13, filename_for_errs, lineno_for_errs); if (!cp) return(-1); fixp[0] &= 0xFD; } if (!strncasecmp(cp, "PID=", 4)) { cp += 4; if (!isdigit(*cp)) { fprintf(stderr, "%s line %d: PID= parameter invalid syntax\n", filename_for_errs, lineno_for_errs); return(-1); } fixp[25] = strtoul(cp, 0, 0); fixp[0] &= 0xFB; while (*cp && !isspace(*cp)) cp++; while (isspace(*cp)) cp++; } if (!strncasecmp(cp, "DCS=", 4)) { cp += 4; if (!isdigit(*cp)) { fprintf(stderr, "%s line %d: DCS= parameter invalid syntax\n", filename_for_errs, lineno_for_errs); return(-1); } fixp[26] = strtoul(cp, 0, 0); fixp[0] &= 0xF7; while (*cp && !isspace(*cp)) cp++; while (isspace(*cp)) cp++; } if (!strncasecmp(cp, "VP=", 3)) { cp += 3; if (!isdigit(*cp)) { fprintf(stderr, "%s line %d: VP= parameter invalid syntax\n", filename_for_errs, lineno_for_errs); return(-1); } fixp[27] = strtoul(cp, 0, 0); fixp[0] &= 0xEF; while (*cp && !isspace(*cp)) cp++; while (isspace(*cp)) cp++; } if (*cp == '"') { cp++; cp = alpha_from_file_qstring(cp, record, curfile_record_len - 28, 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 - 28, 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_smsp_restore(argc, argv) char **argv; { int rc; FILE *inf; int lineno; char linebuf[1024]; rc = select_ef_smsp(); if (rc < 0) return(rc); inf = fopen(argv[1], "r"); if (!inf) { perror(argv[1]); 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[1], lineno); fclose(inf); return(-1); } if (linebuf[0] != '#' || !isdigit(linebuf[1])) continue; rc = process_record(linebuf, argv[1], lineno); if (rc < 0) { fclose(inf); return(rc); } } fclose(inf); return(0); }