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