FreeCalypso > hg > freecalypso-reveng
comparison mpffs/dbgls.c @ 33:660b0ea739f3
mpffs-dbgls implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 30 Jun 2013 07:47:49 +0000 |
parents | |
children | 95f61c3b430a |
comparison
equal
deleted
inserted
replaced
32:0bf037ba4149 | 33:660b0ea739f3 |
---|---|
1 /* | |
2 * Whereas mpffs-ls is more user-oriented, mpffs-dbgls is structured a little | |
3 * different in order to provide a more low-level view of the FFS structure. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <ctype.h> | |
8 #include <stdio.h> | |
9 #include <string.h> | |
10 #include <strings.h> | |
11 #include <stdlib.h> | |
12 #include <unistd.h> | |
13 #include "types.h" | |
14 #include "struct.h" | |
15 | |
16 extern char *imgfile; | |
17 extern u8 *image; | |
18 extern struct objinfo root; | |
19 extern int verbose; | |
20 | |
21 char workpath[512]; | |
22 | |
23 void | |
24 dump_extra_chunks(first_extra_chunk) | |
25 { | |
26 int ent; | |
27 struct objinfo ch; | |
28 struct chunkinfo chi; | |
29 | |
30 for (ent = first_extra_chunk; ent != 0xFFFF; ent = ch.descend) { | |
31 ch.entryno = ent; | |
32 get_index_entry(&ch); | |
33 if (ch.type != 0xF4) { | |
34 fprintf(stderr, | |
35 "file continuation object at index %x: type %02X != expected F4\n", | |
36 ent, ch.type); | |
37 return; | |
38 } | |
39 validate_chunk(&ch); | |
40 printf(" #%x chunk addr=0x%x len=0x%x\n", ch.entryno, | |
41 ch.offset, ch.len); | |
42 size_extra_chunk(&ch, &chi); | |
43 printf(" extra chunk: %lu bytes at 0x%lx\n", (u_long) chi.len, | |
44 (u_long)(chi.start-image)); | |
45 if (ch.sibling != 0xFFFF) | |
46 fprintf(stderr, | |
47 "warning: file continuation object (index %x) has a non-nil sibling pointer\n", | |
48 ent); | |
49 } | |
50 } | |
51 | |
52 void | |
53 dump_object(obj) | |
54 struct objinfo *obj; | |
55 { | |
56 int typechar; | |
57 struct chunkinfo chi; | |
58 | |
59 switch (obj->type) { | |
60 case 0xF2: | |
61 /* directory */ | |
62 typechar = 'd'; | |
63 break; | |
64 case 0xF1: | |
65 /* regular file */ | |
66 typechar = '-'; | |
67 break; | |
68 case 0xE1: | |
69 /* special .journal file */ | |
70 typechar = 'j'; | |
71 break; | |
72 default: | |
73 /* unknown! */ | |
74 typechar = 'U'; | |
75 } | |
76 printf("%c %s\n", typechar, workpath); | |
77 printf(" #%x chunk addr=0x%x len=0x%x\n", obj->entryno, | |
78 obj->offset, obj->len); | |
79 switch (obj->type) { | |
80 case 0xF2: | |
81 /* directory */ | |
82 return; | |
83 case 0xF1: | |
84 /* regular file */ | |
85 size_head_chunk(obj, &chi); | |
86 printf(" head chunk: %lu bytes at 0x%lx\n", (u_long) chi.len, | |
87 (u_long)(chi.start-image)); | |
88 dump_extra_chunks(obj->descend); | |
89 return; | |
90 default: | |
91 if (obj->descend != 0xFFFF) | |
92 printf(" unexpected descend pointer: %x\n", | |
93 obj->descend); | |
94 } | |
95 } | |
96 | |
97 dump_dir(firstent, path_prefix) | |
98 { | |
99 int ent; | |
100 struct objinfo obj; | |
101 | |
102 for (ent = firstent; ent != 0xFFFF; ent = obj.sibling) { | |
103 obj.entryno = ent; | |
104 get_index_entry(&obj); | |
105 if (!obj.type) /* skip deleted objects w/o further validation */ | |
106 continue; | |
107 validate_chunk(&obj); | |
108 validate_obj_name(&obj); | |
109 if (path_prefix + strlen(obj.dataptr) + 2 > sizeof workpath) { | |
110 fprintf(stderr, | |
111 "handling object at index %x, name \"%s\": path buffer overflow\n", | |
112 obj.entryno, (char *)obj.dataptr); | |
113 exit(1); | |
114 } | |
115 sprintf(workpath + path_prefix, "/%s", (char *)obj.dataptr); | |
116 dump_object(&obj); | |
117 if (obj.type == 0xF2) | |
118 dump_dir(obj.descend, strlen(workpath)); | |
119 } | |
120 } | |
121 | |
122 usage() | |
123 { | |
124 fprintf(stderr, "usage: mpffs-dbgls [options] ffs-image\n"); | |
125 exit(1); | |
126 } | |
127 | |
128 main(argc, argv) | |
129 char **argv; | |
130 { | |
131 extern int optind; | |
132 | |
133 parse_cmdline_options(argc, argv); | |
134 if (argc - optind != 1) | |
135 usage(); | |
136 verbose++; | |
137 imgfile = argv[optind]; | |
138 preliminaries(); | |
139 dump_dir(root.descend, 0); | |
140 exit(0); | |
141 } |