comparison simtool/bfsearch.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 a brute force search of file ID space at a given
3 * file system directory level.
4 */
5
6 #include <sys/types.h>
7 #include <ctype.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "simresp.h"
11 #include "file_id.h"
12
13 static
14 parse_skip_ids(argv, array, total)
15 char **argv;
16 unsigned *array, total;
17 {
18 unsigned n;
19
20 for (n = 0; n < total; n++) {
21 if (!isxdigit(argv[n][0]) || !isxdigit(argv[n][1]) ||
22 !isxdigit(argv[n][2]) || !isxdigit(argv[n][3]) ||
23 argv[n][4]) {
24 fprintf(stderr, "error: argument is not 4-digit hex\n");
25 return(-1);
26 }
27 array[n] = strtoul(argv[n], 0, 16);
28 }
29 return(0);
30 }
31
32 static void
33 report_ef_struct(outf)
34 FILE *outf;
35 {
36 unsigned total_size, record_len;
37
38 fputs("EF, ", outf);
39 total_size = (sim_resp_data[2] << 8) | sim_resp_data[3];
40 switch (sim_resp_data[13]) {
41 case 0x00:
42 fprintf(outf, "transparent, length %u\n", total_size);
43 return;
44 case 0x01:
45 fputs("linear fixed, ", outf);
46 break;
47 case 0x03:
48 fputs("cyclic, ", outf);
49 break;
50 default:
51 fprintf(outf, "struct 0x%02X\n", sim_resp_data[13]);
52 return;
53 }
54 if (sim_resp_data_len < 15) {
55 fprintf(outf, "response struct cut off\n");
56 return;
57 }
58 record_len = sim_resp_data[14];
59 fprintf(outf, "record length %u", record_len);
60 if (record_len && total_size % record_len == 0)
61 fprintf(outf, ", %u records", total_size / record_len);
62 putc('\n', outf);
63 }
64
65 cmd_bfsearch(argc, argv, outf)
66 char **argv;
67 FILE *outf;
68 {
69 unsigned skip_ids[8], num_skip_ids;
70 unsigned bfs, n;
71 int rc;
72
73 num_skip_ids = argc - 1;
74 rc = parse_skip_ids(argv + 1, skip_ids, num_skip_ids);
75 if (rc < 0)
76 return(rc);
77 rc = elem_select_op(skip_ids[0]);
78 if (rc < 0)
79 return(rc);
80 if (!rc) {
81 fprintf(stderr, "error: starting file ID 0x%04X not found\n",
82 skip_ids[0]);
83 return(-1);
84 }
85 for (bfs = 0; bfs <= 0xFFFF; bfs++) {
86 for (n = 0; n < num_skip_ids; n++) {
87 if (bfs == skip_ids[n])
88 break;
89 }
90 if (n < num_skip_ids)
91 continue;
92 rc = elem_select_op(bfs);
93 if (rc < 0)
94 return(rc);
95 if (!rc)
96 continue;
97 rc = get_response_op();
98 if (rc < 0)
99 return(rc);
100 fprintf(outf, "%04X: ", bfs);
101 if (sim_resp_data_len < 14)
102 fprintf(outf, "too-short response struct\n");
103 else {
104 switch (sim_resp_data[6]) {
105 case 0x01:
106 fprintf(outf, "MF\n");
107 break;
108 case 0x02:
109 fprintf(outf, "DF\n");
110 break;
111 case 0x04:
112 report_ef_struct(outf);
113 break;
114 default:
115 fprintf(outf, "unknown file type %02X\n",
116 sim_resp_data[6]);
117 }
118 }
119 rc = elem_select_op(skip_ids[0]);
120 if (rc < 0)
121 return(rc);
122 if (!rc) {
123 fprintf(stderr,
124 "reselecting starting file ID 0x%04X not-found error\n",
125 skip_ids[0]);
126 return(-1);
127 }
128 }
129 return(0);
130 }
131
132 static
133 bfsearch_dir(path, pathlen, siblings, nsiblings, outf)
134 unsigned *path, pathlen, *siblings, nsiblings;
135 FILE *outf;
136 {
137 unsigned bfs, n;
138 unsigned df_children[255], ndfc;
139 unsigned childpath[8];
140 int rc;
141
142 for (n = 0; n < pathlen; n++) {
143 rc = elem_select_op(path[n]);
144 if (rc < 0)
145 return(rc);
146 if (!rc) {
147 fprintf(stderr,
148 "error selecting 0x%04X: file not found\n",
149 path[n]);
150 return(-1);
151 }
152 }
153 ndfc = 0;
154 for (bfs = 0; bfs <= 0xFFFF; bfs++) {
155 for (n = 0; n < pathlen; n++) {
156 if (bfs == path[n])
157 break;
158 }
159 if (n < pathlen)
160 continue;
161 for (n = 0; n < nsiblings; n++) {
162 if (bfs == siblings[n])
163 break;
164 }
165 if (n < nsiblings)
166 continue;
167 rc = elem_select_op(bfs);
168 if (rc < 0)
169 return(rc);
170 if (!rc)
171 continue;
172 rc = get_response_op();
173 if (rc < 0)
174 return(rc);
175 for (n = 0; n < pathlen; n++)
176 fprintf(outf, "%04X/", path[n]);
177 fprintf(outf, "%04X: ", bfs);
178 if (sim_resp_data_len < 14)
179 fprintf(outf, "too-short response struct\n");
180 else {
181 switch (sim_resp_data[6]) {
182 case 0x01:
183 fprintf(outf, "MF\n");
184 break;
185 case 0x02:
186 fprintf(outf, "DF\n");
187 if (ndfc < 255)
188 df_children[ndfc++] = bfs;
189 break;
190 case 0x04:
191 report_ef_struct(outf);
192 break;
193 default:
194 fprintf(outf, "unknown file type %02X\n",
195 sim_resp_data[6]);
196 }
197 }
198 rc = elem_select_op(path[pathlen-1]);
199 if (rc < 0)
200 return(rc);
201 if (!rc) {
202 fprintf(stderr,
203 "reselecting starting file ID 0x%04X not-found error\n",
204 path[pathlen-1]);
205 return(-1);
206 }
207 }
208 if (pathlen >= 8)
209 return(0);
210 for (n = 0; n < pathlen; n++)
211 childpath[n] = path[n];
212 for (n = 0; n < ndfc; n++) {
213 childpath[pathlen] = df_children[n];
214 rc = bfsearch_dir(childpath, pathlen + 1, df_children, ndfc,
215 outf);
216 if (rc < 0)
217 return(rc);
218 }
219 return(0);
220 }
221
222 cmd_bfsearch_full(argc, argv, outf)
223 char **argv;
224 FILE *outf;
225 {
226 unsigned initpath;
227
228 initpath = FILEID_MF;
229 return bfsearch_dir(&initpath, 1, &initpath, 1, outf);
230 }