changeset 919:1f27fc13eab7

tiffs: add support for extended filenames found in SE K2x0 FFS
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 31 Dec 2022 09:27:01 +0000
parents 0c33e24ff935
children 0306449ba467
files ffstools/tiffs-rd/cat.c ffstools/tiffs-rd/ls.c ffstools/tiffs-rd/object.c ffstools/tiffs-rd/tree.c
diffstat 4 files changed, 109 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ffstools/tiffs-rd/cat.c	Fri Dec 30 22:04:30 2022 +0000
+++ b/ffstools/tiffs-rd/cat.c	Sat Dec 31 09:27:01 2022 +0000
@@ -220,7 +220,7 @@
 		fprintf(stderr, "error: requested inode has been reclaimed\n");
 		exit(1);
 	}
-	if (!validate_obj_name(headino, 0)) {
+	if (!object_name_mincheck(headino)) {
 		fprintf(stderr,
 "error: no valid name at the beginning of the requested seghead chunk\n");
 		exit(1);
--- a/ffstools/tiffs-rd/ls.c	Fri Dec 30 22:04:30 2022 +0000
+++ b/ffstools/tiffs-rd/ls.c	Sat Dec 31 09:27:01 2022 +0000
@@ -13,6 +13,48 @@
 #include "pathname.h"
 
 static void
+print_ext_obj_name(inf, desc)
+	struct inode_info *inf;
+{
+	u8 *p;
+	int c;
+
+	printf("%s: ", desc);
+	p = inf->dataptr;
+	while (c = *p++) {
+		if (c == '\\') {
+			putchar('\\');
+			putchar('\\');
+		} else if (c >= ' ' && c <= '~')
+			putchar(c);
+		else
+			printf("\\x%02X", c);
+	}
+	putchar('\n');
+}
+
+static int
+obj_name_heuristic(inf)
+	struct inode_info *inf;
+{
+	u8 *p;
+	int c, n;
+
+	p = inf->dataptr;
+	while (c = *p++) {
+		if (n >= MAX_FN_COMPONENT)
+			return(0);
+		if (c < ' ' || c > '~')
+			return(0);
+		n++;
+	}
+	if (n)
+		return(1);
+	else
+		return(0);
+}
+
+static void
 segment_size_callback(inf, opaque)
 	struct inode_info *inf;
 	u_long opaque;
@@ -68,7 +110,7 @@
 }
 
 void
-ls_tree_callback(pathname, ino, depth)
+ls_tree_callback(pathname, ino, depth, bogonym_flag)
 	char *pathname;
 {
 	struct inode_info *inf = inode_info[ino];
@@ -84,16 +126,22 @@
 	case 0xF1:
 		size = get_file_size(ino, 0);
 		printf("f%c %7lu %s\n", readonly, size, pathname);
+		if (bogonym_flag)
+			print_ext_obj_name(inf, "actual name");
 		if (verbose2)
 			ls_seg_file(ino, 0);
 		return;
 	case 0xE2:
 	case 0xF2:
 		printf("d%c         %s\n", readonly, pathname);
+		if (bogonym_flag)
+			print_ext_obj_name(inf, "actual name");
 		return;
 	case 0xE3:
 	case 0xF3:
 		printf("l%c         %s\n", readonly, pathname);
+		if (bogonym_flag)
+			print_ext_obj_name(inf, "actual name");
 		return;
 	default:
 		fprintf(stderr,
@@ -287,18 +335,40 @@
 		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) {
+	switch (inf->type) {
+	case 0x00:
+		if (object_name_mincheck(ino) &&
+		    (assume_file || obj_name_heuristic(inf)))
+			print_ext_obj_name(inf, "object name");
+		else {
+no_name:		printf("No valid object name in the chunk\n\n");
+			return;
+		}
+		if (!assume_file)
+			break;
 		printf("total size: %lu bytes\n",
-			(u_long) get_file_size(ino, !inf->type));
+			(u_long) get_file_size(ino, 1));
 		if (verbose2)
-			ls_seg_file(ino, !inf->type);
+			ls_seg_file(ino, 1);
+		break;
+	case 0xE1:
+	case 0xF1:
+		if (object_name_mincheck(ino))
+			print_ext_obj_name(inf, "object name");
+		else
+			goto no_name;
+		printf("total size: %lu bytes\n",
+			(u_long) get_file_size(ino, 0));
+		if (verbose2)
+			ls_seg_file(ino, 0);
+		break;
+	case 0xF2:
+	case 0xF3:
+		if (object_name_mincheck(ino))
+			print_ext_obj_name(inf, "object name");
+		else
+			goto no_name;
+		break;
 	}
 	putchar('\n');
 }
--- a/ffstools/tiffs-rd/object.c	Fri Dec 30 22:04:30 2022 +0000
+++ b/ffstools/tiffs-rd/object.c	Sat Dec 31 09:27:01 2022 +0000
@@ -13,6 +13,25 @@
 #include "globals.h"
 #include "pathname.h"
 
+object_name_mincheck(ino)
+{
+	struct inode_info *inf = inode_info[ino];
+	u8 *p, *endp;
+
+	if (!inf->len)
+		return(0);
+	p = inf->dataptr;
+	endp = p + inf->len;
+	for (; ; p++) {
+		if (p >= endp)
+			return(0);
+		if (!*p)
+			break;
+	}
+	inf->byte_after_name = p + 1;
+	return(1);
+}
+
 validate_obj_name(ino, root_special)
 {
 	struct inode_info *inf = inode_info[ino];
--- a/ffstools/tiffs-rd/tree.c	Fri Dec 30 22:04:30 2022 +0000
+++ b/ffstools/tiffs-rd/tree.c	Sat Dec 31 09:27:01 2022 +0000
@@ -45,14 +45,18 @@
 				dirino, child);
 			continue;
 		}
-		if (!validate_obj_name(child, 0)) {
+		if (validate_obj_name(child, 0)) {
+			sprintf(pathbuf_ptr, "/%s", inf->dataptr);
+			callback(pathbuf_start, child, ndepth, 0);
+		} else if (object_name_mincheck(child)) {
+			sprintf(pathbuf_ptr, "/!bogo%04x", child);
+			callback(pathbuf_start, child, ndepth, 1);
+		} else {
 			fprintf(stderr,
 		"visible tree walk error: no valid name for inode #%x\n",
 				child);
 			continue;
 		}
-		sprintf(pathbuf_ptr, "/%s", inf->dataptr);
-		callback(pathbuf_start, child, ndepth);
 		if (inf->type == 0xF2)
 			visible_walk_dir(pathbuf_start,
 					 index(pathbuf_ptr, '\0'), child,
@@ -103,7 +107,7 @@
 				dirino, ino);
 			continue;
 		}
-		if (!validate_obj_name(ino, 0)) {
+		if (!object_name_mincheck(ino)) {
 			fprintf(stderr,
 		"visible tree walk error: no valid name for inode #%x\n",
 				ino);