FreeCalypso > hg > freecalypso-sw
view target-utils/libmpffs/basicfind.c @ 101:7029fe8ae0bc
pirexplore: FFS find command implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 02 Sep 2013 00:33:54 +0000 |
parents | |
children | 7f75ffdd674f |
line wrap: on
line source
#include <sys/types.h> #include "types.h" #include "struct.h" #include "globals.h" #include "macros.h" extern char *index(); static u8 * find_endofchunk(ino) { struct inode *irec = mpffs_active_index + ino; u8 *p; int i; p = inode_to_dataptr(irec) + irec->len; for (i = 0; i < 16; i++) { p--; if (!*p) return(p); if (*p != 0xFF) break; } printf("Error: inode #%x has no valid termination\n", ino); return(p); /* XXX */ } static find_named_child(start, seekname) char *seekname; { int ino; struct inode *irec; for (ino = start; ino != 0xFFFF; ino = irec->sibling) { irec = mpffs_active_index + ino; if (!irec->type) continue; if (!strcmp(inode_to_dataptr(irec), seekname)) return(ino); } return(0); } mpffs_pathname_to_inode(pathname) char *pathname; { int ino, stat; struct inode *irec; char *cur, *next; stat = mpffs_init(); if (stat < 0) return(stat); cur = pathname; if (*cur == '/') cur++; for (ino = mpffs_root_ino; cur; cur = next) { if (!*cur) break; next = index(cur, '/'); if (next == cur) { printf("malformed pathname: multiple adjacent slashes\n"); return(-1); } if (next) *next++ = '\0'; irec = mpffs_active_index + ino; if (irec->type != OBJTYPE_DIR) { printf("Error: non-terminal non-directory\n"); if (next) next[-1] = '/'; return(-1); } ino = find_named_child(irec->descend, cur); if (next) next[-1] = '/'; if (!ino) { printf("Error: pathname component not found\n"); return(-1); } } return(ino); } mpffs_find_file(pathname, startret, sizeret, continue_ret) char *pathname; u8 **startret; size_t *sizeret; int *continue_ret; { int ino, cont; struct inode *irec; u8 *start, *end; size_t size; ino = mpffs_pathname_to_inode(pathname); if (ino <= 0) return(-1); irec = mpffs_active_index + ino; if (irec->type != OBJTYPE_FILE) { printf("Error: %s is not a regular file\n", pathname); return(-1); } start = inode_to_dataptr(irec); start += strlen(start) + 1; end = find_endofchunk(ino); size = end - start; if (size < 0) size = 0; cont = irec->descend; if (cont == 0xFFFF) cont = 0; if (startret) *startret = start; if (sizeret) *sizeret = size; if (continue_ret) *continue_ret = cont; return(0); } mpffs_get_segment(ino, startret, sizeret, continue_ret) int ino; u8 **startret; size_t *sizeret; int *continue_ret; { int cont; struct inode *irec; u8 *start, *end; size_t size; for (;;) { irec = mpffs_active_index + ino; if (irec->type) break; if (irec->sibling == 0xFFFF) { printf("Error: segment inode #%d: deleted and no sibling\n", ino); return(-1); } ino = irec->sibling; } if (irec->type != OBJTYPE_SEGMENT) { printf("Error: inode #%x is not a segment\n", ino); return(-1); } start = inode_to_dataptr(irec); end = find_endofchunk(ino); size = end - start; if (size <= 0) { printf("Error: segment inode #%x: bad length\n", ino); return(-1); } cont = irec->descend; if (cont == 0xFFFF) cont = 0; if (startret) *startret = start; if (sizeret) *sizeret = size; if (continue_ret) *continue_ret = cont; return(0); }