diff pirollback/catino.c @ 49:18fa570685de

pirollback: catino implemented, works
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 07 Jul 2013 07:44:03 +0000
parents
children
line wrap: on
line diff
--- /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);
+}