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 } |