FreeCalypso > hg > freecalypso-tools
diff ffstools/tiffs-rd/cat.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/cat.c Sat Jun 11 00:13:35 2016 +0000 @@ -0,0 +1,233 @@ +/* + * This C module implements the cat and catino commands. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include "types.h" +#include "struct.h" +#include "globals.h" +#include "pathname.h" + +int cat_mode; + +static u8 hex_buf[16]; +static int hex_fill; +static u32 hex_offset; + +cat_hex_flush() +{ + int i, c; + + printf("%08X: ", hex_offset); + for (i = 0; i < 16; i++) { + if (i < hex_fill) + printf("%02X ", hex_buf[i]); + else + fputs(" ", stdout); + if (i == 7 || i == 15) + putchar(' '); + } + for (i = 0; i < hex_fill; i++) { + c = hex_buf[i]; + if (c < ' ' || c > '~') + c = '.'; + putchar(c); + } + putchar('\n'); +} + +cat_hex_byte(inb) +{ + hex_buf[hex_fill++] = inb; + if (hex_fill >= 16) { + cat_hex_flush(); + hex_offset += hex_fill; + hex_fill = 0; + } +} + +void +cat_chunk(ch) + struct chunkinfo *ch; +{ + u8 *p; + int c; + + if (!ch->len) + return; + switch (cat_mode) { + case 0: + write(1, ch->start, ch->len); + return; + case 1: + for (p = ch->start; p < ch->end; p++) { + c = *p; + if (c >= ' ' && c <= '~' || c == '\n') + putchar(c); + else { + if (c & 0x80) { + putchar('M'); + putchar('-'); + c &= 0x7F; + } + putchar('^'); + if (c == 0x7F) + putchar('?'); + else + putchar(c + '@'); + } + } + return; + case 2: + for (p = ch->start; p < ch->end; p++) + cat_hex_byte(*p); + return; + } +} + +void +cat_finish() +{ + switch (cat_mode) { + case 1: + putchar('\n'); + return; + case 2: + if (hex_fill) + cat_hex_flush(); + return; + } +} + +static void +segment_cat_callback(inf, opaque) + struct inode_info *inf; + u_long opaque; +{ + struct chunkinfo chi; + + size_extra_chunk(inf, &chi); + cat_chunk(&chi); +} + +cmd_cat(argc, argv) + char **argv; +{ + extern int optind; + int c, headino; + struct inode_info *inf; + struct chunkinfo chi; + + optind = 0; + while ((c = getopt(argc, argv, "hv")) != EOF) + switch (c) { + case 'h': + cat_mode = 2; + continue; + case 'v': + cat_mode = 1; + continue; + default: +usage: fprintf(stderr, "usage: cat [-v|-h] pathname\n"); + exit(1); + } + if (argc != optind + 1) + goto usage; + + read_ffs_image(); + find_inode_block(); + alloc_inode_table(); + find_root_inode(); + + headino = find_pathname(argv[optind]); + inf = inode_info[headino]; + switch (inf->type) { + case 0xE1: + case 0xF1: + break; + case 0xF2: + fprintf(stderr, "error: the requested object is a directory\n"); + exit(1); + case 0xF3: + fprintf(stderr, +"error: the requested object is a symlink; use readlink instead of cat\n"); + exit(1); + default: + fprintf(stderr, "error: unexpected object type %02X\n", + inf->type); + exit(1); + } + size_head_chunk(inf, &chi); + cat_chunk(&chi); + iterate_seg_file(headino, segment_cat_callback, 0L, 0, 0); + cat_finish(); + exit(0); +} + +cmd_catino(argc, argv) + char **argv; +{ + extern int optind; + int c, headino; + struct inode_info *inf; + struct chunkinfo chi; + + optind = 0; + while ((c = getopt(argc, argv, "hv")) != EOF) + switch (c) { + case 'h': + cat_mode = 2; + continue; + case 'v': + cat_mode = 1; + continue; + default: +usage: fprintf(stderr, "usage: catino [-v|-h] ino\n"); + exit(1); + } + if (argc != optind + 1) + goto usage; + headino = strtoul(argv[optind], 0, 16); + + read_ffs_image(); + find_inode_block(); + alloc_inode_table(); + if (!validate_inode(headino)) { + fprintf(stderr, "catino: specified inode number is invalid\n"); + exit(1); + } + inf = inode_info[headino]; + switch (inf->type) { + case 0x00: + case 0xE1: + case 0xF1: + case 0xF3: + break; + case 0xF2: + fprintf(stderr, "error: the requested object is a directory\n"); + exit(1); + default: + fprintf(stderr, "error: unexpected object type %02X\n", + inf->type); + exit(1); + } + if (!inf->len) { + fprintf(stderr, "error: requested inode has been reclaimed\n"); + exit(1); + } + if (!validate_obj_name(headino, 0)) { + fprintf(stderr, +"error: no valid name at the beginning of the requested seghead chunk\n"); + exit(1); + } + size_head_chunk(inf, &chi); + cat_chunk(&chi); + iterate_seg_file(headino, segment_cat_callback, 0L, !inf->type, 0); + cat_finish(); + exit(0); +}