FreeCalypso > hg > freecalypso-tools
diff ffstools/tiffs-rd/ls.c @ 0:e7502631a0f9
initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Jun 2016 00:13:35 +0000 |
parents | |
children | 1f27fc13eab7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/tiffs-rd/ls.c Sat Jun 11 00:13:35 2016 +0000 @@ -0,0 +1,338 @@ +/* + * 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); +}