diff ffstools/tiffs-rd/ls.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 1f27fc13eab7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ffstools/tiffs-rd/ls.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,338 @@
+/*
+ * This C module implements the ls and lsino commands.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "types.h"
+#include "struct.h"
+#include "globals.h"
+#include "pathname.h"
+
+static void
+segment_size_callback(inf, opaque)
+	struct inode_info *inf;
+	u_long opaque;
+{
+	size_t *accump = (size_t *) opaque;
+	struct chunkinfo chi;
+
+	size_extra_chunk(inf, &chi);
+	*accump += chi.len;
+}
+
+size_t
+get_file_size(seghead_ino, deleted)
+{
+	struct chunkinfo chi;
+	size_t accum;
+
+	size_head_chunk(inode_info[seghead_ino], &chi);
+	accum = chi.len;
+	iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum,
+			 deleted, 0);
+	return(accum);
+}
+
+static void
+segment_ls_callback(inf, opaque)
+	struct inode_info *inf;
+	u_long opaque;
+{
+	struct chunkinfo chi;
+
+	size_extra_chunk(inf, &chi);
+	if (verbose2 > 1)
+		printf("seg #%04x @%08x length=%lu\n", inf->ino, inf->offset,
+			(u_long) chi.len);
+	else
+		printf("seg #%04x length=%lu\n", inf->ino, (u_long) chi.len);
+}
+
+ls_seg_file(seghead_ino, deleted)
+{
+	struct inode_info *inf = inode_info[seghead_ino];
+	struct chunkinfo chi;
+
+	size_head_chunk(inf, &chi);
+	printf("%lu bytes in seghead", (u_long) chi.len);
+	if (verbose2 > 1)
+		printf(", starting at offset %lx",
+			(u_long)(inf->byte_after_name - image));
+	putchar('\n');
+	iterate_seg_file(seghead_ino, segment_ls_callback, 0L, deleted,
+			 verbose2 > 1);
+}
+
+void
+ls_tree_callback(pathname, ino, depth)
+	char *pathname;
+{
+	struct inode_info *inf = inode_info[ino];
+	u_long size;
+	char readonly;
+
+	if (inf->type & 0x10)
+		readonly = ' ';
+	else
+		readonly = 'r';
+	switch (inf->type) {
+	case 0xE1:
+	case 0xF1:
+		size = get_file_size(ino, 0);
+		printf("f%c %7lu %s\n", readonly, size, pathname);
+		if (verbose2)
+			ls_seg_file(ino, 0);
+		return;
+	case 0xE2:
+	case 0xF2:
+		printf("d%c         %s\n", readonly, pathname);
+		return;
+	case 0xE3:
+	case 0xF3:
+		printf("l%c         %s\n", readonly, pathname);
+		return;
+	default:
+		fprintf(stderr,
+			"BUG: bad inode byte %02X reached ls_tree_callback()\n",
+			inf->type);
+		exit(1);
+	}
+}
+
+ls_by_pathname(pathname)
+	char *pathname;
+{
+	int ino;
+	struct inode_info *inf;
+	char *type;
+
+	printf("%s\n", pathname);
+	ino = find_pathname(pathname);
+	printf("inode #%x\n", ino);
+	inf = inode_info[ino];
+	switch (inf->type) {
+	case 0xE1:
+		type = "read-only file";
+		break;
+	case 0xF1:
+		type = "file";
+		break;
+	case 0xF2:
+		type = "directory";
+		break;
+	case 0xF3:
+		type = "symlink";
+		break;
+	default:
+		type = "???";
+	}
+	printf("object type %02X (%s)\n", inf->type, type);
+	if (!validate_obj_name(ino, ino == root_inode)) {
+		printf("No valid object name in the chunk!\n");
+		exit(1);
+	}
+	printf("object name: %s\n", inf->dataptr);
+	if (inf->type == 0xF1 || inf->type == 0xE1) {
+		printf("total size: %lu bytes\n",
+			(u_long) get_file_size(ino, 0));
+		if (verbose2)
+			ls_seg_file(ino, 0);
+	}
+	putchar('\n');
+}
+
+cmd_ls(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	int c;
+
+	read_ffs_image();
+	find_inode_block();
+	alloc_inode_table();
+	find_root_inode();
+
+	optind = 0;
+	while ((c = getopt(argc, argv, "v")) != EOF)
+		switch (c) {
+		case 'v':
+			verbose2++;
+			continue;
+		default:
+			fprintf(stderr, "usage: ls [-v[v]] [pathname...]\n");
+			exit(1);
+		}
+	if (optind >= argc) {
+		traverse_visible_tree(ls_tree_callback);
+		exit(0);
+	}
+	for (; optind < argc; optind++)
+		ls_by_pathname(argv[optind]);
+	exit(0);
+}
+
+lsino_all()
+{
+	int ino, last_ino = 0;
+	struct inode_info *inf;
+	char pathname[PATHNAME_BUF_SIZE], typech;
+	int pathstat;
+	char descend_str[8], sibling_str[8];
+
+	for (ino = 1; ino < inode_limit; ino++) {
+		if (!validate_inode(ino))
+			continue;
+		if (ino != last_ino + 1)
+			printf("GAP in inode numbers\n");
+		inf = inode_info[ino];
+		pathstat = pathname_of_inode(ino, pathname);
+		if (pathstat < 0)
+			strcpy(pathname, "-nopath-");
+		switch (inf->type) {
+		case 0x00:
+			typech = '~';
+			break;
+		case 0xE1:
+		case 0xF1:
+			typech = 'f';
+			break;
+		case 0xF2:
+			typech = 'd';
+			break;
+		case 0xF3:
+			typech = 'l';
+			break;
+		case 0xF4:
+			typech = '.';
+			break;
+		default:
+			typech = '?';
+		}
+		printf("#%04x %c %s\n", ino, typech, pathname);
+		if (inf->type && !(inf->type & 0x10))
+			printf("\tread-only object\n");
+		if (ino == root_inode)
+			printf("\tactive root\n");
+		else if (inf->nparents < 1)
+			printf("\torphan\n");
+		else if (inf->nparents > 1)
+			printf("\tparent: #%x (%d)\n", inf->parent,
+				inf->nparents);
+		else if (pathstat < 0 || verbose2)
+			printf("\tparent: #%x\n", inf->parent);
+		if (verbose2 > 1) {
+			if (inf->descend)
+				sprintf(descend_str, "#%x", inf->descend);
+			else
+				strcpy(descend_str, "null");
+			if (inf->sibling)
+				sprintf(sibling_str, "#%x", inf->sibling);
+			else
+				strcpy(sibling_str, "null");
+			printf("\tchild: %s, sibling: %s\n",
+				descend_str, sibling_str);
+		}
+		if (!inf->len)
+			printf("\treclaimed\n");
+		last_ino = ino;
+	}
+	exit(0);
+}
+
+void
+lsino_one(ino, assume_file)
+{
+	struct inode_info *inf;
+	char pathname[PATHNAME_BUF_SIZE], *type;
+
+	if (!validate_inode(ino)) {
+		fprintf(stderr, "lsino: specified inode number is invalid\n");
+		exit(1);
+	}
+	printf("inode #%x\n", ino);
+	inf = inode_info[ino];
+	if (pathname_of_inode(ino, pathname) >= 0)
+		printf("Pathname: %s\n", pathname);
+	else
+		printf("No pathname found\n");
+	inf = inode_info[ino];
+	switch (inf->type) {
+	case 0x00:
+		type = "deleted";
+		break;
+	case 0xE1:
+		type = "read-only file";
+		break;
+	case 0xF1:
+		type = "file";
+		break;
+	case 0xF2:
+		type = "directory";
+		break;
+	case 0xF3:
+		type = "symlink";
+		break;
+	case 0xF4:
+		type = "segment";
+		break;
+	default:
+		type = "???";
+	}
+	printf("object type %02X (%s)\n", inf->type, type);
+	if (!inf->len) {
+		printf("This inode has been reclaimed\n\n");
+		return;
+	}
+	if (validate_obj_name(ino, 1))
+		printf("object name: %s\n", inf->dataptr);
+	else {
+		printf("No valid object name in the chunk\n\n");
+		return;
+	}
+	if (inf->type == 0xF1 || inf->type == 0xE1 ||
+	    !inf->type && assume_file) {
+		printf("total size: %lu bytes\n",
+			(u_long) get_file_size(ino, !inf->type));
+		if (verbose2)
+			ls_seg_file(ino, !inf->type);
+	}
+	putchar('\n');
+}
+
+cmd_lsino(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	int c, assume_file = 0, ino;
+
+	read_ffs_image();
+	find_inode_block();
+	alloc_inode_table();
+	find_root_inode();
+	treewalk_all();
+
+	optind = 0;
+	while ((c = getopt(argc, argv, "fv")) != EOF)
+		switch (c) {
+		case 'f':
+			assume_file++;
+			continue;
+		case 'v':
+			verbose2++;
+			continue;
+		default:
+			fprintf(stderr, "usage: lsino [-v[v]] [ino...]\n");
+			exit(1);
+		}
+	if (optind >= argc)
+		return lsino_all();
+	for (; optind < argc; optind++) {
+		ino = strtoul(argv[optind], 0, 16);
+		lsino_one(ino, assume_file);
+	}
+	exit(0);
+}