view ffstools/tiffs-rd/xtr.c @ 418:a9bf3e92a30c

tfc139: clean exit on success
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Tue, 17 Jun 2014 20:59:59 +0000
parents 66a6f1652909
children
line wrap: on
line source

/*
 * This C module implements the xtr command.
 */

#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "types.h"
#include "struct.h"
#include "globals.h"
#include "pathname.h"

static void
dump_head_chunk(fd, headino)
{
	struct inode_info *inf = inode_info[headino];
	struct chunkinfo chi;

	if (size_head_chunk(inf, &chi))
		write(fd, chi.start, chi.len);
}

static void
dump_extra_chunk(inf, opaque)
	struct inode_info *inf;
	u_long opaque;
{
	int fd = (int)opaque;
	struct chunkinfo chi;

	size_extra_chunk(inf, &chi);
	write(fd, chi.start, chi.len);
}

extract_file(relpath, headino)
	char *relpath;
{
	int fd;

	fd = open(relpath, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if (fd < 0) {
		perror(relpath);
		exit(1);
	}
	dump_head_chunk(fd, headino);
	iterate_seg_file(headino, dump_extra_chunk, (u_long)fd, 0, 0);
	close(fd);
}

void
xtr_tree_callback(pathname, ino, depth)
	char *pathname;
{
	struct inode_info *inf = inode_info[ino];

	switch (inf->type) {
	case 0xE1:
	case 0xF1:
		/* skip /.journal; those who need it can cat it */
		if (strcmp(pathname, "/.journal"))
			extract_file(pathname + 1, ino);
		return;
	case 0xE2:
	case 0xF2:
		if (mkdir(pathname + 1, 0777) < 0) {
			perror(pathname + 1);
			exit(1);
		}
		return;
	case 0xE3:
	case 0xF3:
		fprintf(stderr,
	"symlink at %s ignored: symlink extraction not implemented yet\n",
			pathname);
		return;
	default:
		fprintf(stderr,
		"BUG: bad inode byte %02X reached xtr_tree_callback()\n",
			inf->type);
		exit(1);
	}
}

cmd_xtr(argc, argv)
	char **argv;
{
	if (argc != 2) {
		fprintf(stderr, "usage: xtr dest-dir\n");
		exit(1);
	}
	read_ffs_image();
	find_inode_block();
	alloc_inode_table();
	find_root_inode();
	if (chdir(argv[1]) < 0) {
		perror(argv[1]);
		exit(1);
	}
	traverse_visible_tree(xtr_tree_callback);
	exit(0);
}