FreeCalypso > hg > fc-pcsc-tools
comparison simtool/pbupdate.c @ 10:a76ec3e7da09
simtool/pbupdate.c: a little refactoring from fc-uicc-tool
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 12 Feb 2021 00:47:04 +0000 |
| parents | 2071b28cd0c7 |
| children | 62cdfed70de7 |
comparison
equal
deleted
inserted
replaced
| 9:dc565e91069d | 10:a76ec3e7da09 |
|---|---|
| 1 /* | 1 /* |
| 2 * This module implements the pb-update command. | 2 * This module implements the pb-update family of commands. |
| 3 */ | 3 */ |
| 4 | 4 |
| 5 #include <sys/types.h> | 5 #include <sys/types.h> |
| 6 #include <ctype.h> | 6 #include <ctype.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <strings.h> | 8 #include <strings.h> |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <stdlib.h> | 10 #include <stdlib.h> |
| 11 #include "simresp.h" | |
| 12 #include "curfile.h" | 11 #include "curfile.h" |
| 13 | 12 |
| 14 static u_char gsm7_encode_table[256] = { | 13 static u_char gsm7_encode_table[256] = { |
| 15 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x00 */ | 14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x00 */ |
| 16 0xFF, 0xFF, '\n', 0xFF, 0xFF, '\r', 0xFF, 0xFF, | 15 0xFF, 0xFF, '\n', 0xFF, 0xFF, '\r', 0xFF, 0xFF, |
| 92 sp += 2; | 91 sp += 2; |
| 93 } | 92 } |
| 94 } | 93 } |
| 95 | 94 |
| 96 static char * | 95 static char * |
| 97 decode_qstring_alpha(cp, record, filename_for_errs, lineno_for_errs) | 96 decode_qstring_alpha(cp, record, maxlen, filename_for_errs, lineno_for_errs) |
| 98 char *cp, *filename_for_errs; | 97 char *cp, *filename_for_errs; |
| 99 u_char *record; | 98 u_char *record; |
| 100 { | 99 unsigned maxlen; |
| 101 unsigned maxlen, acclen, nadd; | 100 { |
| 101 unsigned acclen, nadd; | |
| 102 int c; | 102 int c; |
| 103 | 103 |
| 104 maxlen = curfile_record_len - 14; | |
| 105 for (acclen = 0; ; ) { | 104 for (acclen = 0; ; ) { |
| 106 if (*cp == '\0') { | 105 if (*cp == '\0') { |
| 107 unterm_qstring: fprintf(stderr, | 106 unterm_qstring: fprintf(stderr, |
| 108 "%s line %d: unterminated quoted string\n", | 107 "%s line %d: unterminated quoted string\n", |
| 109 filename_for_errs, lineno_for_errs); | 108 filename_for_errs, lineno_for_errs); |
| 156 } | 155 } |
| 157 return(cp + 1); | 156 return(cp + 1); |
| 158 } | 157 } |
| 159 | 158 |
| 160 static char * | 159 static char * |
| 161 decode_hex_alpha(cp, record, filename_for_errs, lineno_for_errs) | 160 decode_hex_alpha(cp, record, maxlen, filename_for_errs, lineno_for_errs) |
| 162 char *cp, *filename_for_errs; | 161 char *cp, *filename_for_errs; |
| 163 u_char *record; | 162 u_char *record; |
| 164 { | 163 unsigned maxlen; |
| 165 unsigned maxlen, acclen; | 164 { |
| 166 | 165 unsigned acclen; |
| 167 maxlen = curfile_record_len - 14; | 166 |
| 168 for (acclen = 0; ; ) { | 167 for (acclen = 0; ; ) { |
| 169 if (!isxdigit(cp[0]) || !isxdigit(cp[1])) | 168 if (!isxdigit(cp[0]) || !isxdigit(cp[1])) |
| 170 break; | 169 break; |
| 171 if (acclen >= maxlen) { | 170 if (acclen >= maxlen) { |
| 172 fprintf(stderr, | 171 fprintf(stderr, |
| 180 } | 179 } |
| 181 return(cp); | 180 return(cp); |
| 182 } | 181 } |
| 183 | 182 |
| 184 static | 183 static |
| 185 process_record(line, filename_for_errs, lineno_for_errs) | 184 process_record(line, pb_record_len, pb_record_count, filename_for_errs, |
| 185 lineno_for_errs) | |
| 186 char *line, *filename_for_errs; | 186 char *line, *filename_for_errs; |
| 187 unsigned pb_record_len, pb_record_count; | |
| 187 { | 188 { |
| 188 unsigned recno; | 189 unsigned recno; |
| 189 u_char record[255], *fixp; | 190 u_char record[255], *fixp; |
| 190 u_char digits[20]; | 191 u_char digits[20]; |
| 191 unsigned ndigits, num_digit_bytes; | 192 unsigned ndigits, num_digit_bytes; |
| 192 char *cp; | 193 char *cp; |
| 193 int c; | 194 int c; |
| 194 | 195 |
| 195 recno = strtoul(line+1, 0, 10); | 196 recno = strtoul(line+1, 0, 10); |
| 196 if (recno < 1 || recno > curfile_record_count) { | 197 if (recno < 1 || recno > pb_record_count) { |
| 197 fprintf(stderr, "%s line %d: record number is out of range\n", | 198 fprintf(stderr, "%s line %d: record number is out of range\n", |
| 198 filename_for_errs, lineno_for_errs); | 199 filename_for_errs, lineno_for_errs); |
| 199 return(-1); | 200 return(-1); |
| 200 } | 201 } |
| 201 cp = line + 1; | 202 cp = line + 1; |
| 206 filename_for_errs, lineno_for_errs); | 207 filename_for_errs, lineno_for_errs); |
| 207 return(-1); | 208 return(-1); |
| 208 } | 209 } |
| 209 while (isspace(*cp)) | 210 while (isspace(*cp)) |
| 210 cp++; | 211 cp++; |
| 211 memset(record, 0xFF, curfile_record_len); | 212 memset(record, 0xFF, pb_record_len); |
| 212 fixp = record + curfile_record_len - 14; | 213 fixp = record + pb_record_len - 14; |
| 213 if (digit_char_to_gsm(*cp) < 0) | 214 if (digit_char_to_gsm(*cp) < 0) |
| 214 goto inv_syntax; | 215 goto inv_syntax; |
| 215 for (ndigits = 0; ; ndigits++) { | 216 for (ndigits = 0; ; ndigits++) { |
| 216 c = digit_char_to_gsm(*cp); | 217 c = digit_char_to_gsm(*cp); |
| 217 if (c < 0) | 218 if (c < 0) |
| 254 while (isspace(*cp)) | 255 while (isspace(*cp)) |
| 255 cp++; | 256 cp++; |
| 256 } | 257 } |
| 257 if (*cp == '"') { | 258 if (*cp == '"') { |
| 258 cp++; | 259 cp++; |
| 259 cp = decode_qstring_alpha(cp, record, filename_for_errs, | 260 cp = decode_qstring_alpha(cp, record, pb_record_len - 14, |
| 260 lineno_for_errs); | 261 filename_for_errs, lineno_for_errs); |
| 261 if (!cp) | 262 if (!cp) |
| 262 return(-1); | 263 return(-1); |
| 263 } else if (!strncasecmp(cp, "HEX", 3)) { | 264 } else if (!strncasecmp(cp, "HEX", 3)) { |
| 264 cp += 3; | 265 cp += 3; |
| 265 while (isspace(*cp)) | 266 while (isspace(*cp)) |
| 266 cp++; | 267 cp++; |
| 267 cp = decode_hex_alpha(cp, record, filename_for_errs, | 268 cp = decode_hex_alpha(cp, record, pb_record_len - 14, |
| 268 lineno_for_errs); | 269 filename_for_errs, lineno_for_errs); |
| 269 if (!cp) | 270 if (!cp) |
| 270 return(-1); | 271 return(-1); |
| 271 } else | 272 } else |
| 272 goto inv_syntax; | 273 goto inv_syntax; |
| 273 while (isspace(*cp)) | 274 while (isspace(*cp)) |
| 274 cp++; | 275 cp++; |
| 275 if (*cp) | 276 if (*cp) |
| 276 goto inv_syntax; | 277 goto inv_syntax; |
| 277 return update_rec_op(recno, 0x04, record, curfile_record_len); | 278 return update_rec_op(recno, 0x04, record, pb_record_len); |
| 278 } | 279 } |
| 279 | 280 |
| 280 cmd_pb_update(argc, argv) | 281 cmd_pb_update(argc, argv) |
| 281 char **argv; | 282 char **argv; |
| 282 { | 283 { |
| 301 fclose(inf); | 302 fclose(inf); |
| 302 return(-1); | 303 return(-1); |
| 303 } | 304 } |
| 304 if (linebuf[0] != '#' || !isdigit(linebuf[1])) | 305 if (linebuf[0] != '#' || !isdigit(linebuf[1])) |
| 305 continue; | 306 continue; |
| 306 rc = process_record(linebuf, argv[2], lineno); | 307 rc = process_record(linebuf, curfile_record_len, |
| 308 curfile_record_count, argv[2], lineno); | |
| 307 if (rc < 0) { | 309 if (rc < 0) { |
| 308 fclose(inf); | 310 fclose(inf); |
| 309 return(rc); | 311 return(rc); |
| 310 } | 312 } |
| 311 } | 313 } |
| 360 goto inv_arg; | 362 goto inv_arg; |
| 361 return(0); | 363 return(0); |
| 362 } | 364 } |
| 363 | 365 |
| 364 static | 366 static |
| 365 decode_alphatag_arg(arg, record) | 367 decode_alphatag_arg(arg, record, maxlen) |
| 366 char *arg; | 368 char *arg; |
| 367 u_char *record; | 369 u_char *record; |
| 368 { | 370 unsigned maxlen; |
| 369 unsigned maxlen, acclen, nadd; | 371 { |
| 372 unsigned acclen, nadd; | |
| 370 char *cp; | 373 char *cp; |
| 371 int c; | 374 int c; |
| 372 | 375 |
| 373 maxlen = curfile_record_len - 14; | |
| 374 cp = arg; | 376 cp = arg; |
| 375 for (acclen = 0; *cp; ) { | 377 for (acclen = 0; *cp; ) { |
| 376 c = *cp++; | 378 c = *cp++; |
| 377 if (c == '\\') { | 379 if (c == '\\') { |
| 378 if (*cp == '\0') { | 380 if (*cp == '\0') { |
| 438 fixp = record + curfile_record_len - 14; | 440 fixp = record + curfile_record_len - 14; |
| 439 rc = decode_number_arg(argv[3], fixp); | 441 rc = decode_number_arg(argv[3], fixp); |
| 440 if (rc < 0) | 442 if (rc < 0) |
| 441 return(rc); | 443 return(rc); |
| 442 if (argv[4]) { | 444 if (argv[4]) { |
| 443 rc = decode_alphatag_arg(argv[4], record); | 445 rc = decode_alphatag_arg(argv[4], record, |
| 446 curfile_record_len - 14); | |
| 444 if (rc < 0) | 447 if (rc < 0) |
| 445 return(rc); | 448 return(rc); |
| 446 } | 449 } |
| 447 return update_rec_op(recno, 0x04, record, curfile_record_len); | 450 return update_rec_op(recno, 0x04, record, curfile_record_len); |
| 448 } | 451 } |
| 449 | 452 |
| 450 static | 453 static |
| 451 decode_alphatag_arg_hex(arg, record) | 454 decode_alphatag_arg_hex(arg, record, maxlen) |
| 452 char *arg; | 455 char *arg; |
| 453 u_char *record; | 456 u_char *record; |
| 454 { | 457 unsigned maxlen; |
| 455 unsigned maxlen, acclen; | 458 { |
| 456 | 459 unsigned acclen; |
| 457 maxlen = curfile_record_len - 14; | 460 |
| 458 for (acclen = 0; ; acclen++) { | 461 for (acclen = 0; ; acclen++) { |
| 459 while (isspace(*arg)) | 462 while (isspace(*arg)) |
| 460 arg++; | 463 arg++; |
| 461 if (!*arg) | 464 if (!*arg) |
| 462 break; | 465 break; |
| 494 memset(record, 0xFF, curfile_record_len); | 497 memset(record, 0xFF, curfile_record_len); |
| 495 fixp = record + curfile_record_len - 14; | 498 fixp = record + curfile_record_len - 14; |
| 496 rc = decode_number_arg(argv[3], fixp); | 499 rc = decode_number_arg(argv[3], fixp); |
| 497 if (rc < 0) | 500 if (rc < 0) |
| 498 return(rc); | 501 return(rc); |
| 499 rc = decode_alphatag_arg_hex(argv[4], record); | 502 rc = decode_alphatag_arg_hex(argv[4], record, curfile_record_len - 14); |
| 500 if (rc < 0) | 503 if (rc < 0) |
| 501 return(rc); | 504 return(rc); |
| 502 return update_rec_op(recno, 0x04, record, curfile_record_len); | 505 return update_rec_op(recno, 0x04, record, curfile_record_len); |
| 503 } | 506 } |
