changeset 238:0b13839f782c

tiffs IVA: lsino (non-specific) implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 26 Jan 2014 23:32:42 +0000
parents 317936902be4
children 28ea957a9d8a
files ffstools/tiffs-rd/ls.c ffstools/tiffs-rd/main.c ffstools/tiffs-rd/tree.c
diffstat 3 files changed, 167 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ffstools/tiffs-rd/ls.c	Sun Jan 26 21:12:15 2014 +0000
+++ b/ffstools/tiffs-rd/ls.c	Sun Jan 26 23:32:42 2014 +0000
@@ -174,3 +174,99 @@
 		ls_by_pathname(argv[optind]);
 	exit(0);
 }
+
+lsino_all()
+{
+	int ino, last_ino = 0;
+	struct inode_info *inf;
+	char pathname[PATHNAME_BUF_SIZE], typech;
+	int pathstat;
+	char descend_str[8], sibling_str[8];
+
+	for (ino = 1; ino < inode_limit; ino++) {
+		if (!validate_inode(ino))
+			continue;
+		if (ino != last_ino + 1)
+			printf("GAP in inode numbers\n");
+		inf = inode_info[ino];
+		pathstat = pathname_of_inode(ino, pathname);
+		if (pathstat < 0)
+			strcpy(pathname, "-nopath-");
+		switch (inf->type) {
+		case 0x00:
+			typech = '~';
+			break;
+		case 0xE1:
+		case 0xF1:
+			typech = 'f';
+			break;
+		case 0xF2:
+			typech = 'd';
+			break;
+		case 0xF3:
+			typech = 'l';
+			break;
+		case 0xF4:
+			typech = '.';
+			break;
+		default:
+			typech = '?';
+		}
+		printf("#%04x %c %s\n", ino, typech, pathname);
+		if (inf->type && !(inf->type & 0x10))
+			printf("\tread-only object\n");
+		if (ino == root_inode)
+			printf("\tactive root\n");
+		else if (inf->nparents < 1)
+			printf("\torphan\n");
+		else if (inf->nparents > 1)
+			printf("\tparent: #%x (%d)\n", inf->parent,
+				inf->nparents);
+		else if (pathstat < 0 || verbose2)
+			printf("\tparent: #%x\n", inf->parent);
+		if (verbose2 > 1) {
+			if (inf->descend)
+				sprintf(descend_str, "#%x", inf->descend);
+			else
+				strcpy(descend_str, "null");
+			if (inf->sibling)
+				sprintf(sibling_str, "#%x", inf->sibling);
+			else
+				strcpy(sibling_str, "null");
+			printf("\tchild: %s, sibling: %s\n",
+				descend_str, sibling_str);
+		}
+		if (!inf->len)
+			printf("\treclaimed\n");
+		last_ino = ino;
+	}
+	exit(0);
+}
+
+cmd_lsino(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	int c;
+
+	read_ffs_image();
+	find_inode_block();
+	alloc_inode_table();
+	find_root_inode();
+	treewalk_all();
+
+	optind = 0;
+	while ((c = getopt(argc, argv, "v")) != EOF)
+		switch (c) {
+		case 'v':
+			verbose2++;
+			continue;
+		default:
+			fprintf(stderr, "usage: lsino [-v[v]] [ino...]\n");
+			exit(1);
+		}
+	if (optind >= argc)
+		return lsino_all();
+	fprintf(stderr, "lsino of specific inodes not implemented yet\n");
+	exit(1);
+}
--- a/ffstools/tiffs-rd/main.c	Sun Jan 26 21:12:15 2014 +0000
+++ b/ffstools/tiffs-rd/main.c	Sun Jan 26 23:32:42 2014 +0000
@@ -56,6 +56,7 @@
 extern int cmd_blkhdr();
 extern int cmd_fsinfo();
 extern int cmd_ls();
+extern int cmd_lsino();
 
 static struct cmdtab {
 	char *cmd;
@@ -66,6 +67,7 @@
 	{"fsck", NULL},
 	{"fsinfo", cmd_fsinfo},
 	{"ls", cmd_ls},
+	{"lsino", cmd_lsino},
 	{"xtr", NULL},
 	{NULL, NULL}
 };
--- a/ffstools/tiffs-rd/tree.c	Sun Jan 26 21:12:15 2014 +0000
+++ b/ffstools/tiffs-rd/tree.c	Sun Jan 26 23:32:42 2014 +0000
@@ -165,3 +165,72 @@
 	}
 	return(ino);
 }
+
+/*
+ * treewalk_all() walks the entire inode tree from the root down, without
+ * regard to object types, including deleted objects and even reclaimed ones.
+ * The output is the filling of the parent and nparents fields in the inode
+ * info array.
+ */
+
+static void
+treewalk_all_node(parent)
+{
+	int child;
+	struct inode_info *inf;
+
+	for (child = inode_info[parent]->descend; child; child = inf->sibling) {
+		if (!validate_inode(child)) {
+			fprintf(stderr,
+			"error: walk of complete tree hit invalid inode #%x\n",
+				child);
+			return;
+		}
+		inf = inode_info[child];
+		inf->parent = parent;
+		inf->nparents++;
+		if (inf->nparents >= inode_limit) {
+			fprintf(stderr,
+		"error: detected loop in inode tree at #%x, child of #%x\n",
+				child, parent);
+			return;
+		}
+		treewalk_all_node(child);
+	}
+}
+
+treewalk_all()
+{
+	treewalk_all_node(root_inode);
+}
+
+pathname_of_inode(ino, pnbuf)
+	char *pnbuf;
+{
+	int level;
+	char *revpath[MAX_DIR_NEST+1];
+	struct inode_info *inf;
+	char *op;
+
+	for (level = 0; ino != root_inode; ino = inf->parent) {
+		if (!validate_obj_name(ino, 0))
+			return(-1);
+		inf = inode_info[ino];
+		if (!inf->parent)
+			return(-1);
+		if (level > MAX_DIR_NEST)
+			return(-1);
+		revpath[level++] = (char *) inf->dataptr;
+	}
+	op = pnbuf;
+	if (!level)
+		*op++ = '/';
+	while (level) {
+		level--;
+		*op++ = '/';
+		strcpy(op, revpath[level]);
+		op = index(op, '\0');
+	}
+	*op = '\0';
+	return(0);
+}