changeset 231:5ceacdbd4490

tiffs IVA: finds the root inode
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 26 Jan 2014 08:11:42 +0000
parents ffaa033e7643
children 73372cfdaf7f
files ffstools/tiffs-rd/Makefile ffstools/tiffs-rd/basics.c ffstools/tiffs-rd/globals.c ffstools/tiffs-rd/globals.h ffstools/tiffs-rd/inode.c ffstools/tiffs-rd/main.c ffstools/tiffs-rd/struct.h
diffstat 7 files changed, 214 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/ffstools/tiffs-rd/Makefile	Sun Jan 26 00:34:22 2014 +0000
+++ b/ffstools/tiffs-rd/Makefile	Sun Jan 26 08:11:42 2014 +0000
@@ -1,12 +1,15 @@
 CC=	gcc
 CFLAGS=	-O2
 PROG=	tiffs
-OBJS=	basics.o main.o
+OBJS=	basics.o globals.o inode.o main.o
+HDRS=	globals.h pathname.h struct.h types.h
 
 all:	${PROG}
 
 ${PROG}: ${OBJS}
 	${CC} -o $@ ${OBJS}
 
+${OBJS}: ${HDRS}
+
 clean:
 	rm -f ${PROG} *.o *.out *errs
--- a/ffstools/tiffs-rd/basics.c	Sun Jan 26 00:34:22 2014 +0000
+++ b/ffstools/tiffs-rd/basics.c	Sun Jan 26 08:11:42 2014 +0000
@@ -12,19 +12,9 @@
 #include <string.h>
 #include <strings.h>
 #include "types.h"
+#include "globals.h"
 
 u8 tiffs_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};
-
-extern char *imgfile;
-extern u32 eraseblk_size;
-extern int total_blocks;
-extern u32 total_ffs_size;
-extern int index_blk_num, root_node_no;
-extern int verbose;
-
-u8 *image, *inode_block;
 
 read_ffs_image()
 {
@@ -109,7 +99,7 @@
 		switch (ptr[8]) {
 		case 0xAB:
 			if (verbose)
-				printf(
+				fprintf(stderr,
 			"Found AB index in erase block #%d (offset %x)\n",
 					i, ptr - image);
 			index_blk_num = i;
@@ -143,5 +133,8 @@
 	read_ffs_image();
 	find_inode_block();
 	printf("Active inode block (AB) is block #%d\n", index_blk_num);
+	alloc_inode_table();
+	find_root_inode();
+	printf("Root inode is #%x\n", root_inode);
 	exit(0);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ffstools/tiffs-rd/globals.c	Sun Jan 26 08:11:42 2014 +0000
@@ -0,0 +1,17 @@
+/*
+ * Definitions of global variables for the tiffs IVA program.
+ */
+
+#include "types.h"
+#include "struct.h"
+
+char *imgfile;
+u32 eraseblk_size;
+int total_blocks;
+u32 total_ffs_size;
+int index_blk_num = -1, root_inode;
+int inode_limit;
+int verbose;
+
+u8 *image, *inode_block;
+struct inode_info **inode_info;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ffstools/tiffs-rd/globals.h	Sun Jan 26 08:11:42 2014 +0000
@@ -0,0 +1,14 @@
+/*
+ * extern declarations of global variables
+ */
+
+extern char *imgfile;
+extern u32 eraseblk_size;
+extern int total_blocks;
+extern u32 total_ffs_size;
+extern int index_blk_num, root_inode;
+extern int inode_limit;
+extern int verbose;
+
+extern u8 *image, *inode_block;
+extern struct inode_info **inode_info;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ffstools/tiffs-rd/inode.c	Sun Jan 26 08:11:42 2014 +0000
@@ -0,0 +1,161 @@
+/*
+ * This C module implements the reading and decoding of inode information.
+ */
+
+#include <sys/types.h>
+#include <endian.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "types.h"
+#include "struct.h"
+#include "globals.h"
+
+u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+			   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+alloc_inode_table()
+{
+	inode_info = malloc(sizeof(struct inode_info *) * inode_limit);
+	if (!inode_info) {
+		perror("malloc of inode table");
+		exit(1);
+	}
+	bzero(inode_info, sizeof(struct inode_info *) * inode_limit);
+}
+
+static int
+convert_ptr(in, infp)
+	int in;
+	int *infp;
+{
+	if (in == 0xFFFF) {
+		*infp = 0;
+		return(0);
+	}
+	if (in < 1 || in >= inode_limit)
+		return(-1);
+	*infp = in;
+	return(1);
+}
+
+validate_inode(ino)
+{
+	struct inode_flash *fl;
+	struct inode_info *inf;
+
+	if (ino < 1 || ino >= inode_limit)
+		return(0);
+	if (inode_info[ino])
+		return(1);
+	fl = (struct inode_flash *)inode_block + ino;
+	if (!bcmp(fl, blank_flash_line, sizeof blank_flash_line))
+		return(0);
+	inf = malloc(sizeof(struct inode_info));
+	if (!inf) {
+		perror("malloc of struct inode_info");
+		exit(1);
+	}
+	bzero(inf, sizeof(struct inode_info));
+	inf->len = le16toh(fl->len);
+	if (inf->len & 0xF) {
+		fprintf(stderr,
+			"warning: inode #%x: invalid length, skipping\n", ino);
+		free(inf);
+		return(0);
+	}
+	inf->type = fl->type;
+	switch (inf->type) {
+	case 0x00:
+		break;
+	case 0xE1:
+	case 0xF1:
+	case 0xF2:
+	case 0xF3:
+	case 0xF4:
+		if (!inf->len) {
+			fprintf(stderr,
+	"warning: inode #%x: non-deleted object has zero length, skipping\n",
+				ino);
+			free(inf);
+			return(0);
+		}
+		break;
+	default:
+		fprintf(stderr,
+		"warning: inode #%x: unexpected object type %02X, skipping\n",
+			ino, inf->type);
+		free(inf);
+		return(0);
+	}
+	if (convert_ptr(le16toh(fl->descend), &inf->descend) < 0) {
+		fprintf(stderr,
+		"warning: inode #%x: invalid descend pointer, skipping\n",
+			ino);
+		free(inf);
+		return(0);
+	}
+	if (convert_ptr(le16toh(fl->sibling), &inf->sibling) < 0) {
+		fprintf(stderr,
+		"warning: inode #%x: invalid sibling pointer, skipping\n",
+			ino);
+		free(inf);
+		return(0);
+	}
+	if (inf->len) {
+		inf->rawloc = le32toh(fl->dataptr);
+		if (inf->rawloc > 0x0FFFFFFF) {
+invdptr:		fprintf(stderr,
+			"warning: inode #%x: invalid data pointer, skipping\n",
+				ino);
+			free(inf);
+			return(0);
+		}
+		inf->offset = inf->rawloc << 4;
+		if (inf->offset >= total_ffs_size)
+			goto invdptr;
+		if (inf->offset + inf->len > total_ffs_size) {
+			fprintf(stderr,
+"warning: inode #%x: data pointer + length > FFS total size, skipping\n",
+				ino);
+			free(inf);
+			return(0);
+		}
+		inf->dataptr = image + inf->offset;
+	}
+	inode_info[ino] = inf;
+	return(1);
+}
+
+find_root_inode()
+{
+	int ino;
+
+	if (root_inode) {
+		if (!validate_inode(root_inode)) {
+			fprintf(stderr,
+			"error: root inode specified with -r is invalid\n");
+			exit(1);
+		}
+		return(1);
+	}
+	for (ino = 1; ino < inode_limit; ino++) {
+		if (!validate_inode(ino))
+			continue;
+		if (inode_info[ino]->type != 0xF2)
+			continue;
+		if (*inode_info[ino]->dataptr != '/')
+			continue;
+		root_inode = ino;
+		if (verbose)
+			fprintf(stderr, "Found root inode at #%x\n", ino);
+		if (inode_info[ino]->sibling)
+			fprintf(stderr,
+		"warning: root inode #%x has a non-null sibling pointer\n",
+				ino);
+		return(0);
+	}
+	fprintf(stderr, "error: no root inode found; try -r\n");
+	exit(1);
+}
--- a/ffstools/tiffs-rd/main.c	Sun Jan 26 00:34:22 2014 +0000
+++ b/ffstools/tiffs-rd/main.c	Sun Jan 26 08:11:42 2014 +0000
@@ -10,13 +10,7 @@
 #include <string.h>
 #include <strings.h>
 #include "types.h"
-
-char *imgfile;
-u32 eraseblk_size;
-int total_blocks;
-u32 total_ffs_size;
-int index_blk_num = -1, root_node_no;
-int verbose;
+#include "globals.h"
 
 parse_org_arg(arg)
 	char *arg;
@@ -56,6 +50,7 @@
 		exit(1);
 	}
 	total_ffs_size = eraseblk_size * total_blocks;
+	inode_limit = eraseblk_size >> 4;
 }
 
 extern int cmd_blkhdr();
@@ -89,7 +84,7 @@
 			index_blk_num = atoi(optarg);
 			continue;
 		case 'r':
-			root_node_no = atoi(optarg);
+			root_inode = strtoul(optarg, 0, 16);
 			continue;
 		case 'v':
 			verbose++;
--- a/ffstools/tiffs-rd/struct.h	Sun Jan 26 00:34:22 2014 +0000
+++ b/ffstools/tiffs-rd/struct.h	Sun Jan 26 08:11:42 2014 +0000
@@ -21,20 +21,19 @@
 	u16	repli;	/* ??? */
 };
 
-/* our own struct for convenience */
+/* our own distilled info struct */
 struct inode_info {
-	struct	inode_flash *flash;
-	int	parent;
+	/* info from the inode record */
 	int	type;
-	u8	*dataptr;
-	u32	offset;
-	u32	rawloc;
-	u16	len;
 	int	descend;
 	int	sibling;
+	u16	len;
+	u32	rawloc;
+	u32	offset;
+	u8	*dataptr;
+	/* filled by treewalk */
+	int	nparents;
+	int	parent;
+	/* filled by misc */
 	u8	*byte_after_name;
-	/* info added from parsing the journal */
-	struct	journal_entry *jflash;
-	int	j_unlink_ptr;
-	int	j_oldver;
 };