FreeCalypso > hg > freecalypso-reveng
view pirollback/catino.c @ 193:37f78f986a0a
grokdsn: tree dump implemented
author | Michael Spacefalcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 07 Jan 2015 08:09:30 +0000 |
parents | 18fa570685de |
children |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "types.h" #include "struct.h" extern char *imgfile; extern struct inode_info inode[]; extern int last_inode; extern int journal_start_ino; u8 * find_end_of_chunk(ino) { struct inode_info *ch = inode + ino; u8 *p; int i; p = ch->dataptr + ch->len; for (i = 1; i <= 16; i++) { if (!p[-i]) return(p - i); if (p[-1] != 0xFF) break; } fprintf(stderr, "chunk starting at %x (inode #%x): no valid termination found\n", ch->offset, ino); exit(1); } dump_cont_chain(start) { int ino; struct inode_info *inf; u8 *endp; for (ino = start; ino; ino = inf->descend) { inf = inode + ino; if (inf->type != 0xF4) { fprintf(stderr, "continuation chunk #%x does not have type F4\n", ino); exit(1); } endp = find_end_of_chunk(ino); write(1, inf->dataptr, endp - inf->dataptr); } } do_cat(ino) { struct inode_info *inf = inode + ino; u8 *endp; if (inf->type != 0xF1) { fprintf(stderr, "error: requested inode is not a file\n"); exit(1); } endp = find_end_of_chunk(ino); if (endp > inf->byte_after_name) write(1, inf->byte_after_name, endp - inf->byte_after_name); dump_cont_chain(inf->descend); } main(argc, argv) char **argv; { int ino; char *strtoul_endp; if (argc != 3) { usage: fprintf(stderr, "usage: %s ffs-image inode\n", argv[0]); exit(1); } imgfile = argv[1]; ino = strtoul(argv[2], &strtoul_endp, 16); if (!argv[2][0] || *strtoul_endp) goto usage; read_img_file(); read_inodes(); walk_tree(); check_object_names(); parse_journal(); check_object_names(); /* rerun for "undeleted" objects */ if (ino < 1 || ino > last_inode) { fprintf(stderr, "%s: bad inode number specified\n", argv[0]); exit(1); } do_cat(ino); exit(0); }