# HG changeset patch # User Michael Spacefalcon # Date 1372573738 0 # Node ID 9c3c5a572b57eb08cc95e1b550acdb1c01d89462 # Parent e96d6862cec0ab3a6ab147d0556651be4b38f384 mpffs-ls works with the length code stubbed out diff -r e96d6862cec0 -r 9c3c5a572b57 .hgignore --- a/.hgignore Sun Jun 30 05:16:23 2013 +0000 +++ b/.hgignore Sun Jun 30 06:28:58 2013 +0000 @@ -1,4 +1,11 @@ -re:^mokosrec2bin$ -re:^mysteryffs/dump[12]$ -re:^mysteryffs/extract$ -re:^mysteryffs/scan1$ +syntax: regexp + +\.[oa]$ + +^mokosrec2bin$ + +^mpffs/mpffs-ls$ + +^mysteryffs/dump[12]$ +^mysteryffs/extract$ +^mysteryffs/scan1$ diff -r e96d6862cec0 -r 9c3c5a572b57 mpffs/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpffs/Makefile Sun Jun 30 06:28:58 2013 +0000 @@ -0,0 +1,19 @@ +CC= gcc +CFLAGS= -O2 +PROGS= mpffs-ls +INSTDIR=/usr/local/bin + +CAT_OBJS= common.o cat.o +LS_OBJS= common.o ls.o +XTR_OBJS= common.o xtr.o + +all: ${PROGS} + +mpffs-ls: ${LS_OBJS} + ${CC} -o $@ ${LS_OBJS} + +install: + install -c ${PROGS} ${INSTDIR} + +clean: + rm -f *.o *.out *errs ${PROGS} diff -r e96d6862cec0 -r 9c3c5a572b57 mpffs/common.c --- a/mpffs/common.c Sun Jun 30 05:16:23 2013 +0000 +++ b/mpffs/common.c Sun Jun 30 06:28:58 2013 +0000 @@ -17,13 +17,16 @@ #include "struct.h" u8 mpffs_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}; char *imgfile; u32 eraseblk_size; int total_blocks; u32 total_ffs_size; u8 *image, *indexblk; -int index_blk_num, root_node_no; +int index_blk_num = -1, root_node_no; +struct objinfo root; int verbose; /* @@ -42,13 +45,58 @@ eraseblk_size_reasonable() { - if (count_ones(eraseblk_size) != 1 || eraseblk_size < 16384) { + if (count_ones(eraseblk_size) != 1 || eraseblk_size < 16384 || + eraseblk_size > 0x100000) { fprintf(stderr, "0x%lx is an unreasonable erase block size\n", (u_long) eraseblk_size); exit(1); } } +parse_cmdline_options(argc, argv) + char **argv; +{ + extern char *optarg; + int c; + + while ((c = getopt(argc, argv, "a:e:mn:pr:v")) != EOF) + switch (c) { + case 'a': + index_blk_num = atoi(optarg); + continue; + case 'e': + eraseblk_size = strtoul(optarg, 0, 0); + eraseblk_size_reasonable(); + continue; + case 'm': /* "moko" */ + eraseblk_size = 0x10000; + total_blocks = 7; + continue; + case 'n': + total_blocks = atoi(optarg); + if (total_blocks < 1) { + fprintf(stderr, "invalid -n value\n"); + exit(1); + } + continue; + case 'p': /* Pirelli */ + eraseblk_size = 0x40000; + total_blocks = 18; + continue; + case 'r': + root_node_no = atoi(optarg); + continue; + case 'v': + verbose++; + continue; + default: + usage(); + exit(1); + } + + return(0); +} + read_img_file() { int fd; @@ -114,8 +162,8 @@ int i, abcnt; u8 *ptr; - if (index_blk_num) { - if (index_blk_num < 0 || index_blk_num >= total_blocks) { + if (index_blk_num >= 0) { + if (index_blk_num >= total_blocks) { fprintf(stderr, "invalid block # given with the -a option\n"); exit(1); @@ -205,7 +253,7 @@ exit(1); } dptr <<= 4; - if (dptr >= total_img_size - oi->len) + if (dptr > total_ffs_size - oi->len) goto invdptr; oi->offset = dptr; oi->dataptr = image + dptr; @@ -262,3 +310,64 @@ ch->offset, ch->entryno); exit(1); } + +find_root_node() +{ + struct objinfo obj; + u16 lim; + + lim = (eraseblk_size >> 4) - 1; + if (root_node_no) { + if (root_node_no < 1 || root_node_no > lim) { + fprintf(stderr, + "root node # given with -r is invalid\n"); + exit(1); + } + return(1); + } + for (obj.entryno = 1; obj.entryno <= lim; obj.entryno++) { + get_index_entry(&obj); + if (!bcmp(obj.idxrec, blank_flash_line, 16)) + break; + if (obj.type != 0xF2) + continue; + validate_chunk(&obj); + validate_obj_name(&obj); + if (*obj.dataptr != '/') + continue; + root_node_no = obj.entryno; + if (verbose) + printf("Found root node at index #%x\n", root_node_no); + return(0); + } + fprintf(stderr, "error: no root node found (try -r)\n"); + exit(1); +} + +validate_root_node() +{ + root.entryno = root_node_no; + get_index_entry(&root); + validate_chunk(&root); + validate_obj_name(&root); + if (verbose) + printf("Root node name: %s\n", (char *)root.dataptr); + if (root.type != 0xF2) { + fprintf(stderr, + "error: index entry #%x (expected root dir) is not a directory\n", + root_node_no); + exit(1); + } + if (root.sibling != 0xFFFF) + fprintf(stderr, + "warning: root entry has a non-nil sibling pointer\n"); + return(0); +} + +preliminaries() +{ + read_img_file(); + find_index_block(); + find_root_node(); + validate_root_node(); +} diff -r e96d6862cec0 -r 9c3c5a572b57 mpffs/ls.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpffs/ls.c Sun Jun 30 06:28:58 2013 +0000 @@ -0,0 +1,89 @@ +/* + * This module contains the main function and other code specific to mpffs-ls + */ + +#include +#include +#include +#include +#include +#include +#include +#include "types.h" +#include "struct.h" + +extern char *imgfile; +extern struct objinfo root; +extern int verbose; + +char workpath[512]; + +u_long +get_file_size(head) + struct objinfo *head; +{ + return(0); /* stub, remains to be implemented */ +} + +dump_dir(firstent, path_prefix) +{ + int ent; + struct objinfo obj; + u_long size; + + for (ent = firstent; ent != 0xFFFF; ent = obj.sibling) { + obj.entryno = ent; + get_index_entry(&obj); + if (!obj.type) /* skip deleted objects w/o further validation */ + continue; + validate_chunk(&obj); + validate_obj_name(&obj); + if (path_prefix + strlen(obj.dataptr) + 2 > sizeof workpath) { + fprintf(stderr, + "handling object at index %x, name \"%s\": path buffer overflow\n", + obj.entryno, (char *)obj.dataptr); + exit(1); + } + sprintf(workpath + path_prefix, "/%s", (char *)obj.dataptr); + switch (obj.type) { + case 0xF2: + /* directory */ + printf("d %s\n", workpath); + dump_dir(obj.descend, strlen(workpath)); + continue; + case 0xF1: + /* regular file */ + size = get_file_size(&obj); + printf("- %7lu %s\n", size, workpath); + continue; + case 0xE1: + /* special .journal file */ + printf("j %s\n", workpath); + continue; + default: + printf("%s (index entry #%x): unexpected type %02X; skipping\n", + workpath, obj.entryno, obj.type); + continue; + } + } +} + +usage() +{ + fprintf(stderr, "usage: mpffs-ls [options] ffs-image\n"); + exit(1); +} + +main(argc, argv) + char **argv; +{ + extern int optind; + + parse_cmdline_options(argc, argv); + if (argc - optind != 1) + usage(); + imgfile = argv[optind]; + preliminaries(); + dump_dir(root.descend, 0); + exit(0); +}