# HG changeset patch # User Michael Spacefalcon # Date 1390723902 0 # Node ID 5ceacdbd44903085abe244443de7d39b3eff2e68 # Parent ffaa033e7643d6a18fbe709d8f4e47551c3896eb tiffs IVA: finds the root inode diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/Makefile --- a/ffstools/tiffs-rd/Makefile Sun Jan 26 00:34:22 2014 +0000 +++ b/ffstools/tiffs-rd/Makefile Sun Jan 26 08:11:42 2014 +0000 @@ -1,12 +1,15 @@ CC= gcc CFLAGS= -O2 PROG= tiffs -OBJS= basics.o main.o +OBJS= basics.o globals.o inode.o main.o +HDRS= globals.h pathname.h struct.h types.h all: ${PROG} ${PROG}: ${OBJS} ${CC} -o $@ ${OBJS} +${OBJS}: ${HDRS} + clean: rm -f ${PROG} *.o *.out *errs diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/basics.c --- a/ffstools/tiffs-rd/basics.c Sun Jan 26 00:34:22 2014 +0000 +++ b/ffstools/tiffs-rd/basics.c Sun Jan 26 08:11:42 2014 +0000 @@ -12,19 +12,9 @@ #include #include #include "types.h" +#include "globals.h" u8 tiffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02}; -u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - -extern char *imgfile; -extern u32 eraseblk_size; -extern int total_blocks; -extern u32 total_ffs_size; -extern int index_blk_num, root_node_no; -extern int verbose; - -u8 *image, *inode_block; read_ffs_image() { @@ -109,7 +99,7 @@ switch (ptr[8]) { case 0xAB: if (verbose) - printf( + fprintf(stderr, "Found AB index in erase block #%d (offset %x)\n", i, ptr - image); index_blk_num = i; @@ -143,5 +133,8 @@ read_ffs_image(); find_inode_block(); printf("Active inode block (AB) is block #%d\n", index_blk_num); + alloc_inode_table(); + find_root_inode(); + printf("Root inode is #%x\n", root_inode); exit(0); } diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/globals.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/globals.c Sun Jan 26 08:11:42 2014 +0000 @@ -0,0 +1,17 @@ +/* + * Definitions of global variables for the tiffs IVA program. + */ + +#include "types.h" +#include "struct.h" + +char *imgfile; +u32 eraseblk_size; +int total_blocks; +u32 total_ffs_size; +int index_blk_num = -1, root_inode; +int inode_limit; +int verbose; + +u8 *image, *inode_block; +struct inode_info **inode_info; diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/globals.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/globals.h Sun Jan 26 08:11:42 2014 +0000 @@ -0,0 +1,14 @@ +/* + * extern declarations of global variables + */ + +extern char *imgfile; +extern u32 eraseblk_size; +extern int total_blocks; +extern u32 total_ffs_size; +extern int index_blk_num, root_inode; +extern int inode_limit; +extern int verbose; + +extern u8 *image, *inode_block; +extern struct inode_info **inode_info; diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/inode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/inode.c Sun Jan 26 08:11:42 2014 +0000 @@ -0,0 +1,161 @@ +/* + * This C module implements the reading and decoding of inode information. + */ + +#include +#include +#include +#include +#include +#include +#include "types.h" +#include "struct.h" +#include "globals.h" + +u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +alloc_inode_table() +{ + inode_info = malloc(sizeof(struct inode_info *) * inode_limit); + if (!inode_info) { + perror("malloc of inode table"); + exit(1); + } + bzero(inode_info, sizeof(struct inode_info *) * inode_limit); +} + +static int +convert_ptr(in, infp) + int in; + int *infp; +{ + if (in == 0xFFFF) { + *infp = 0; + return(0); + } + if (in < 1 || in >= inode_limit) + return(-1); + *infp = in; + return(1); +} + +validate_inode(ino) +{ + struct inode_flash *fl; + struct inode_info *inf; + + if (ino < 1 || ino >= inode_limit) + return(0); + if (inode_info[ino]) + return(1); + fl = (struct inode_flash *)inode_block + ino; + if (!bcmp(fl, blank_flash_line, sizeof blank_flash_line)) + return(0); + inf = malloc(sizeof(struct inode_info)); + if (!inf) { + perror("malloc of struct inode_info"); + exit(1); + } + bzero(inf, sizeof(struct inode_info)); + inf->len = le16toh(fl->len); + if (inf->len & 0xF) { + fprintf(stderr, + "warning: inode #%x: invalid length, skipping\n", ino); + free(inf); + return(0); + } + inf->type = fl->type; + switch (inf->type) { + case 0x00: + break; + case 0xE1: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + if (!inf->len) { + fprintf(stderr, + "warning: inode #%x: non-deleted object has zero length, skipping\n", + ino); + free(inf); + return(0); + } + break; + default: + fprintf(stderr, + "warning: inode #%x: unexpected object type %02X, skipping\n", + ino, inf->type); + free(inf); + return(0); + } + if (convert_ptr(le16toh(fl->descend), &inf->descend) < 0) { + fprintf(stderr, + "warning: inode #%x: invalid descend pointer, skipping\n", + ino); + free(inf); + return(0); + } + if (convert_ptr(le16toh(fl->sibling), &inf->sibling) < 0) { + fprintf(stderr, + "warning: inode #%x: invalid sibling pointer, skipping\n", + ino); + free(inf); + return(0); + } + if (inf->len) { + inf->rawloc = le32toh(fl->dataptr); + if (inf->rawloc > 0x0FFFFFFF) { +invdptr: fprintf(stderr, + "warning: inode #%x: invalid data pointer, skipping\n", + ino); + free(inf); + return(0); + } + inf->offset = inf->rawloc << 4; + if (inf->offset >= total_ffs_size) + goto invdptr; + if (inf->offset + inf->len > total_ffs_size) { + fprintf(stderr, +"warning: inode #%x: data pointer + length > FFS total size, skipping\n", + ino); + free(inf); + return(0); + } + inf->dataptr = image + inf->offset; + } + inode_info[ino] = inf; + return(1); +} + +find_root_inode() +{ + int ino; + + if (root_inode) { + if (!validate_inode(root_inode)) { + fprintf(stderr, + "error: root inode specified with -r is invalid\n"); + exit(1); + } + return(1); + } + for (ino = 1; ino < inode_limit; ino++) { + if (!validate_inode(ino)) + continue; + if (inode_info[ino]->type != 0xF2) + continue; + if (*inode_info[ino]->dataptr != '/') + continue; + root_inode = ino; + if (verbose) + fprintf(stderr, "Found root inode at #%x\n", ino); + if (inode_info[ino]->sibling) + fprintf(stderr, + "warning: root inode #%x has a non-null sibling pointer\n", + ino); + return(0); + } + fprintf(stderr, "error: no root inode found; try -r\n"); + exit(1); +} diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/main.c --- a/ffstools/tiffs-rd/main.c Sun Jan 26 00:34:22 2014 +0000 +++ b/ffstools/tiffs-rd/main.c Sun Jan 26 08:11:42 2014 +0000 @@ -10,13 +10,7 @@ #include #include #include "types.h" - -char *imgfile; -u32 eraseblk_size; -int total_blocks; -u32 total_ffs_size; -int index_blk_num = -1, root_node_no; -int verbose; +#include "globals.h" parse_org_arg(arg) char *arg; @@ -56,6 +50,7 @@ exit(1); } total_ffs_size = eraseblk_size * total_blocks; + inode_limit = eraseblk_size >> 4; } extern int cmd_blkhdr(); @@ -89,7 +84,7 @@ index_blk_num = atoi(optarg); continue; case 'r': - root_node_no = atoi(optarg); + root_inode = strtoul(optarg, 0, 16); continue; case 'v': verbose++; diff -r ffaa033e7643 -r 5ceacdbd4490 ffstools/tiffs-rd/struct.h --- a/ffstools/tiffs-rd/struct.h Sun Jan 26 00:34:22 2014 +0000 +++ b/ffstools/tiffs-rd/struct.h Sun Jan 26 08:11:42 2014 +0000 @@ -21,20 +21,19 @@ u16 repli; /* ??? */ }; -/* our own struct for convenience */ +/* our own distilled info struct */ struct inode_info { - struct inode_flash *flash; - int parent; + /* info from the inode record */ int type; - u8 *dataptr; - u32 offset; - u32 rawloc; - u16 len; int descend; int sibling; + u16 len; + u32 rawloc; + u32 offset; + u8 *dataptr; + /* filled by treewalk */ + int nparents; + int parent; + /* filled by misc */ u8 *byte_after_name; - /* info added from parsing the journal */ - struct journal_entry *jflash; - int j_unlink_ptr; - int j_oldver; };