changeset 237:317936902be4

tiffs IVA: regular ls fully implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 26 Jan 2014 21:12:15 +0000
parents 254de9560ef3
children 0b13839f782c
files ffstools/tiffs-rd/ls.c ffstools/tiffs-rd/object.c ffstools/tiffs-rd/tree.c
diffstat 3 files changed, 178 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ffstools/tiffs-rd/ls.c	Sun Jan 26 19:03:33 2014 +0000
+++ b/ffstools/tiffs-rd/ls.c	Sun Jan 26 21:12:15 2014 +0000
@@ -33,7 +33,7 @@
 	size_head_chunk(inode_info[seghead_ino], &chi);
 	accum = chi.len;
 	iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum,
-			 deleted);
+			 deleted, 0);
 	return(accum);
 }
 
@@ -45,7 +45,11 @@
 	struct chunkinfo chi;
 
 	size_extra_chunk(inf, &chi);
-	printf("seg #%04x length=%lu\n", inf->ino, (u_long) chi.len);
+	if (verbose2 > 1)
+		printf("seg #%04x @%08x length=%lu\n", inf->ino, inf->offset,
+			(u_long) chi.len);
+	else
+		printf("seg #%04x length=%lu\n", inf->ino, (u_long) chi.len);
 }
 
 ls_seg_file(seghead_ino, deleted)
@@ -54,12 +58,17 @@
 	struct chunkinfo chi;
 
 	size_head_chunk(inf, &chi);
-	printf("%lu bytes in seghead\n", (u_long) chi.len);
-	iterate_seg_file(seghead_ino, segment_ls_callback, 0L, deleted);
+	printf("%lu bytes in seghead", (u_long) chi.len);
+	if (verbose2 > 1)
+		printf(", starting at offset %lx",
+			(u_long)(inf->byte_after_name - image));
+	putchar('\n');
+	iterate_seg_file(seghead_ino, segment_ls_callback, 0L, deleted,
+			 verbose2 > 1);
 }
 
 void
-ls_callback(pathname, ino, depth)
+ls_tree_callback(pathname, ino, depth)
 	char *pathname;
 {
 	struct inode_info *inf = inode_info[ino];
@@ -94,28 +103,74 @@
 	}
 }
 
-ls_visible_tree()
+ls_by_pathname(pathname)
+	char *pathname;
 {
-	read_ffs_image();
-	find_inode_block();
-	alloc_inode_table();
-	find_root_inode();
-	traverse_visible_tree(ls_callback);
-	exit(0);
+	int ino;
+	struct inode_info *inf;
+	char *type;
+
+	printf("%s\n", pathname);
+	ino = find_pathname(pathname);
+	printf("inode #%x\n", ino);
+	inf = inode_info[ino];
+	switch (inf->type) {
+	case 0xE1:
+		type = "read-only file";
+		break;
+	case 0xF1:
+		type = "file";
+		break;
+	case 0xF2:
+		type = "directory";
+		break;
+	case 0xF3:
+		type = "symlink";
+		break;
+	default:
+		type = "???";
+	}
+	printf("object type %02X (%s)\n", inf->type, type);
+	if (!validate_obj_name(ino, ino == root_inode)) {
+		printf("No valid object name in the chunk!\n");
+		exit(1);
+	}
+	printf("object name: %s\n", inf->dataptr);
+	if (inf->type == 0xF1 || inf->type == 0xE1) {
+		printf("total size: %lu bytes\n",
+			(u_long) get_file_size(ino, 0));
+		if (verbose2)
+			ls_seg_file(ino, 0);
+	}
+	putchar('\n');
 }
 
 cmd_ls(argc, argv)
 	char **argv;
 {
-	char **ap;
+	extern int optind;
+	int c;
+
+	read_ffs_image();
+	find_inode_block();
+	alloc_inode_table();
+	find_root_inode();
 
-	ap = argv + 1;
-	if (*ap && !strcmp(*ap, "-v")) {
-		verbose2++;
-		ap++;
+	optind = 0;
+	while ((c = getopt(argc, argv, "v")) != EOF)
+		switch (c) {
+		case 'v':
+			verbose2++;
+			continue;
+		default:
+			fprintf(stderr, "usage: ls [-v[v]] [pathname...]\n");
+			exit(1);
+		}
+	if (optind >= argc) {
+		traverse_visible_tree(ls_tree_callback);
+		exit(0);
 	}
-	if (!*ap)
-		return ls_visible_tree();
-	fprintf(stderr, "ls of individual files not yet implemented\n");
-	exit(1);
+	for (; optind < argc; optind++)
+		ls_by_pathname(argv[optind]);
+	exit(0);
 }
--- a/ffstools/tiffs-rd/object.c	Sun Jan 26 19:03:33 2014 +0000
+++ b/ffstools/tiffs-rd/object.c	Sun Jan 26 21:12:15 2014 +0000
@@ -103,7 +103,7 @@
 }
 
 void
-iterate_seg_file(seghead, callback, callback_data, deleted)
+iterate_seg_file(seghead, callback, callback_data, deleted, verbose)
 	void (*callback)();
 	u_long callback_data;
 {
@@ -138,6 +138,9 @@
 					ino);
 				return;
 			}
+			if (verbose)
+				printf("seg inode #%x deleted, moved to #%x\n",
+					ino, inf->sibling);
 			ino = inf->sibling;
 			goto loop;
 		default:
--- a/ffstools/tiffs-rd/tree.c	Sun Jan 26 19:03:33 2014 +0000
+++ b/ffstools/tiffs-rd/tree.c	Sun Jan 26 21:12:15 2014 +0000
@@ -67,3 +67,101 @@
 
 	visible_walk_dir(pathbuf, pathbuf, root_inode, 0, callback);
 }
+
+/*
+ * The following function iterates through the descendants of a directory
+ * object looking for a specific directory-member filename.
+ *
+ * Arguments:
+ * - inode # of the parent directory
+ * - inode # of the first descendant (descendant pointer from the dir object)
+ * - filename to search for
+ *
+ * Returns: inode # of the sought descendant object if found, 0 otherwise.
+ */
+find_dir_member(dirino, first_descend, srchname)
+	char *srchname;
+{
+	int ino;
+	struct inode_info *inf;
+
+	for (ino = first_descend; ino; ino = inf->sibling) {
+		if (!validate_inode(ino)) {
+			fprintf(stderr,
+			"error: pathname search hit invalid inode #%x\n",
+				ino);
+			exit(1);
+		}
+		inf = inode_info[ino];
+		switch (inf->type) {
+		case 0x00:
+			/* walking the *visible* tree: skip deleted objects */
+			continue;
+		case 0xF4:
+			fprintf(stderr,
+	"warning: directory #%x has child #%x of type segment (F4), skipping\n",
+				dirino, ino);
+			continue;
+		}
+		if (!validate_obj_name(ino, 0)) {
+			fprintf(stderr,
+		"visible tree walk error: no valid name for inode #%x\n",
+				ino);
+			continue;
+		}
+		if (!strcmp(inf->dataptr, srchname))
+			return(ino);
+	}
+	return(0);
+}
+
+/*
+ * The following function searches for a pathname from the root down.
+ * Returns the inode # if found, otherwise exits with an error message
+ * indicating which step failed.
+ *
+ * Warning: the pathname in the argument buffer will be destroyed:
+ * 0s put in place of the slashes.
+ */
+find_pathname(pathname)
+	char *pathname;
+{
+	char *cur, *next;
+	int ino;
+	struct inode_info *inf;
+
+	cur = pathname;
+	if (*cur == '/')
+		cur++;
+	else {
+		fprintf(stderr,
+		"bad pathname \"%s\": TIFFS pathnames must be absolute\n",
+			pathname);
+		exit(1);
+	}
+	for (ino = root_inode; cur; cur = next) {
+		if (!*cur)
+			break;
+		next = index(cur, '/');
+		if (next == cur) {
+			fprintf(stderr,
+			"malformed pathname: multiple adjacent slashes\n");
+			exit(1);
+		}
+		if (next)
+			*next++ = '\0';
+		inf = inode_info[ino];
+		if (inf->type != 0xF2) {
+			fprintf(stderr,
+			"pathname search error: encountered a non-directory\n");
+			exit(1);
+		}
+		ino = find_dir_member(ino, inf->descend, cur);
+		if (!ino) {
+			fprintf(stderr,
+			"pathname search error: component name not found\n");
+			exit(1);
+		}
+	}
+	return(ino);
+}