# HG changeset patch # User Michael Spacefalcon # Date 1372609228 0 # Node ID 95f61c3b430a56fd7298f0730a151e35634fecdd # Parent 660b0ea739f30b50849565d5ae1cb3a779e26b63 mpffs-rdutils: pathname search implemented diff -r 660b0ea739f3 -r 95f61c3b430a mpffs/Makefile --- 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 diff -r 660b0ea739f3 -r 95f61c3b430a mpffs/dbgls.c --- 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); } diff -r 660b0ea739f3 -r 95f61c3b430a mpffs/find.c --- /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 +#include +#include +#include +#include +#include +#include +#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); +}