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