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);
+}