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 }