FreeCalypso > hg > freecalypso-sw
view ffstools/tiffs-rd/ls.c @ 295:3dd74b16df82
fc-fsio: pathname recursion handling revamped
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 01 Mar 2014 08:01:08 +0000 |
parents | e14609e9b907 |
children |
line wrap: on
line source
/* * This C module implements the ls and lsino commands. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "types.h" #include "struct.h" #include "globals.h" #include "pathname.h" static void segment_size_callback(inf, opaque) struct inode_info *inf; u_long opaque; { size_t *accump = (size_t *) opaque; struct chunkinfo chi; size_extra_chunk(inf, &chi); *accump += chi.len; } size_t get_file_size(seghead_ino, deleted) { struct chunkinfo chi; size_t accum; size_head_chunk(inode_info[seghead_ino], &chi); accum = chi.len; iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum, deleted, 0); return(accum); } static void segment_ls_callback(inf, opaque) struct inode_info *inf; u_long opaque; { struct chunkinfo chi; size_extra_chunk(inf, &chi); if (verbose2 > 1) printf("seg #%04x @%08x length=%lu\n", inf->ino, inf->offset, (u_long) chi.len); else printf("seg #%04x length=%lu\n", inf->ino, (u_long) chi.len); } ls_seg_file(seghead_ino, deleted) { struct inode_info *inf = inode_info[seghead_ino]; struct chunkinfo chi; size_head_chunk(inf, &chi); printf("%lu bytes in seghead", (u_long) chi.len); if (verbose2 > 1) printf(", starting at offset %lx", (u_long)(inf->byte_after_name - image)); putchar('\n'); iterate_seg_file(seghead_ino, segment_ls_callback, 0L, deleted, verbose2 > 1); } void ls_tree_callback(pathname, ino, depth) char *pathname; { struct inode_info *inf = inode_info[ino]; u_long size; char readonly; if (inf->type & 0x10) readonly = ' '; else readonly = 'r'; switch (inf->type) { case 0xE1: case 0xF1: size = get_file_size(ino, 0); printf("f%c %7lu %s\n", readonly, size, pathname); if (verbose2) ls_seg_file(ino, 0); return; case 0xE2: case 0xF2: printf("d%c %s\n", readonly, pathname); return; case 0xE3: case 0xF3: printf("l%c %s\n", readonly, pathname); return; default: fprintf(stderr, "BUG: bad inode byte %02X reached ls_tree_callback()\n", inf->type); exit(1); } } ls_by_pathname(pathname) char *pathname; { int ino; struct inode_info *inf; char *type; printf("%s\n", pathname); ino = find_pathname(pathname); printf("inode #%x\n", ino); inf = inode_info[ino]; switch (inf->type) { case 0xE1: type = "read-only file"; break; case 0xF1: type = "file"; break; case 0xF2: type = "directory"; break; case 0xF3: type = "symlink"; break; default: type = "???"; } printf("object type %02X (%s)\n", inf->type, type); if (!validate_obj_name(ino, ino == root_inode)) { printf("No valid object name in the chunk!\n"); exit(1); } printf("object name: %s\n", inf->dataptr); if (inf->type == 0xF1 || inf->type == 0xE1) { printf("total size: %lu bytes\n", (u_long) get_file_size(ino, 0)); if (verbose2) ls_seg_file(ino, 0); } putchar('\n'); } cmd_ls(argc, argv) char **argv; { extern int optind; int c; read_ffs_image(); find_inode_block(); alloc_inode_table(); find_root_inode(); optind = 0; while ((c = getopt(argc, argv, "v")) != EOF) switch (c) { case 'v': verbose2++; continue; default: fprintf(stderr, "usage: ls [-v[v]] [pathname...]\n"); exit(1); } if (optind >= argc) { traverse_visible_tree(ls_tree_callback); exit(0); } for (; optind < argc; optind++) ls_by_pathname(argv[optind]); exit(0); } lsino_all() { int ino, last_ino = 0; struct inode_info *inf; char pathname[PATHNAME_BUF_SIZE], typech; int pathstat; char descend_str[8], sibling_str[8]; for (ino = 1; ino < inode_limit; ino++) { if (!validate_inode(ino)) continue; if (ino != last_ino + 1) printf("GAP in inode numbers\n"); inf = inode_info[ino]; pathstat = pathname_of_inode(ino, pathname); if (pathstat < 0) strcpy(pathname, "-nopath-"); switch (inf->type) { case 0x00: typech = '~'; break; case 0xE1: case 0xF1: typech = 'f'; break; case 0xF2: typech = 'd'; break; case 0xF3: typech = 'l'; break; case 0xF4: typech = '.'; break; default: typech = '?'; } printf("#%04x %c %s\n", ino, typech, pathname); if (inf->type && !(inf->type & 0x10)) printf("\tread-only object\n"); if (ino == root_inode) printf("\tactive root\n"); else if (inf->nparents < 1) printf("\torphan\n"); else if (inf->nparents > 1) printf("\tparent: #%x (%d)\n", inf->parent, inf->nparents); else if (pathstat < 0 || verbose2) printf("\tparent: #%x\n", inf->parent); if (verbose2 > 1) { if (inf->descend) sprintf(descend_str, "#%x", inf->descend); else strcpy(descend_str, "null"); if (inf->sibling) sprintf(sibling_str, "#%x", inf->sibling); else strcpy(sibling_str, "null"); printf("\tchild: %s, sibling: %s\n", descend_str, sibling_str); } if (!inf->len) printf("\treclaimed\n"); last_ino = ino; } exit(0); } void lsino_one(ino, assume_file) { struct inode_info *inf; char pathname[PATHNAME_BUF_SIZE], *type; if (!validate_inode(ino)) { fprintf(stderr, "lsino: specified inode number is invalid\n"); exit(1); } printf("inode #%x\n", ino); inf = inode_info[ino]; if (pathname_of_inode(ino, pathname) >= 0) printf("Pathname: %s\n", pathname); else printf("No pathname found\n"); inf = inode_info[ino]; switch (inf->type) { case 0x00: type = "deleted"; break; case 0xE1: type = "read-only file"; break; case 0xF1: type = "file"; break; case 0xF2: type = "directory"; break; case 0xF3: type = "symlink"; break; case 0xF4: type = "segment"; break; default: type = "???"; } printf("object type %02X (%s)\n", inf->type, type); if (!inf->len) { 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) { printf("total size: %lu bytes\n", (u_long) get_file_size(ino, !inf->type)); if (verbose2) ls_seg_file(ino, !inf->type); } putchar('\n'); } cmd_lsino(argc, argv) char **argv; { extern int optind; int c, assume_file = 0, ino; read_ffs_image(); find_inode_block(); alloc_inode_table(); find_root_inode(); treewalk_all(); optind = 0; while ((c = getopt(argc, argv, "fv")) != EOF) switch (c) { case 'f': assume_file++; continue; case 'v': verbose2++; continue; default: fprintf(stderr, "usage: lsino [-v[v]] [ino...]\n"); exit(1); } if (optind >= argc) return lsino_all(); for (; optind < argc; optind++) { ino = strtoul(argv[optind], 0, 16); lsino_one(ino, assume_file); } exit(0); }