changeset 49:18fa570685de

pirollback: catino implemented, works
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 07 Jul 2013 07:44:03 +0000
parents 79a0897dee7b
children 40b1ae2ab2d7
files .hgignore pirollback/Makefile pirollback/catino.c
diffstat 3 files changed, 99 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Jul 07 07:15:58 2013 +0000
+++ b/.hgignore	Sun Jul 07 07:44:03 2013 +0000
@@ -14,5 +14,6 @@
 ^mysteryffs/scan1$
 
 ^pirollback/analyze$
+^pirollback/catino$
 ^pirollback/dumpjournal$
 ^pirollback/inopath$
--- a/pirollback/Makefile	Sun Jul 07 07:15:58 2013 +0000
+++ b/pirollback/Makefile	Sun Jul 07 07:44:03 2013 +0000
@@ -1,8 +1,9 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	analyze dumpjournal inopath
+PROGS=	analyze catino dumpjournal inopath
 
 ANALYZE_OBJS=	analyze.o checknames.o init.o journal.o treewalk.o
+CAT_OBJS=	catino.o checknames.o init.o journal.o treewalk.o
 DUMPJ_OBJS=	checknames.o dumpjournal.o init.o journal.o pathname.o \
 		treewalk.o
 INOPATH_OBJS=	checknames.o init.o inopath.o pathname.o treewalk.o
@@ -12,6 +13,9 @@
 analyze:	${ANALYZE_OBJS}
 	${CC} -o $@ ${ANALYZE_OBJS}
 
+catino:		${CAT_OBJS}
+	${CC} -o $@ ${CAT_OBJS}
+
 dumpjournal:	${DUMPJ_OBJS}
 	${CC} -o $@ ${DUMPJ_OBJS}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pirollback/catino.c	Sun Jul 07 07:44:03 2013 +0000
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "types.h"
+#include "struct.h"
+
+extern char *imgfile;
+extern struct inode_info inode[];
+extern int last_inode;
+extern int journal_start_ino;
+
+u8 *
+find_end_of_chunk(ino)
+{
+	struct inode_info *ch = inode + ino;
+	u8 *p;
+	int i;
+
+	p = ch->dataptr + ch->len;
+	for (i = 1; i <= 16; i++) {
+		if (!p[-i])
+			return(p - i);
+		if (p[-1] != 0xFF)
+			break;
+	}
+	fprintf(stderr,
+	"chunk starting at %x (inode #%x): no valid termination found\n",
+		ch->offset, ino);
+	exit(1);
+}
+
+dump_cont_chain(start)
+{
+	int ino;
+	struct inode_info *inf;
+	u8 *endp;
+
+	for (ino = start; ino; ino = inf->descend) {
+		inf = inode + ino;
+		if (inf->type != 0xF4) {
+			fprintf(stderr,
+			"continuation chunk #%x does not have type F4\n",
+				ino);
+			exit(1);
+		}
+		endp = find_end_of_chunk(ino);
+		write(1, inf->dataptr, endp - inf->dataptr);
+	}
+}
+
+do_cat(ino)
+{
+	struct inode_info *inf = inode + ino;
+	u8 *endp;
+
+	if (inf->type != 0xF1) {
+		fprintf(stderr, "error: requested inode is not a file\n");
+		exit(1);
+	}
+	endp = find_end_of_chunk(ino);
+	if (endp > inf->byte_after_name)
+		write(1, inf->byte_after_name, endp - inf->byte_after_name);
+	dump_cont_chain(inf->descend);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	int ino;
+	char *strtoul_endp;
+
+	if (argc != 3) {
+usage:		fprintf(stderr, "usage: %s ffs-image inode\n", argv[0]);
+		exit(1);
+	}
+	imgfile = argv[1];
+	ino = strtoul(argv[2], &strtoul_endp, 16);
+	if (!argv[2][0] || *strtoul_endp)
+		goto usage;
+	read_img_file();
+	read_inodes();
+	walk_tree();
+	check_object_names();
+	parse_journal();
+	check_object_names();	/* rerun for "undeleted" objects */
+	if (ino < 1 || ino > last_inode) {
+		fprintf(stderr, "%s: bad inode number specified\n", argv[0]);
+		exit(1);
+	}
+	do_cat(ino);
+	exit(0);
+}