FreeCalypso > hg > freecalypso-tools
view ffstools/tiffs-rd/basics.c @ 704:dacd9fdc392a
CHANGES: lunadrv addition documented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 07 May 2020 03:39:55 +0000 |
parents | e7502631a0f9 |
children |
line wrap: on
line source
/* * This C module implements the "basics" of TIFFS image analysis. */ #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <strings.h> #include "types.h" #include "struct.h" #include "globals.h" u8 tiffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02}; read_ffs_image() { int fd; struct stat st; fd = open(imgfile, O_RDONLY); if (fd < 0) { perror(imgfile); exit(1); } fstat(fd, &st); if (!S_ISREG(st.st_mode)) { fprintf(stderr, "error: %s is not a regular file\n", imgfile); exit(1); } if (st.st_size < imgfile_offset) { fprintf(stderr, "error: offset given with -o exceeds the size of the file\n"); exit(1); } if (st.st_size - imgfile_offset < total_ffs_size) { fprintf(stderr, "error: %s is shorter than FFS size of 0x%lx bytes\n", imgfile, (u_long)total_ffs_size); exit(1); } image = mmap(NULL, total_ffs_size, PROT_READ, MAP_PRIVATE, fd, imgfile_offset); if (image == MAP_FAILED) { perror("mmap"); exit(1); } close(fd); } cmd_blkhdr() { int blk; u8 *blkhdr; read_ffs_image(); for (blk = 0; blk < total_blocks; blk++) { printf("Block %3d: ", blk); blkhdr = image + blk * eraseblk_size; if (bcmp(blkhdr, tiffs_header, sizeof tiffs_header)) { printf("No TIFFS header\n"); continue; } printf("age %02X%02X, type/status %02X\n", blkhdr[7], blkhdr[6], blkhdr[8]); } exit(0); } find_inode_block() { int i, abcnt; u8 *ptr; if (index_blk_num >= 0) { if (index_blk_num >= total_blocks) { fprintf(stderr, "invalid block # given with the -a option\n"); exit(1); } ptr = image + index_blk_num * eraseblk_size; if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) { fprintf(stderr, "error: block specified with -a has no TIFFS header\n"); exit(1); } if (ptr[8] != 0xAB) { fprintf(stderr, "error: block specified with -a is not an AB block\n"); exit(1); } inode_block = ptr; return(0); } abcnt = 0; for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) { if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) { fprintf(stderr, "warning: no TIFFS signature in erase block #%d (offset %x)\n", i, ptr - image); continue; } switch (ptr[8]) { case 0xAB: if (verbose) fprintf(stderr, "Found AB index in erase block #%d (offset %x)\n", i, ptr - image); index_blk_num = i; inode_block = ptr; abcnt++; continue; case 0xBD: case 0xBF: continue; } fprintf(stderr, "warning: unexpected block type/status %02X at offset %x\n", ptr[8], ptr - image); } if (!inode_block) { fprintf(stderr, "error: could not find an active inode block in %s\n", imgfile); exit(1); } if (abcnt > 1) { fprintf(stderr, "error: found more than one AB block; use -a\n"); exit(1); } return(0); } cmd_fsinfo() { read_ffs_image(); find_inode_block(); printf("Active inode block (AB) is block #%d\n", index_blk_num); alloc_inode_table(); find_root_inode(); printf("Root inode is #%x\n", root_inode); if (validate_obj_name(root_inode, 1)) { printf("Root inode (format) name: %s\n", inode_info[root_inode]->dataptr); exit(0); } else { printf("No valid name found in the root inode!\n"); exit(1); } }