diff ffstools/tiffs-rd/basics.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/basics.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,155 @@
+/*
+ * This C module implements the "basics" of TIFFS image analysis.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include "types.h"
+#include "struct.h"
+#include "globals.h"
+
+u8 tiffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02};
+
+read_ffs_image()
+{
+	int fd;
+	struct stat st;
+
+	fd = open(imgfile, O_RDONLY);
+	if (fd < 0) {
+		perror(imgfile);
+		exit(1);
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		fprintf(stderr, "error: %s is not a regular file\n", imgfile);
+		exit(1);
+	}
+	if (st.st_size < imgfile_offset) {
+		fprintf(stderr,
+		"error: offset given with -o exceeds the size of the file\n");
+		exit(1);
+	}
+	if (st.st_size - imgfile_offset < total_ffs_size) {
+		fprintf(stderr,
+			"error: %s is shorter than FFS size of 0x%lx bytes\n",
+			imgfile, (u_long)total_ffs_size);
+		exit(1);
+	}
+	image = mmap(NULL, total_ffs_size, PROT_READ, MAP_PRIVATE, fd,
+			imgfile_offset);
+	if (image == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+	close(fd);
+}
+
+cmd_blkhdr()
+{
+	int blk;
+	u8 *blkhdr;
+
+	read_ffs_image();
+	for (blk = 0; blk < total_blocks; blk++) {
+		printf("Block %3d: ", blk);
+		blkhdr = image + blk * eraseblk_size;
+		if (bcmp(blkhdr, tiffs_header, sizeof tiffs_header)) {
+			printf("No TIFFS header\n");
+			continue;
+		}
+		printf("age %02X%02X, type/status %02X\n",
+			blkhdr[7], blkhdr[6], blkhdr[8]);
+	}
+	exit(0);
+}
+
+find_inode_block()
+{
+	int i, abcnt;
+	u8 *ptr;
+
+	if (index_blk_num >= 0) {
+		if (index_blk_num >= total_blocks) {
+			fprintf(stderr,
+				"invalid block # given with the -a option\n");
+			exit(1);
+		}
+		ptr = image + index_blk_num * eraseblk_size;
+		if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) {
+			fprintf(stderr,
+			"error: block specified with -a has no TIFFS header\n");
+			exit(1);
+		}
+		if (ptr[8] != 0xAB) {
+			fprintf(stderr,
+			"error: block specified with -a is not an AB block\n");
+			exit(1);
+		}
+		inode_block = ptr;
+		return(0);
+	}
+	abcnt = 0;
+	for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) {
+		if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) {
+			fprintf(stderr,
+		"warning: no TIFFS signature in erase block #%d (offset %x)\n",
+				i, ptr - image);
+			continue;
+		}
+		switch (ptr[8]) {
+		case 0xAB:
+			if (verbose)
+				fprintf(stderr,
+			"Found AB index in erase block #%d (offset %x)\n",
+					i, ptr - image);
+			index_blk_num = i;
+			inode_block = ptr;
+			abcnt++;
+			continue;
+		case 0xBD:
+		case 0xBF:
+			continue;
+		}
+		fprintf(stderr,
+		"warning: unexpected block type/status %02X at offset %x\n",
+			ptr[8], ptr - image);
+	}
+	if (!inode_block) {
+		fprintf(stderr,
+			"error: could not find an active inode block in %s\n",
+			imgfile);
+		exit(1);
+	}
+	if (abcnt > 1) {
+		fprintf(stderr,
+			"error: found more than one AB block; use -a\n");
+		exit(1);
+	}
+	return(0);
+}
+
+cmd_fsinfo()
+{
+	read_ffs_image();
+	find_inode_block();
+	printf("Active inode block (AB) is block #%d\n", index_blk_num);
+	alloc_inode_table();
+	find_root_inode();
+	printf("Root inode is #%x\n", root_inode);
+	if (validate_obj_name(root_inode, 1)) {
+		printf("Root inode (format) name: %s\n",
+			inode_info[root_inode]->dataptr);
+		exit(0);
+	} else {
+		printf("No valid name found in the root inode!\n");
+		exit(1);
+	}
+}