FreeCalypso > hg > fc-pcsc-tools
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); +}