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 }