FreeCalypso > hg > freecalypso-reveng
diff pirollback/catino.c @ 49:18fa570685de
pirollback: catino implemented, works
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 07 Jul 2013 07:44:03 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pirollback/catino.c Sun Jul 07 07:44:03 2013 +0000 @@ -0,0 +1,93 @@ +#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); +}