FreeCalypso > hg > freecalypso-reveng
changeset 33:660b0ea739f3
mpffs-dbgls implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 30 Jun 2013 07:47:49 +0000 |
parents | 0bf037ba4149 |
children | 95f61c3b430a |
files | .hgignore mpffs/Makefile mpffs/dbgls.c |
diffstat | 3 files changed, 147 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Sun Jun 30 07:16:01 2013 +0000 +++ b/.hgignore Sun Jun 30 07:47:49 2013 +0000 @@ -4,6 +4,7 @@ ^mokosrec2bin$ +^mpffs/mpffs-dbgls$ ^mpffs/mpffs-ls$ ^mysteryffs/dump[12]$
--- a/mpffs/Makefile Sun Jun 30 07:16:01 2013 +0000 +++ b/mpffs/Makefile Sun Jun 30 07:47:49 2013 +0000 @@ -1,14 +1,18 @@ CC= gcc CFLAGS= -O2 -PROGS= mpffs-ls +PROGS= mpffs-dbgls mpffs-ls INSTDIR=/usr/local/bin CAT_OBJS= common.o cat.o +DBGLS_OBJS= common.o dbgls.o LS_OBJS= common.o ls.o XTR_OBJS= common.o xtr.o all: ${PROGS} +mpffs-dbgls: ${DBGLS_OBJS} + ${CC} -o $@ ${DBGLS_OBJS} + mpffs-ls: ${LS_OBJS} ${CC} -o $@ ${LS_OBJS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpffs/dbgls.c Sun Jun 30 07:47:49 2013 +0000 @@ -0,0 +1,141 @@ +/* + * Whereas mpffs-ls is more user-oriented, mpffs-dbgls is structured a little + * different in order to provide a more low-level view of the FFS structure. + */ + +#include <sys/types.h> +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include <unistd.h> +#include "types.h" +#include "struct.h" + +extern char *imgfile; +extern u8 *image; +extern struct objinfo root; +extern int verbose; + +char workpath[512]; + +void +dump_extra_chunks(first_extra_chunk) +{ + int ent; + struct objinfo ch; + struct chunkinfo chi; + + for (ent = first_extra_chunk; ent != 0xFFFF; ent = ch.descend) { + ch.entryno = ent; + get_index_entry(&ch); + if (ch.type != 0xF4) { + fprintf(stderr, + "file continuation object at index %x: type %02X != expected F4\n", + ent, ch.type); + return; + } + validate_chunk(&ch); + printf(" #%x chunk addr=0x%x len=0x%x\n", ch.entryno, + ch.offset, ch.len); + size_extra_chunk(&ch, &chi); + printf(" extra chunk: %lu bytes at 0x%lx\n", (u_long) chi.len, + (u_long)(chi.start-image)); + if (ch.sibling != 0xFFFF) + fprintf(stderr, +"warning: file continuation object (index %x) has a non-nil sibling pointer\n", + ent); + } +} + +void +dump_object(obj) + struct objinfo *obj; +{ + int typechar; + struct chunkinfo chi; + + switch (obj->type) { + case 0xF2: + /* directory */ + typechar = 'd'; + break; + case 0xF1: + /* regular file */ + typechar = '-'; + break; + case 0xE1: + /* special .journal file */ + typechar = 'j'; + break; + default: + /* unknown! */ + typechar = 'U'; + } + printf("%c %s\n", typechar, workpath); + printf(" #%x chunk addr=0x%x len=0x%x\n", obj->entryno, + obj->offset, obj->len); + switch (obj->type) { + case 0xF2: + /* directory */ + return; + case 0xF1: + /* regular file */ + size_head_chunk(obj, &chi); + printf(" head chunk: %lu bytes at 0x%lx\n", (u_long) chi.len, + (u_long)(chi.start-image)); + dump_extra_chunks(obj->descend); + return; + default: + if (obj->descend != 0xFFFF) + printf(" unexpected descend pointer: %x\n", + obj->descend); + } +} + +dump_dir(firstent, path_prefix) +{ + int ent; + struct objinfo obj; + + 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); + dump_object(&obj); + if (obj.type == 0xF2) + dump_dir(obj.descend, strlen(workpath)); + } +} + +usage() +{ + fprintf(stderr, "usage: mpffs-dbgls [options] ffs-image\n"); + exit(1); +} + +main(argc, argv) + char **argv; +{ + extern int optind; + + parse_cmdline_options(argc, argv); + if (argc - optind != 1) + usage(); + verbose++; + imgfile = argv[optind]; + preliminaries(); + dump_dir(root.descend, 0); + exit(0); +}