changeset 234:024042383a26

tiffs IVA: ls reports file sizes
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 26 Jan 2014 11:47:13 +0000
parents ae9ff2d1e3da
children e17bb8818318
files ffstools/tiffs-rd/globals.c ffstools/tiffs-rd/inode.c ffstools/tiffs-rd/ls.c ffstools/tiffs-rd/object.c ffstools/tiffs-rd/struct.h ffstools/tiffs-rd/tree.c
diffstat 6 files changed, 137 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ffstools/tiffs-rd/globals.c	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/globals.c	Sun Jan 26 11:47:13 2014 +0000
@@ -2,6 +2,7 @@
  * Definitions of global variables for the tiffs IVA program.
  */
 
+#include <sys/types.h>
 #include "types.h"
 #include "struct.h"
 
--- a/ffstools/tiffs-rd/inode.c	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/inode.c	Sun Jan 26 11:47:13 2014 +0000
@@ -58,6 +58,7 @@
 		exit(1);
 	}
 	bzero(inf, sizeof(struct inode_info));
+	inf->ino = ino;
 	inf->len = le16toh(fl->len);
 	if (inf->len & 0xF) {
 		fprintf(stderr,
--- a/ffstools/tiffs-rd/ls.c	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/ls.c	Sun Jan 26 11:47:13 2014 +0000
@@ -2,6 +2,7 @@
  * This C module implements the ls command.
  */
 
+#include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -11,31 +12,56 @@
 #include "globals.h"
 #include "pathname.h"
 
+static void
+segment_size_callback(inf, opaque)
+	struct inode_info *inf;
+	u_long opaque;
+{
+	size_t *accump = (size_t *) opaque;
+	struct chunkinfo chi;
+
+	size_extra_chunk(inf, &chi);
+	*accump += chi.len;
+}
+
+size_t
+get_file_size(seghead_ino, deleted)
+{
+	struct chunkinfo chi;
+	size_t accum;
+
+	size_head_chunk(inode_info[seghead_ino], &chi);
+	accum = chi.len;
+	iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum,
+			 deleted);
+	return(accum);
+}
+
 void
 ls_callback(pathname, ino, depth)
 	char *pathname;
 {
 	struct inode_info *inf = inode_info[ino];
-	char type;
+	u_long size;
 
 	switch (inf->type) {
 	case 0xE1:
 	case 0xF1:
-		type = 'f';
-		break;
+		size = get_file_size(ino, 0);
+		printf("f %7lu %s\n", size, pathname);
+		return;
 	case 0xF2:
-		type = 'd';
-		break;
+		printf("d         %s\n", pathname);
+		return;
 	case 0xF3:
-		type = 'l';
-		break;
+		printf("l         %s\n", pathname);
+		return;
 	default:
 		fprintf(stderr,
 			"BUG: bad inode byte %02X reached ls_callback()\n",
 			inf->type);
 		exit(1);
 	}
-	printf("%c %s\n", type, pathname);
 }
 
 cmd_ls()
--- a/ffstools/tiffs-rd/object.c	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/object.c	Sun Jan 26 11:47:13 2014 +0000
@@ -2,6 +2,7 @@
  * This C module implements object-level analysis.
  */
 
+#include <sys/types.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -56,3 +57,94 @@
 	inf->byte_after_name = p + 1;
 	return(1);
 }
+
+u8 *
+find_end_of_chunk(inf)
+	struct inode_info *inf;
+{
+	u8 *p;
+	int i;
+
+	p = inf->dataptr + inf->len;
+	for (i = 1; i <= 16; i++) {
+		if (!p[-i])
+			return(p - i);
+		if (p[-i] != 0xFF)
+			break;
+	}
+	fprintf(stderr,
+		"error: chunk @%x (inode #%x): no valid termination found\n",
+		inf->offset, inf->ino);
+	return(p);	/* bogon, allows the rest to continue */
+}
+
+size_head_chunk(inf, chi)
+	struct inode_info *inf;
+	struct chunkinfo *chi;
+{
+	chi->start = inf->byte_after_name;
+	chi->end = find_end_of_chunk(inf);
+	if (chi->start >= chi->end) {
+		chi->len = 0;
+		return(0);
+	} else {
+		chi->len = chi->end - chi->start;
+		return(1);
+	}
+}
+
+size_extra_chunk(inf, chi)
+	struct inode_info *inf;
+	struct chunkinfo *chi;
+{
+	chi->start = inf->dataptr;
+	chi->end = find_end_of_chunk(inf);
+	chi->len = chi->end - chi->start;
+}
+
+void
+iterate_seg_file(seghead, callback, callback_data, deleted)
+	void (*callback)();
+	u_long callback_data;
+{
+	int ino;
+	struct inode_info *inf;
+
+	for (ino = inode_info[seghead]->descend; ino; ino = inf->descend) {
+loop:		if (!validate_inode(ino)) {
+			fprintf(stderr,
+			"error: following seg file hit invalid inode #%x\n",
+				ino);
+			return;
+		}
+		inf = inode_info[ino];
+		switch (inf->type) {
+		case 0xF4:
+			callback(inf, callback_data);
+			continue;
+		case 0x00:
+			if (deleted) {
+				if (inf->len)
+					callback(inf, callback_data);
+				else
+					fprintf(stderr,
+	"error: presumed deleted segment inode #%x has been reclaimed\n",
+						ino);
+				continue;
+			}
+			if (!inf->sibling) {
+				fprintf(stderr,
+	"error: segment object at inode #%x: marked deleted, but no sibling\n",
+					ino);
+				return;
+			}
+			ino = inf->sibling;
+			goto loop;
+		default:
+			fprintf(stderr,
+	"error: inode #%x: unexpected type %02X when expecting segment (F4)\n",
+				ino, inf->type);
+			return;
+		}
+	}
+}
--- a/ffstools/tiffs-rd/struct.h	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/struct.h	Sun Jan 26 11:47:13 2014 +0000
@@ -23,6 +23,7 @@
 
 /* our own distilled info struct */
 struct inode_info {
+	int	ino;
 	/* info from the inode record */
 	int	type;
 	int	descend;
@@ -37,3 +38,10 @@
 	/* filled by misc */
 	u8	*byte_after_name;
 };
+
+/* chunk location and size info */
+struct chunkinfo {
+	u8	*start;
+	u8	*end;
+	size_t	len;
+};
--- a/ffstools/tiffs-rd/tree.c	Sun Jan 26 10:54:42 2014 +0000
+++ b/ffstools/tiffs-rd/tree.c	Sun Jan 26 11:47:13 2014 +0000
@@ -2,6 +2,7 @@
  * This C module implements operations on the tree level.
  */
 
+#include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>