diff ffstools/tiffs-rd/xtr.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ffstools/tiffs-rd/xtr.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,105 @@
+/*
+ * 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);
+}