# HG changeset patch # User Michael Spacefalcon # Date 1390733682 0 # Node ID ae9ff2d1e3da1356822d1ebd9999d25574455c94 # Parent 73372cfdaf7f0dd9dfbd4bdd1742762f556384ff tiffs IVA: basic ls integrated diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/Makefile --- a/ffstools/tiffs-rd/Makefile Sun Jan 26 08:42:59 2014 +0000 +++ b/ffstools/tiffs-rd/Makefile Sun Jan 26 10:54:42 2014 +0000 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 PROG= tiffs -OBJS= basics.o globals.o inode.o main.o +OBJS= basics.o globals.o inode.o ls.o main.o object.o tree.o HDRS= globals.h pathname.h struct.h types.h all: ${PROG} diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/inode.c --- a/ffstools/tiffs-rd/inode.c Sun Jan 26 08:42:59 2014 +0000 +++ b/ffstools/tiffs-rd/inode.c Sun Jan 26 10:54:42 2014 +0000 @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -12,7 +11,6 @@ #include "types.h" #include "struct.h" #include "globals.h" -#include "pathname.h" u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; @@ -161,44 +159,3 @@ fprintf(stderr, "error: no root inode found; try -r\n"); exit(1); } - -validate_obj_name(ino, root_special) -{ - struct inode_info *inf = inode_info[ino]; - u8 *p, *endp; - int c; - - if (!inf->len) - return(0); - p = inf->dataptr; - endp = p + inf->len; - for (; ; p++) { - if (p >= endp) - return(0); - c = *p; - if (!c) - break; - if (c < ' ' || c > '~') - return(0); - if (root_special || isalnum(c)) - continue; - switch (c) { - case '.': - case ',': - case '_': - case '-': - case '+': - case '%': - case '$': - case '#': - continue; - default: - return(0); - } - } - c = p - inf->dataptr; - if (c < 1 || c > MAX_FN_COMPONENT && !root_special) - return(0); - inf->byte_after_name = p + 1; - return(1); -} diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/ls.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/ls.c Sun Jan 26 10:54:42 2014 +0000 @@ -0,0 +1,49 @@ +/* + * This C module implements the ls command. + */ + +#include +#include +#include +#include +#include "types.h" +#include "struct.h" +#include "globals.h" +#include "pathname.h" + +void +ls_callback(pathname, ino, depth) + char *pathname; +{ + struct inode_info *inf = inode_info[ino]; + char type; + + switch (inf->type) { + case 0xE1: + case 0xF1: + type = 'f'; + break; + case 0xF2: + type = 'd'; + break; + case 0xF3: + type = 'l'; + break; + default: + fprintf(stderr, + "BUG: bad inode byte %02X reached ls_callback()\n", + inf->type); + exit(1); + } + printf("%c %s\n", type, pathname); +} + +cmd_ls() +{ + read_ffs_image(); + find_inode_block(); + alloc_inode_table(); + find_root_inode(); + traverse_visible_tree(ls_callback); + exit(0); +} diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/main.c --- a/ffstools/tiffs-rd/main.c Sun Jan 26 08:42:59 2014 +0000 +++ b/ffstools/tiffs-rd/main.c Sun Jan 26 10:54:42 2014 +0000 @@ -55,6 +55,7 @@ extern int cmd_blkhdr(); extern int cmd_fsinfo(); +extern int cmd_ls(); static struct cmdtab { char *cmd; @@ -64,7 +65,7 @@ {"cat", NULL}, {"fsck", NULL}, {"fsinfo", cmd_fsinfo}, - {"ls", NULL}, + {"ls", cmd_ls}, {"xtr", NULL}, {NULL, NULL} }; diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/object.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/object.c Sun Jan 26 10:54:42 2014 +0000 @@ -0,0 +1,58 @@ +/* + * This C module implements object-level analysis. + */ + +#include +#include +#include +#include +#include +#include "types.h" +#include "struct.h" +#include "globals.h" +#include "pathname.h" + +validate_obj_name(ino, root_special) +{ + struct inode_info *inf = inode_info[ino]; + u8 *p, *endp; + int c; + + if (!inf->len) + return(0); + p = inf->dataptr; + endp = p + inf->len; + for (; ; p++) { + if (p >= endp) + return(0); + c = *p; + if (!c) + break; + if (c < ' ' || c > '~') + return(0); + if (root_special || isalnum(c)) + continue; + switch (c) { + case '.': + case ',': + case '_': + case '-': + case '+': + case '%': + case '$': + case '#': + continue; + default: + return(0); + } + } + if (!root_special) { + c = p - inf->dataptr; + if (c < 1 || c > MAX_FN_COMPONENT) + return(0); + if (!strcmp(inf->dataptr, ".") || !strcmp(inf->dataptr, "..")) + return(0); + } + inf->byte_after_name = p + 1; + return(1); +} diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/pathname.h --- a/ffstools/tiffs-rd/pathname.h Sun Jan 26 08:42:59 2014 +0000 +++ b/ffstools/tiffs-rd/pathname.h Sun Jan 26 10:54:42 2014 +0000 @@ -1,3 +1,3 @@ #define MAX_FN_COMPONENT 20 #define MAX_DIR_NEST 6 -#define PATHNAME_BUF_SIZE ((MAX_FN_COMPONENT+1) * MAX_DIR_NEST + 2) +#define PATHNAME_BUF_SIZE ((MAX_FN_COMPONENT+1) * (MAX_DIR_NEST+1) + 1) diff -r 73372cfdaf7f -r ae9ff2d1e3da ffstools/tiffs-rd/tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/tree.c Sun Jan 26 10:54:42 2014 +0000 @@ -0,0 +1,68 @@ +/* + * This C module implements operations on the tree level. + */ + +#include +#include +#include +#include +#include "types.h" +#include "struct.h" +#include "globals.h" +#include "pathname.h" + +static void +visible_walk_dir(pathbuf_start, pathbuf_ptr, dirino, depth, callback) + char *pathbuf_start, *pathbuf_ptr; + void (*callback)(); +{ + int ndepth = depth + 1; + int child; + struct inode_info *inf; + + if (depth > MAX_DIR_NEST) { + fprintf(stderr, + "error: max dir nesting exceeded at inode #%x\n", + dirino); + return; + } + for (child = inode_info[dirino]->descend; child; child = inf->sibling) { + if (!validate_inode(child)) { + fprintf(stderr, + "error: walk of visible tree hit invalid inode #%x\n", + child); + return; + } + inf = inode_info[child]; + switch (inf->type) { + case 0x00: + /* walking the *visible* tree: skip deleted objects */ + continue; + case 0xF4: + fprintf(stderr, + "warning: directory #%x has child #%x of type segment (F4), skipping\n", + dirino, child); + continue; + } + if (!validate_obj_name(child, 0)) { + fprintf(stderr, + "visible tree walk error: no valid name for inode #%x\n", + child); + continue; + } + sprintf(pathbuf_ptr, "/%s", inf->dataptr); + callback(pathbuf_start, child, ndepth); + if (inf->type == 0xF2) + visible_walk_dir(pathbuf_start, + index(pathbuf_ptr, '\0'), child, + ndepth, callback); + } +} + +traverse_visible_tree(callback) + void (*callback)(); +{ + char pathbuf[PATHNAME_BUF_SIZE]; + + visible_walk_dir(pathbuf, pathbuf, root_inode, 0, callback); +}