# HG changeset patch # User Michael Spacefalcon # Date 1390807253 0 # Node ID 10afa4d39a7b660583e3ef3595accdded5a57e98 # Parent 190121a34b3b14ee2da911874a452915334a788c tiffs xtr implemented diff -r 190121a34b3b -r 10afa4d39a7b ffstools/tiffs-rd/Makefile --- a/ffstools/tiffs-rd/Makefile Mon Jan 27 06:42:03 2014 +0000 +++ b/ffstools/tiffs-rd/Makefile Mon Jan 27 07:20:53 2014 +0000 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 PROG= tiffs -OBJS= basics.o cat.o globals.o inode.o ls.o main.o object.o tree.o +OBJS= basics.o cat.o globals.o inode.o ls.o main.o object.o tree.o xtr.o HDRS= globals.h pathname.h struct.h types.h INSTBIN=/usr/local/bin diff -r 190121a34b3b -r 10afa4d39a7b ffstools/tiffs-rd/ls.c --- a/ffstools/tiffs-rd/ls.c Mon Jan 27 06:42:03 2014 +0000 +++ b/ffstools/tiffs-rd/ls.c Mon Jan 27 07:20:53 2014 +0000 @@ -97,7 +97,7 @@ return; default: fprintf(stderr, - "BUG: bad inode byte %02X reached ls_callback()\n", + "BUG: bad inode byte %02X reached ls_tree_callback()\n", inf->type); exit(1); } diff -r 190121a34b3b -r 10afa4d39a7b ffstools/tiffs-rd/main.c --- a/ffstools/tiffs-rd/main.c Mon Jan 27 06:42:03 2014 +0000 +++ b/ffstools/tiffs-rd/main.c Mon Jan 27 07:20:53 2014 +0000 @@ -59,6 +59,7 @@ extern int cmd_fsinfo(); extern int cmd_ls(); extern int cmd_lsino(); +extern int cmd_xtr(); static struct cmdtab { char *cmd; @@ -71,7 +72,7 @@ {"fsinfo", cmd_fsinfo}, {"ls", cmd_ls}, {"lsino", cmd_lsino}, - {"xtr", NULL}, + {"xtr", cmd_xtr}, {NULL, NULL} }; diff -r 190121a34b3b -r 10afa4d39a7b ffstools/tiffs-rd/xtr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/xtr.c Mon Jan 27 07:20:53 2014 +0000 @@ -0,0 +1,103 @@ +/* + * This C module implements the xtr command. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "types.h" +#include "struct.h" +#include "globals.h" +#include "pathname.h" + +static void +dump_head_chunk(fd, headino) +{ + struct inode_info *inf = inode_info[headino]; + struct chunkinfo chi; + + if (size_head_chunk(inf, &chi)) + write(fd, chi.start, chi.len); +} + +static void +dump_extra_chunk(inf, opaque) + struct inode_info *inf; + u_long opaque; +{ + int fd = (int)opaque; + struct chunkinfo chi; + + size_extra_chunk(inf, &chi); + write(fd, chi.start, chi.len); +} + +extract_file(relpath, headino) + char *relpath; +{ + int fd; + + fd = open(relpath, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (fd < 0) { + perror(relpath); + exit(1); + } + dump_head_chunk(fd, headino); + iterate_seg_file(headino, dump_extra_chunk, (u_long)fd, 0, 0); + close(fd); +} + +void +xtr_tree_callback(pathname, ino, depth) + char *pathname; +{ + struct inode_info *inf = inode_info[ino]; + + switch (inf->type) { + case 0xE1: + case 0xF1: + extract_file(pathname + 1, ino); + return; + case 0xE2: + case 0xF2: + if (mkdir(pathname + 1, 0777) < 0) { + perror(pathname + 1); + exit(1); + } + return; + case 0xE3: + case 0xF3: + fprintf(stderr, + "symlink at %s ignored: symlink extraction not implemented yet\n", + pathname); + return; + default: + fprintf(stderr, + "BUG: bad inode byte %02X reached xtr_tree_callback()\n", + inf->type); + exit(1); + } +} + +cmd_xtr(argc, argv) + char **argv; +{ + if (argc != 2) { + fprintf(stderr, "usage: xtr dest-dir\n"); + exit(1); + } + read_ffs_image(); + find_inode_block(); + alloc_inode_table(); + find_root_inode(); + if (chdir(argv[1]) < 0) { + perror(argv[1]); + exit(1); + } + traverse_visible_tree(xtr_tree_callback); + exit(0); +}