comparison simtool/smsp_restore.c @ 39:2467b7acad1f

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