comparison simtool/pbrestore.c @ 87:bc862d41f96b

pb-restore command implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 17 Feb 2021 07:04:05 +0000
parents simtool/pbupd_file.c@51167ee0151b
children ae831b21ef77
comparison
equal deleted inserted replaced
86:bd19dc7591ec 87:bc862d41f96b
1 /*
2 * This module implements pb-restore and pb-update commands.
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
17 process_record(line, bin_file_buf, filename_for_errs, lineno_for_errs)
18 char *line, *filename_for_errs;
19 u_char *bin_file_buf;
20 {
21 unsigned recno;
22 u_char record[255], *fixp;
23 u_char digits[20];
24 unsigned ndigits, num_digit_bytes;
25 char *cp;
26 int c;
27
28 recno = strtoul(line+1, 0, 10);
29 if (recno < 1 || recno > curfile_record_count) {
30 fprintf(stderr, "%s line %d: record number is out of range\n",
31 filename_for_errs, lineno_for_errs);
32 return(-1);
33 }
34 cp = line + 1;
35 while (isdigit(*cp))
36 cp++;
37 if (*cp++ != ':') {
38 inv_syntax: fprintf(stderr, "%s line %d: invalid syntax\n",
39 filename_for_errs, lineno_for_errs);
40 return(-1);
41 }
42 while (isspace(*cp))
43 cp++;
44 memset(record, 0xFF, curfile_record_len);
45 fixp = record + curfile_record_len - 14;
46 if (digit_char_to_gsm(*cp) < 0)
47 goto inv_syntax;
48 for (ndigits = 0; ; ndigits++) {
49 c = digit_char_to_gsm(*cp);
50 if (c < 0)
51 break;
52 cp++;
53 if (ndigits >= 20) {
54 fprintf(stderr, "%s line %d: too many number digits\n",
55 filename_for_errs, lineno_for_errs);
56 return(-1);
57 }
58 digits[ndigits] = c;
59 }
60 if (ndigits & 1)
61 digits[ndigits++] = 0xF;
62 num_digit_bytes = ndigits >> 1;
63 fixp[0] = num_digit_bytes + 1;
64 pack_digit_bytes(digits, fixp + 2, num_digit_bytes);
65 if (*cp++ != ',')
66 goto inv_syntax;
67 if (cp[0] != '0' || cp[1] != 'x' && cp[1] != 'X' || !isxdigit(cp[2]) ||
68 !isxdigit(cp[3]) || !isspace(cp[4]))
69 goto inv_syntax;
70 fixp[1] = strtoul(cp, 0, 16);
71 cp += 5;
72 while (isspace(*cp))
73 cp++;
74 if (!strncasecmp(cp, "CCP=", 4)) {
75 cp += 4;
76 fixp[12] = strtoul(cp, 0, 0);
77 while (*cp && !isspace(*cp))
78 cp++;
79 while (isspace(*cp))
80 cp++;
81 }
82 if (!strncasecmp(cp, "EXT=", 4)) {
83 cp += 4;
84 fixp[13] = strtoul(cp, 0, 0);
85 while (*cp && !isspace(*cp))
86 cp++;
87 while (isspace(*cp))
88 cp++;
89 }
90 if (*cp == '"') {
91 cp++;
92 cp = alpha_from_file_qstring(cp, record,
93 curfile_record_len - 14,
94 filename_for_errs,
95 lineno_for_errs);
96 if (!cp)
97 return(-1);
98 } else if (!strncasecmp(cp, "HEX", 3)) {
99 cp += 3;
100 while (isspace(*cp))
101 cp++;
102 cp = alpha_from_file_hex(cp, record, curfile_record_len - 14,
103 filename_for_errs, lineno_for_errs);
104 if (!cp)
105 return(-1);
106 } else
107 goto inv_syntax;
108 while (isspace(*cp))
109 cp++;
110 if (*cp)
111 goto inv_syntax;
112 if (bin_file_buf) {
113 bcopy(record, bin_file_buf + (recno - 1) * curfile_record_len,
114 curfile_record_len);
115 return(0);
116 } else
117 return update_rec_op(recno, 0x04, record, curfile_record_len);
118 }
119
120 cmd_pb_restore(argc, argv)
121 char **argv;
122 {
123 int rc;
124 FILE *inf;
125 int lineno;
126 char linebuf[1024];
127 u_char *databuf;
128
129 rc = phonebook_op_common(argv[1]);
130 if (rc < 0)
131 return(rc);
132 databuf = malloc(curfile_total_size);
133 if (!databuf) {
134 perror("malloc for full phonebook EF");
135 return(-1);
136 }
137 inf = fopen(argv[2], "r");
138 if (!inf) {
139 perror(argv[2]);
140 free(databuf);
141 return(-1);
142 }
143 memset(databuf, 0xFF, curfile_total_size);
144 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
145 if (!index(linebuf, '\n')) {
146 fprintf(stderr,
147 "%s line %d: too long or missing newline\n",
148 argv[2], lineno);
149 fclose(inf);
150 free(databuf);
151 return(-1);
152 }
153 if (linebuf[0] != '#' || !isdigit(linebuf[1]))
154 continue;
155 rc = process_record(linebuf, databuf, argv[2], lineno);
156 if (rc < 0) {
157 fclose(inf);
158 free(databuf);
159 return(rc);
160 }
161 }
162 fclose(inf);
163 rc = restore_bin_records(databuf);
164 free(databuf);
165 return(rc);
166 }
167
168 cmd_pb_update(argc, argv)
169 char **argv;
170 {
171 int rc;
172 FILE *inf;
173 int lineno;
174 char linebuf[1024];
175
176 rc = phonebook_op_common(argv[1]);
177 if (rc < 0)
178 return(rc);
179 inf = fopen(argv[2], "r");
180 if (!inf) {
181 perror(argv[2]);
182 return(-1);
183 }
184 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
185 if (!index(linebuf, '\n')) {
186 fprintf(stderr,
187 "%s line %d: too long or missing newline\n",
188 argv[2], lineno);
189 fclose(inf);
190 return(-1);
191 }
192 if (linebuf[0] != '#' || !isdigit(linebuf[1]))
193 continue;
194 rc = process_record(linebuf, 0, argv[2], lineno);
195 if (rc < 0) {
196 fclose(inf);
197 return(rc);
198 }
199 }
200 fclose(inf);
201 return(0);
202 }