changeset 30:9c3c5a572b57

mpffs-ls works with the length code stubbed out
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Jun 2013 06:28:58 +0000
parents e96d6862cec0
children 3cca8070ef0f
files .hgignore mpffs/Makefile mpffs/common.c mpffs/ls.c
diffstat 4 files changed, 233 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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$
--- /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}
--- 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();
+}
--- /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 <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 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);
+}