changeset 34:95f61c3b430a

mpffs-rdutils: pathname search implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Jun 2013 16:20:28 +0000
parents 660b0ea739f3
children ee4c761187cf
files mpffs/Makefile mpffs/dbgls.c mpffs/find.c
diffstat 3 files changed, 127 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mpffs/Makefile	Sun Jun 30 07:47:49 2013 +0000
+++ b/mpffs/Makefile	Sun Jun 30 16:20:28 2013 +0000
@@ -3,8 +3,8 @@
 PROGS=	mpffs-dbgls mpffs-ls
 INSTDIR=/usr/local/bin
 
-CAT_OBJS=	common.o cat.o
-DBGLS_OBJS=	common.o dbgls.o
+CAT_OBJS=	common.o cat.o find.o
+DBGLS_OBJS=	common.o dbgls.o find.o
 LS_OBJS=	common.o ls.o
 XTR_OBJS=	common.o xtr.o
 
--- a/mpffs/dbgls.c	Sun Jun 30 07:47:49 2013 +0000
+++ b/mpffs/dbgls.c	Sun Jun 30 16:20:28 2013 +0000
@@ -119,9 +119,34 @@
 	}
 }
 
+save_pathname_arg(pnarg)
+	char *pnarg;
+{
+	if (*pnarg == '/')
+		pnarg++;
+	if (strlen(pnarg) + 2 > sizeof workpath) {
+		fprintf(stderr,
+	"error: specified pathname is too long (overflows internal buffer)\n");
+		exit(1);
+	}
+	sprintf(workpath, "/%s", pnarg);
+}
+
+dump_by_pathname(pnarg)
+	char *pnarg;
+{
+	struct objinfo obj;
+
+	save_pathname_arg(pnarg);
+	obj.entryno = find_pathname(pnarg);
+	get_index_entry(&obj);
+	validate_chunk(&obj);
+	dump_object(&obj);
+}
+
 usage()
 {
-	fprintf(stderr, "usage: mpffs-dbgls [options] ffs-image\n");
+	fprintf(stderr, "usage: mpffs-dbgls [options] ffs-image [pathname]\n");
 	exit(1);
 }
 
@@ -131,11 +156,16 @@
 	extern int optind;
 
 	parse_cmdline_options(argc, argv);
-	if (argc - optind != 1)
+	argc -= optind;
+	argv += optind;
+	if (argc < 1 || argc > 2)
 		usage();
 	verbose++;
-	imgfile = argv[optind];
+	imgfile = argv[0];
 	preliminaries();
-	dump_dir(root.descend, 0);
+	if (argc == 1)
+		dump_dir(root.descend, 0);
+	else
+		dump_by_pathname(argv[1]);
 	exit(0);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpffs/find.c	Sun Jun 30 16:20:28 2013 +0000
@@ -0,0 +1,91 @@
+/*
+ * This module contains the code for searching the FFS tree structure
+ * for a specified absolute pathname.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "types.h"
+#include "struct.h"
+
+extern int root_node_no;
+
+/*
+ * The following function iterates through the descendants of a directory
+ * object looking for a specific directory-member filename.
+ *
+ * Arguments:
+ * - index # of the first descendant (descendant pointer from the dir object)
+ * - filename to search for
+ *
+ * Returns: index # of the sought descendant object if found, 0 otherwise.
+ */
+find_dir_member(first_descend, srchname)
+	char *srchname;
+{
+	int ent;
+	struct objinfo obj;
+
+	for (ent = first_descend; ent != 0xFFFF; ent = obj.sibling) {
+		obj.entryno = ent;
+		get_index_entry(&obj);
+		if (!obj.type) /* skip deleted objects w/o further looking */
+			continue;
+		validate_chunk(&obj);
+		validate_obj_name(&obj);
+		if (!strcmp(obj.dataptr, srchname))
+			return(ent);
+	}
+	return(0);
+}
+
+/*
+ * The following function searches for a pathname from the root down.
+ * Returns the index # if found, otherwise exits with an error message
+ * indicating which step failed.
+ *
+ * Warning: the pathname in the argument buffer will be destroyed:
+ * 0s put in place of the slashes.
+ */
+find_pathname(pathname)
+	char *pathname;
+{
+	char *cur, *next;
+	int idx;
+	struct objinfo dir;
+
+	cur = pathname;
+	if (*cur == '/')
+		cur++;
+	for (idx = root_node_no; cur; cur = next) {
+		if (!*cur)
+			break;
+		next = index(cur, '/');
+		if (next == cur) {
+			fprintf(stderr,
+			"malformed pathname: multiple adjacent slashes\n");
+			exit(1);
+		}
+		if (next)
+			*next++ = '\0';
+		dir.entryno = idx;
+		get_index_entry(&dir);
+		if (dir.type != 0xF2) {
+			fprintf(stderr,
+			"pathname search error: encountered a non-directory\n");
+			exit(1);
+		}
+		idx = find_dir_member(dir.descend, cur);
+		if (!idx) {
+			fprintf(stderr,
+			"pathname search error: component name not found\n");
+			exit(1);
+		}
+	}
+	return(idx);
+}