# HG changeset patch # User Michael Spacefalcon # Date 1390736833 0 # Node ID 024042383a26b33ad7a15cbfbe94dae313f488c3 # Parent ae9ff2d1e3da1356822d1ebd9999d25574455c94 tiffs IVA: ls reports file sizes diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/globals.c --- a/ffstools/tiffs-rd/globals.c Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/globals.c Sun Jan 26 11:47:13 2014 +0000 @@ -2,6 +2,7 @@ * Definitions of global variables for the tiffs IVA program. */ +#include #include "types.h" #include "struct.h" diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/inode.c --- a/ffstools/tiffs-rd/inode.c Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/inode.c Sun Jan 26 11:47:13 2014 +0000 @@ -58,6 +58,7 @@ exit(1); } bzero(inf, sizeof(struct inode_info)); + inf->ino = ino; inf->len = le16toh(fl->len); if (inf->len & 0xF) { fprintf(stderr, diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/ls.c --- a/ffstools/tiffs-rd/ls.c Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/ls.c Sun Jan 26 11:47:13 2014 +0000 @@ -2,6 +2,7 @@ * This C module implements the ls command. */ +#include #include #include #include @@ -11,31 +12,56 @@ #include "globals.h" #include "pathname.h" +static void +segment_size_callback(inf, opaque) + struct inode_info *inf; + u_long opaque; +{ + size_t *accump = (size_t *) opaque; + struct chunkinfo chi; + + size_extra_chunk(inf, &chi); + *accump += chi.len; +} + +size_t +get_file_size(seghead_ino, deleted) +{ + struct chunkinfo chi; + size_t accum; + + size_head_chunk(inode_info[seghead_ino], &chi); + accum = chi.len; + iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum, + deleted); + return(accum); +} + void ls_callback(pathname, ino, depth) char *pathname; { struct inode_info *inf = inode_info[ino]; - char type; + u_long size; switch (inf->type) { case 0xE1: case 0xF1: - type = 'f'; - break; + size = get_file_size(ino, 0); + printf("f %7lu %s\n", size, pathname); + return; case 0xF2: - type = 'd'; - break; + printf("d %s\n", pathname); + return; case 0xF3: - type = 'l'; - break; + printf("l %s\n", pathname); + return; default: fprintf(stderr, "BUG: bad inode byte %02X reached ls_callback()\n", inf->type); exit(1); } - printf("%c %s\n", type, pathname); } cmd_ls() diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/object.c --- a/ffstools/tiffs-rd/object.c Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/object.c Sun Jan 26 11:47:13 2014 +0000 @@ -2,6 +2,7 @@ * This C module implements object-level analysis. */ +#include #include #include #include @@ -56,3 +57,94 @@ inf->byte_after_name = p + 1; return(1); } + +u8 * +find_end_of_chunk(inf) + struct inode_info *inf; +{ + u8 *p; + int i; + + p = inf->dataptr + inf->len; + for (i = 1; i <= 16; i++) { + if (!p[-i]) + return(p - i); + if (p[-i] != 0xFF) + break; + } + fprintf(stderr, + "error: chunk @%x (inode #%x): no valid termination found\n", + inf->offset, inf->ino); + return(p); /* bogon, allows the rest to continue */ +} + +size_head_chunk(inf, chi) + struct inode_info *inf; + struct chunkinfo *chi; +{ + chi->start = inf->byte_after_name; + chi->end = find_end_of_chunk(inf); + if (chi->start >= chi->end) { + chi->len = 0; + return(0); + } else { + chi->len = chi->end - chi->start; + return(1); + } +} + +size_extra_chunk(inf, chi) + struct inode_info *inf; + struct chunkinfo *chi; +{ + chi->start = inf->dataptr; + chi->end = find_end_of_chunk(inf); + chi->len = chi->end - chi->start; +} + +void +iterate_seg_file(seghead, callback, callback_data, deleted) + void (*callback)(); + u_long callback_data; +{ + int ino; + struct inode_info *inf; + + for (ino = inode_info[seghead]->descend; ino; ino = inf->descend) { +loop: if (!validate_inode(ino)) { + fprintf(stderr, + "error: following seg file hit invalid inode #%x\n", + ino); + return; + } + inf = inode_info[ino]; + switch (inf->type) { + case 0xF4: + callback(inf, callback_data); + continue; + case 0x00: + if (deleted) { + if (inf->len) + callback(inf, callback_data); + else + fprintf(stderr, + "error: presumed deleted segment inode #%x has been reclaimed\n", + ino); + continue; + } + if (!inf->sibling) { + fprintf(stderr, + "error: segment object at inode #%x: marked deleted, but no sibling\n", + ino); + return; + } + ino = inf->sibling; + goto loop; + default: + fprintf(stderr, + "error: inode #%x: unexpected type %02X when expecting segment (F4)\n", + ino, inf->type); + return; + } + } +} diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/struct.h --- a/ffstools/tiffs-rd/struct.h Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/struct.h Sun Jan 26 11:47:13 2014 +0000 @@ -23,6 +23,7 @@ /* our own distilled info struct */ struct inode_info { + int ino; /* info from the inode record */ int type; int descend; @@ -37,3 +38,10 @@ /* filled by misc */ u8 *byte_after_name; }; + +/* chunk location and size info */ +struct chunkinfo { + u8 *start; + u8 *end; + size_t len; +}; diff -r ae9ff2d1e3da -r 024042383a26 ffstools/tiffs-rd/tree.c --- a/ffstools/tiffs-rd/tree.c Sun Jan 26 10:54:42 2014 +0000 +++ b/ffstools/tiffs-rd/tree.c Sun Jan 26 11:47:13 2014 +0000 @@ -2,6 +2,7 @@ * This C module implements operations on the tree level. */ +#include #include #include #include