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 }