# HG changeset patch # User Michael Spacefalcon # Date 1373183043 0 # Node ID 18fa570685de6d4c0edf412b599dac903c933938 # Parent 79a0897dee7bc2660745d9f824cf5e19ffd4950b pirollback: catino implemented, works diff -r 79a0897dee7b -r 18fa570685de .hgignore --- a/.hgignore Sun Jul 07 07:15:58 2013 +0000 +++ b/.hgignore Sun Jul 07 07:44:03 2013 +0000 @@ -14,5 +14,6 @@ ^mysteryffs/scan1$ ^pirollback/analyze$ +^pirollback/catino$ ^pirollback/dumpjournal$ ^pirollback/inopath$ diff -r 79a0897dee7b -r 18fa570685de pirollback/Makefile --- a/pirollback/Makefile Sun Jul 07 07:15:58 2013 +0000 +++ b/pirollback/Makefile Sun Jul 07 07:44:03 2013 +0000 @@ -1,8 +1,9 @@ CC= gcc CFLAGS= -O2 -PROGS= analyze dumpjournal inopath +PROGS= analyze catino dumpjournal inopath ANALYZE_OBJS= analyze.o checknames.o init.o journal.o treewalk.o +CAT_OBJS= catino.o checknames.o init.o journal.o treewalk.o DUMPJ_OBJS= checknames.o dumpjournal.o init.o journal.o pathname.o \ treewalk.o INOPATH_OBJS= checknames.o init.o inopath.o pathname.o treewalk.o @@ -12,6 +13,9 @@ analyze: ${ANALYZE_OBJS} ${CC} -o $@ ${ANALYZE_OBJS} +catino: ${CAT_OBJS} + ${CC} -o $@ ${CAT_OBJS} + dumpjournal: ${DUMPJ_OBJS} ${CC} -o $@ ${DUMPJ_OBJS} diff -r 79a0897dee7b -r 18fa570685de pirollback/catino.c --- /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 +#include +#include +#include +#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); +}