FreeCalypso > hg > fc-sim-tools
comparison simtool/smsp_restore.c @ 10:ddd767f6e15b
fc-simtool ported over
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 14 Mar 2021 07:11:25 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 9:c9ef9e91dd8e | 10:ddd767f6e15b |
|---|---|
| 1 /* | |
| 2 * This module implements the smsp-restore command. | |
| 3 */ | |
| 4 | |
| 5 #include <sys/types.h> | |
| 6 #include <ctype.h> | |
| 7 #include <string.h> | |
| 8 #include <strings.h> | |
| 9 #include <stdio.h> | |
| 10 #include <stdlib.h> | |
| 11 #include "curfile.h" | |
| 12 | |
| 13 extern FILE *open_script_input_file(); | |
| 14 | |
| 15 extern char *alpha_from_file_qstring(); | |
| 16 extern char *alpha_from_file_hex(); | |
| 17 | |
| 18 static char * | |
| 19 parse_da(cp, bina, filename_for_errs, lineno_for_errs) | |
| 20 char *cp, *filename_for_errs; | |
| 21 u_char *bina; | |
| 22 { | |
| 23 u_char digits[20]; | |
| 24 unsigned ndigits, num_digit_bytes; | |
| 25 int c; | |
| 26 | |
| 27 if (digit_char_to_gsm(*cp) < 0) { | |
| 28 inv_syntax: fprintf(stderr, "%s line %d: DA= parameter invalid syntax\n", | |
| 29 filename_for_errs, lineno_for_errs); | |
| 30 return(0); | |
| 31 } | |
| 32 for (ndigits = 0; ; ndigits++) { | |
| 33 c = digit_char_to_gsm(*cp); | |
| 34 if (c < 0) | |
| 35 break; | |
| 36 cp++; | |
| 37 if (ndigits >= 20) { | |
| 38 fprintf(stderr, "%s line %d: too many number digits\n", | |
| 39 filename_for_errs, lineno_for_errs); | |
| 40 return(0); | |
| 41 } | |
| 42 digits[ndigits] = c; | |
| 43 } | |
| 44 bina[0] = ndigits; | |
| 45 if (ndigits & 1) | |
| 46 digits[ndigits++] = 0xF; | |
| 47 num_digit_bytes = ndigits >> 1; | |
| 48 pack_digit_bytes(digits, bina + 2, num_digit_bytes); | |
| 49 if (*cp++ != ',') | |
| 50 goto inv_syntax; | |
| 51 if (cp[0] != '0' || cp[1] != 'x' && cp[1] != 'X' || !isxdigit(cp[2]) || | |
| 52 !isxdigit(cp[3]) || !isspace(cp[4])) | |
| 53 goto inv_syntax; | |
| 54 bina[1] = strtoul(cp, 0, 16); | |
| 55 cp += 5; | |
| 56 while (isspace(*cp)) | |
| 57 cp++; | |
| 58 return(cp); | |
| 59 } | |
| 60 | |
| 61 static char * | |
| 62 parse_sc(cp, bina, filename_for_errs, lineno_for_errs) | |
| 63 char *cp, *filename_for_errs; | |
| 64 u_char *bina; | |
| 65 { | |
| 66 u_char digits[20]; | |
| 67 unsigned ndigits, num_digit_bytes; | |
| 68 int c; | |
| 69 | |
| 70 if (digit_char_to_gsm(*cp) < 0) { | |
| 71 inv_syntax: fprintf(stderr, "%s line %d: SC= parameter invalid syntax\n", | |
| 72 filename_for_errs, lineno_for_errs); | |
| 73 return(0); | |
| 74 } | |
| 75 for (ndigits = 0; ; ndigits++) { | |
| 76 c = digit_char_to_gsm(*cp); | |
| 77 if (c < 0) | |
| 78 break; | |
| 79 cp++; | |
| 80 if (ndigits >= 20) { | |
| 81 fprintf(stderr, "%s line %d: too many number digits\n", | |
| 82 filename_for_errs, lineno_for_errs); | |
| 83 return(0); | |
| 84 } | |
| 85 digits[ndigits] = c; | |
| 86 } | |
| 87 if (ndigits & 1) | |
| 88 digits[ndigits++] = 0xF; | |
| 89 num_digit_bytes = ndigits >> 1; | |
| 90 bina[0] = num_digit_bytes + 1; | |
| 91 pack_digit_bytes(digits, bina + 2, num_digit_bytes); | |
| 92 if (*cp++ != ',') | |
| 93 goto inv_syntax; | |
| 94 if (cp[0] != '0' || cp[1] != 'x' && cp[1] != 'X' || !isxdigit(cp[2]) || | |
| 95 !isxdigit(cp[3]) || !isspace(cp[4])) | |
| 96 goto inv_syntax; | |
| 97 bina[1] = strtoul(cp, 0, 16); | |
| 98 cp += 5; | |
| 99 while (isspace(*cp)) | |
| 100 cp++; | |
| 101 return(cp); | |
| 102 } | |
| 103 | |
| 104 static | |
| 105 process_record(line, filename_for_errs, lineno_for_errs) | |
| 106 char *line, *filename_for_errs; | |
| 107 { | |
| 108 unsigned recno; | |
| 109 u_char record[255], *fixp; | |
| 110 char *cp; | |
| 111 | |
| 112 recno = strtoul(line+1, 0, 10); | |
| 113 if (recno < 1 || recno > curfile_record_count) { | |
| 114 fprintf(stderr, "%s line %d: record number is out of range\n", | |
| 115 filename_for_errs, lineno_for_errs); | |
| 116 return(-1); | |
| 117 } | |
| 118 cp = line + 1; | |
| 119 while (isdigit(*cp)) | |
| 120 cp++; | |
| 121 if (*cp++ != ':') { | |
| 122 inv_syntax: fprintf(stderr, "%s line %d: invalid syntax\n", | |
| 123 filename_for_errs, lineno_for_errs); | |
| 124 return(-1); | |
| 125 } | |
| 126 while (isspace(*cp)) | |
| 127 cp++; | |
| 128 memset(record, 0xFF, curfile_record_len); | |
| 129 fixp = record + curfile_record_len - 28; | |
| 130 if (!strncasecmp(cp, "DA=", 3)) { | |
| 131 cp += 3; | |
| 132 cp = parse_da(cp, fixp + 1, filename_for_errs, lineno_for_errs); | |
| 133 if (!cp) | |
| 134 return(-1); | |
| 135 fixp[0] &= 0xFE; | |
| 136 } | |
| 137 if (!strncasecmp(cp, "SC=", 3)) { | |
| 138 cp += 3; | |
| 139 cp = parse_sc(cp, fixp+13, filename_for_errs, lineno_for_errs); | |
| 140 if (!cp) | |
| 141 return(-1); | |
| 142 fixp[0] &= 0xFD; | |
| 143 } | |
| 144 if (!strncasecmp(cp, "PID=", 4)) { | |
| 145 cp += 4; | |
| 146 if (!isdigit(*cp)) { | |
| 147 fprintf(stderr, | |
| 148 "%s line %d: PID= parameter invalid syntax\n", | |
| 149 filename_for_errs, lineno_for_errs); | |
| 150 return(-1); | |
| 151 } | |
| 152 fixp[25] = strtoul(cp, 0, 0); | |
| 153 fixp[0] &= 0xFB; | |
| 154 while (*cp && !isspace(*cp)) | |
| 155 cp++; | |
| 156 while (isspace(*cp)) | |
| 157 cp++; | |
| 158 } | |
| 159 if (!strncasecmp(cp, "DCS=", 4)) { | |
| 160 cp += 4; | |
| 161 if (!isdigit(*cp)) { | |
| 162 fprintf(stderr, | |
| 163 "%s line %d: DCS= parameter invalid syntax\n", | |
| 164 filename_for_errs, lineno_for_errs); | |
| 165 return(-1); | |
| 166 } | |
| 167 fixp[26] = strtoul(cp, 0, 0); | |
| 168 fixp[0] &= 0xF7; | |
| 169 while (*cp && !isspace(*cp)) | |
| 170 cp++; | |
| 171 while (isspace(*cp)) | |
| 172 cp++; | |
| 173 } | |
| 174 if (!strncasecmp(cp, "VP=", 3)) { | |
| 175 cp += 3; | |
| 176 if (!isdigit(*cp)) { | |
| 177 fprintf(stderr, | |
| 178 "%s line %d: VP= parameter invalid syntax\n", | |
| 179 filename_for_errs, lineno_for_errs); | |
| 180 return(-1); | |
| 181 } | |
| 182 fixp[27] = strtoul(cp, 0, 0); | |
| 183 fixp[0] &= 0xEF; | |
| 184 while (*cp && !isspace(*cp)) | |
| 185 cp++; | |
| 186 while (isspace(*cp)) | |
| 187 cp++; | |
| 188 } | |
| 189 if (*cp == '"') { | |
| 190 cp++; | |
| 191 cp = alpha_from_file_qstring(cp, record, | |
| 192 curfile_record_len - 28, | |
| 193 filename_for_errs, | |
| 194 lineno_for_errs); | |
| 195 if (!cp) | |
| 196 return(-1); | |
| 197 } else if (!strncasecmp(cp, "HEX", 3)) { | |
| 198 cp += 3; | |
| 199 while (isspace(*cp)) | |
| 200 cp++; | |
| 201 cp = alpha_from_file_hex(cp, record, curfile_record_len - 28, | |
| 202 filename_for_errs, lineno_for_errs); | |
| 203 if (!cp) | |
| 204 return(-1); | |
| 205 } else | |
| 206 goto inv_syntax; | |
| 207 while (isspace(*cp)) | |
| 208 cp++; | |
| 209 if (*cp) | |
| 210 goto inv_syntax; | |
| 211 return update_rec_op(recno, 0x04, record, curfile_record_len); | |
| 212 } | |
| 213 | |
| 214 cmd_smsp_restore(argc, argv) | |
| 215 char **argv; | |
| 216 { | |
| 217 int rc; | |
| 218 FILE *inf; | |
| 219 int lineno; | |
| 220 char linebuf[1024]; | |
| 221 | |
| 222 rc = select_ef_smsp(); | |
| 223 if (rc < 0) | |
| 224 return(rc); | |
| 225 inf = open_script_input_file(argv[1]); | |
| 226 if (!inf) { | |
| 227 perror(argv[1]); | |
| 228 return(-1); | |
| 229 } | |
| 230 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { | |
| 231 if (!index(linebuf, '\n')) { | |
| 232 fprintf(stderr, | |
| 233 "%s line %d: too long or missing newline\n", | |
| 234 argv[1], lineno); | |
| 235 fclose(inf); | |
| 236 return(-1); | |
| 237 } | |
| 238 if (linebuf[0] != '#' || !isdigit(linebuf[1])) | |
| 239 continue; | |
| 240 rc = process_record(linebuf, argv[1], lineno); | |
| 241 if (rc < 0) { | |
| 242 fclose(inf); | |
| 243 return(rc); | |
| 244 } | |
| 245 } | |
| 246 fclose(inf); | |
| 247 return(0); | |
| 248 } |
