view pirollback/catino.c @ 51:e516128db432

pirollback: resurrect file descendant chains
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Wed, 24 Jul 2013 21:52:09 +0000
parents 18fa570685de
children
line wrap: on
line source

#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);
}