FreeCalypso > hg > freecalypso-reveng
comparison miscprog/grokdsn.c @ 193:37f78f986a0a
grokdsn: tree dump implemented
author | Michael Spacefalcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 07 Jan 2015 08:09:30 +0000 |
parents | 5d84f63eff72 |
children | 805e99848aea |
comparison
equal
deleted
inserted
replaced
192:5d84f63eff72 | 193:37f78f986a0a |
---|---|
45 uint32_t mfat_start; | 45 uint32_t mfat_start; |
46 uint32_t mfat_sectors; | 46 uint32_t mfat_sectors; |
47 uint32_t fat_secids[HEADER_MFAT_ENTRIES]; | 47 uint32_t fat_secids[HEADER_MFAT_ENTRIES]; |
48 }; | 48 }; |
49 | 49 |
50 struct dir_entry { | |
51 uint16_t uni_name[32]; | |
52 uint16_t name_len; | |
53 u_char type; | |
54 u_char color; | |
55 uint32_t left_child; | |
56 uint32_t right_child; | |
57 uint32_t subtree_dirid; | |
58 u_char uid[16]; | |
59 u_char user_flags[4]; | |
60 u_char time_creat[8]; | |
61 u_char time_lastmod[8]; | |
62 uint32_t content_secid; | |
63 uint32_t content_bytes; | |
64 u_char rsvd[4]; | |
65 }; | |
66 | |
50 char *dsnfilename; | 67 char *dsnfilename; |
51 u_char *filemapping; | 68 u_char *filemapping; |
52 struct cdf_header *cdf_header; | 69 struct cdf_header *cdf_header; |
53 unsigned total_sectors, fat_nsectors; | 70 unsigned total_sectors, fat_nsectors; |
71 | |
72 #define MAX_DIR_SECTORS 64 | |
73 unsigned dir_nsectors, dir_secids[MAX_DIR_SECTORS]; | |
54 | 74 |
55 open_and_mmap_file() | 75 open_and_mmap_file() |
56 { | 76 { |
57 int fd; | 77 int fd; |
58 struct stat st; | 78 struct stat st; |
173 i = n; | 193 i = n; |
174 } | 194 } |
175 return(0); | 195 return(0); |
176 } | 196 } |
177 | 197 |
198 locate_dir_sectors() | |
199 { | |
200 int sec, next, num; | |
201 | |
202 sec = le32toh(cdf_header->dir_start); | |
203 for (num = 0; sec >= 0; sec = next) { | |
204 if (num >= MAX_DIR_SECTORS) { | |
205 fprintf(stderr, "error: MAX_DIR_SECTORS exceeded\n"); | |
206 exit(1); | |
207 } | |
208 dir_secids[num++] = sec; | |
209 next = get_fat_entry(sec); | |
210 } | |
211 dir_nsectors = num; | |
212 return(0); | |
213 } | |
214 | |
215 u_char * | |
216 get_dir_sector(dir_sec_no) | |
217 unsigned dir_sec_no; | |
218 { | |
219 unsigned secid; | |
220 | |
221 if (dir_sec_no > dir_nsectors) { | |
222 fprintf(stderr, | |
223 "error: request for dir sector #%u; we only have %u in total\n", | |
224 dir_sec_no, dir_nsectors); | |
225 exit(1); | |
226 } | |
227 secid = dir_secids[dir_sec_no]; | |
228 return get_sector_ptr(secid); | |
229 } | |
230 | |
231 struct dir_entry * | |
232 get_dir_entry(dirid) | |
233 unsigned dirid; | |
234 { | |
235 unsigned dir_sec_no, entry_in_sec; | |
236 struct dir_entry *dir_sector; | |
237 | |
238 dir_sec_no = dirid / 4; | |
239 entry_in_sec = dirid % 4; | |
240 dir_sector = (struct dir_entry *) get_dir_sector(dir_sec_no); | |
241 return dir_sector + entry_in_sec; | |
242 } | |
243 | |
244 dump_dir_entry(rec, indent) | |
245 struct dir_entry *rec; | |
246 { | |
247 int i, u; | |
248 | |
249 for (i = indent; i; i--) | |
250 putchar(' '); | |
251 for (i = 0; i < 32; i++) { | |
252 u = le16toh(rec->uni_name[i]); | |
253 if (u == 0) | |
254 break; | |
255 if (u >= ' ' && u <= '~') | |
256 putchar(u); | |
257 else | |
258 printf("<%04X>", u); | |
259 } | |
260 printf(" (type %02X, length %u)\n", rec->type, rec->content_bytes); | |
261 return(0); | |
262 } | |
263 | |
264 dump_dir_level(dirid, indent) | |
265 unsigned dirid; | |
266 { | |
267 struct dir_entry *rec; | |
268 int32_t ndir; | |
269 | |
270 rec = get_dir_entry(dirid); | |
271 ndir = le32toh(rec->left_child); | |
272 if (ndir >= 0) | |
273 dump_dir_level(ndir, indent); | |
274 dump_dir_entry(rec, indent); | |
275 ndir = le32toh(rec->right_child); | |
276 if (ndir >= 0) | |
277 dump_dir_level(ndir, indent); | |
278 ndir = le32toh(rec->subtree_dirid); | |
279 if (ndir >= 0) | |
280 dump_dir_level(ndir, indent + 2); | |
281 return(0); | |
282 } | |
283 | |
284 dump_dir_tree() | |
285 { | |
286 init_fat_access(); | |
287 locate_dir_sectors(); | |
288 dump_dir_level(0, 0); | |
289 return(0); | |
290 } | |
291 | |
178 main(argc, argv) | 292 main(argc, argv) |
179 char **argv; | 293 char **argv; |
180 { | 294 { |
181 if (sizeof(struct cdf_header) != 512) { | 295 if (sizeof(struct cdf_header) != 512) { |
182 fprintf(stderr, "error: struct cdf_header is misdefined\n"); | 296 fprintf(stderr, "error: struct cdf_header is misdefined\n"); |
297 exit(1); | |
298 } | |
299 if (sizeof(struct dir_entry) != 128) { | |
300 fprintf(stderr, "error: struct dir_entry is misdefined\n"); | |
183 exit(1); | 301 exit(1); |
184 } | 302 } |
185 if (argc < 3) { | 303 if (argc < 3) { |
186 fprintf(stderr, "usage: %s binfile.dsn <op> [args]\n", argv[0]); | 304 fprintf(stderr, "usage: %s binfile.dsn <op> [args]\n", argv[0]); |
187 exit(1); | 305 exit(1); |
190 open_and_mmap_file(); | 308 open_and_mmap_file(); |
191 if (!strcmp(argv[2], "hdr")) | 309 if (!strcmp(argv[2], "hdr")) |
192 return dump_cdf_header(); | 310 return dump_cdf_header(); |
193 if (!strcmp(argv[2], "fatchain")) | 311 if (!strcmp(argv[2], "fatchain")) |
194 return dump_fat_chain(argv[3]); | 312 return dump_fat_chain(argv[3]); |
313 if (!strcmp(argv[2], "ls")) | |
314 return dump_dir_tree(); | |
195 fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]); | 315 fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]); |
196 exit(1); | 316 exit(1); |
197 } | 317 } |