FreeCalypso > hg > freecalypso-tools
view ffstools/tiffs-rd/object.c @ 72:e31b601744cd
CHANGES: fc-tmsh change documented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 27 Oct 2016 00:01:56 +0000 |
parents | e7502631a0f9 |
children | 1f27fc13eab7 |
line wrap: on
line source
/* * This C module implements object-level analysis. */ #include <sys/types.h> #include <ctype.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" validate_obj_name(ino, root_special) { struct inode_info *inf = inode_info[ino]; u8 *p, *endp; int c; if (!inf->len) return(0); p = inf->dataptr; endp = p + inf->len; for (; ; p++) { if (p >= endp) return(0); c = *p; if (!c) break; if (c < ' ' || c > '~') return(0); if (root_special || isalnum(c)) continue; switch (c) { case '.': case ',': case '_': case '-': case '+': case '%': case '$': case '#': continue; default: return(0); } } if (!root_special) { c = p - inf->dataptr; if (c < 1 || c > MAX_FN_COMPONENT) return(0); if (!strcmp(inf->dataptr, ".") || !strcmp(inf->dataptr, "..")) return(0); } inf->byte_after_name = p + 1; return(1); } u8 * find_end_of_chunk(inf) struct inode_info *inf; { u8 *p; int i; p = inf->dataptr + inf->len; for (i = 1; i <= 16; i++) { if (!p[-i]) return(p - i); if (p[-i] != 0xFF) break; } fprintf(stderr, "error: chunk @%x (inode #%x): no valid termination found\n", inf->offset, inf->ino); return(p); /* bogon, allows the rest to continue */ } size_head_chunk(inf, chi) struct inode_info *inf; struct chunkinfo *chi; { chi->start = inf->byte_after_name; chi->end = find_end_of_chunk(inf); if (chi->start >= chi->end) { chi->len = 0; return(0); } else { chi->len = chi->end - chi->start; return(1); } } size_extra_chunk(inf, chi) struct inode_info *inf; struct chunkinfo *chi; { chi->start = inf->dataptr; chi->end = find_end_of_chunk(inf); chi->len = chi->end - chi->start; } void iterate_seg_file(seghead, callback, callback_data, deleted, verbose) void (*callback)(); u_long callback_data; { int ino; struct inode_info *inf; for (ino = inode_info[seghead]->descend; ino; ino = inf->descend) { loop: if (!validate_inode(ino)) { fprintf(stderr, "error: following seg file hit invalid inode #%x\n", ino); return; } inf = inode_info[ino]; switch (inf->type) { case 0xF4: callback(inf, callback_data); continue; case 0x00: if (deleted) { if (inf->len) callback(inf, callback_data); else fprintf(stderr, "error: presumed deleted segment inode #%x has been reclaimed\n", ino); continue; } if (!inf->sibling) { fprintf(stderr, "error: segment object at inode #%x: marked deleted, but no sibling\n", ino); return; } if (verbose) printf("seg inode #%x deleted, moved to #%x\n", ino, inf->sibling); ino = inf->sibling; goto loop; default: fprintf(stderr, "error: inode #%x: unexpected type %02X when expecting segment (F4)\n", ino, inf->type); return; } } }