FreeCalypso > hg > freecalypso-tools
comparison ffstools/tiffs-rd/object.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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:e7502631a0f9 |
|---|---|
| 1 /* | |
| 2 * This C module implements object-level analysis. | |
| 3 */ | |
| 4 | |
| 5 #include <sys/types.h> | |
| 6 #include <ctype.h> | |
| 7 #include <stdio.h> | |
| 8 #include <stdlib.h> | |
| 9 #include <string.h> | |
| 10 #include <strings.h> | |
| 11 #include "types.h" | |
| 12 #include "struct.h" | |
| 13 #include "globals.h" | |
| 14 #include "pathname.h" | |
| 15 | |
| 16 validate_obj_name(ino, root_special) | |
| 17 { | |
| 18 struct inode_info *inf = inode_info[ino]; | |
| 19 u8 *p, *endp; | |
| 20 int c; | |
| 21 | |
| 22 if (!inf->len) | |
| 23 return(0); | |
| 24 p = inf->dataptr; | |
| 25 endp = p + inf->len; | |
| 26 for (; ; p++) { | |
| 27 if (p >= endp) | |
| 28 return(0); | |
| 29 c = *p; | |
| 30 if (!c) | |
| 31 break; | |
| 32 if (c < ' ' || c > '~') | |
| 33 return(0); | |
| 34 if (root_special || isalnum(c)) | |
| 35 continue; | |
| 36 switch (c) { | |
| 37 case '.': | |
| 38 case ',': | |
| 39 case '_': | |
| 40 case '-': | |
| 41 case '+': | |
| 42 case '%': | |
| 43 case '$': | |
| 44 case '#': | |
| 45 continue; | |
| 46 default: | |
| 47 return(0); | |
| 48 } | |
| 49 } | |
| 50 if (!root_special) { | |
| 51 c = p - inf->dataptr; | |
| 52 if (c < 1 || c > MAX_FN_COMPONENT) | |
| 53 return(0); | |
| 54 if (!strcmp(inf->dataptr, ".") || !strcmp(inf->dataptr, "..")) | |
| 55 return(0); | |
| 56 } | |
| 57 inf->byte_after_name = p + 1; | |
| 58 return(1); | |
| 59 } | |
| 60 | |
| 61 u8 * | |
| 62 find_end_of_chunk(inf) | |
| 63 struct inode_info *inf; | |
| 64 { | |
| 65 u8 *p; | |
| 66 int i; | |
| 67 | |
| 68 p = inf->dataptr + inf->len; | |
| 69 for (i = 1; i <= 16; i++) { | |
| 70 if (!p[-i]) | |
| 71 return(p - i); | |
| 72 if (p[-i] != 0xFF) | |
| 73 break; | |
| 74 } | |
| 75 fprintf(stderr, | |
| 76 "error: chunk @%x (inode #%x): no valid termination found\n", | |
| 77 inf->offset, inf->ino); | |
| 78 return(p); /* bogon, allows the rest to continue */ | |
| 79 } | |
| 80 | |
| 81 size_head_chunk(inf, chi) | |
| 82 struct inode_info *inf; | |
| 83 struct chunkinfo *chi; | |
| 84 { | |
| 85 chi->start = inf->byte_after_name; | |
| 86 chi->end = find_end_of_chunk(inf); | |
| 87 if (chi->start >= chi->end) { | |
| 88 chi->len = 0; | |
| 89 return(0); | |
| 90 } else { | |
| 91 chi->len = chi->end - chi->start; | |
| 92 return(1); | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 size_extra_chunk(inf, chi) | |
| 97 struct inode_info *inf; | |
| 98 struct chunkinfo *chi; | |
| 99 { | |
| 100 chi->start = inf->dataptr; | |
| 101 chi->end = find_end_of_chunk(inf); | |
| 102 chi->len = chi->end - chi->start; | |
| 103 } | |
| 104 | |
| 105 void | |
| 106 iterate_seg_file(seghead, callback, callback_data, deleted, verbose) | |
| 107 void (*callback)(); | |
| 108 u_long callback_data; | |
| 109 { | |
| 110 int ino; | |
| 111 struct inode_info *inf; | |
| 112 | |
| 113 for (ino = inode_info[seghead]->descend; ino; ino = inf->descend) { | |
| 114 loop: if (!validate_inode(ino)) { | |
| 115 fprintf(stderr, | |
| 116 "error: following seg file hit invalid inode #%x\n", | |
| 117 ino); | |
| 118 return; | |
| 119 } | |
| 120 inf = inode_info[ino]; | |
| 121 switch (inf->type) { | |
| 122 case 0xF4: | |
| 123 callback(inf, callback_data); | |
| 124 continue; | |
| 125 case 0x00: | |
| 126 if (deleted) { | |
| 127 if (inf->len) | |
| 128 callback(inf, callback_data); | |
| 129 else | |
| 130 fprintf(stderr, | |
| 131 "error: presumed deleted segment inode #%x has been reclaimed\n", | |
| 132 ino); | |
| 133 continue; | |
| 134 } | |
| 135 if (!inf->sibling) { | |
| 136 fprintf(stderr, | |
| 137 "error: segment object at inode #%x: marked deleted, but no sibling\n", | |
| 138 ino); | |
| 139 return; | |
| 140 } | |
| 141 if (verbose) | |
| 142 printf("seg inode #%x deleted, moved to #%x\n", | |
| 143 ino, inf->sibling); | |
| 144 ino = inf->sibling; | |
| 145 goto loop; | |
| 146 default: | |
| 147 fprintf(stderr, | |
| 148 "error: inode #%x: unexpected type %02X when expecting segment (F4)\n", | |
| 149 ino, inf->type); | |
| 150 return; | |
| 151 } | |
| 152 } | |
| 153 } |
