FreeCalypso > hg > freecalypso-tools
comparison ffstools/tiffs-rd/inode.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e7502631a0f9 |
---|---|
1 /* | |
2 * This C module implements the reading and decoding of inode information. | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <endian.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 | |
15 u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | |
16 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | |
17 | |
18 alloc_inode_table() | |
19 { | |
20 inode_info = malloc(sizeof(struct inode_info *) * inode_limit); | |
21 if (!inode_info) { | |
22 perror("malloc of inode table"); | |
23 exit(1); | |
24 } | |
25 bzero(inode_info, sizeof(struct inode_info *) * inode_limit); | |
26 } | |
27 | |
28 static int | |
29 convert_ptr(in, infp) | |
30 int in; | |
31 int *infp; | |
32 { | |
33 if (in == 0xFFFF) { | |
34 *infp = 0; | |
35 return(0); | |
36 } | |
37 if (in < 1 || in >= inode_limit) | |
38 return(-1); | |
39 *infp = in; | |
40 return(1); | |
41 } | |
42 | |
43 validate_inode(ino) | |
44 { | |
45 struct inode_flash *fl; | |
46 struct inode_info *inf; | |
47 | |
48 if (ino < 1 || ino >= inode_limit) | |
49 return(0); | |
50 if (inode_info[ino]) | |
51 return(1); | |
52 fl = (struct inode_flash *)inode_block + ino; | |
53 if (!bcmp(fl, blank_flash_line, sizeof blank_flash_line)) | |
54 return(0); | |
55 inf = malloc(sizeof(struct inode_info)); | |
56 if (!inf) { | |
57 perror("malloc of struct inode_info"); | |
58 exit(1); | |
59 } | |
60 bzero(inf, sizeof(struct inode_info)); | |
61 inf->ino = ino; | |
62 inf->len = le16toh(fl->len); | |
63 if (inf->len & 0xF) { | |
64 fprintf(stderr, | |
65 "warning: inode #%x: invalid length, skipping\n", ino); | |
66 free(inf); | |
67 return(0); | |
68 } | |
69 inf->type = fl->type; | |
70 switch (inf->type) { | |
71 case 0x00: | |
72 break; | |
73 case 0xE1: | |
74 case 0xF1: | |
75 case 0xF2: | |
76 case 0xF3: | |
77 case 0xF4: | |
78 if (!inf->len) { | |
79 fprintf(stderr, | |
80 "warning: inode #%x: non-deleted object has zero length, skipping\n", | |
81 ino); | |
82 free(inf); | |
83 return(0); | |
84 } | |
85 break; | |
86 default: | |
87 fprintf(stderr, | |
88 "warning: inode #%x: unexpected object type %02X, skipping\n", | |
89 ino, inf->type); | |
90 free(inf); | |
91 return(0); | |
92 } | |
93 if (convert_ptr(le16toh(fl->descend), &inf->descend) < 0) { | |
94 fprintf(stderr, | |
95 "warning: inode #%x: invalid descend pointer, skipping\n", | |
96 ino); | |
97 free(inf); | |
98 return(0); | |
99 } | |
100 if (convert_ptr(le16toh(fl->sibling), &inf->sibling) < 0) { | |
101 fprintf(stderr, | |
102 "warning: inode #%x: invalid sibling pointer, skipping\n", | |
103 ino); | |
104 free(inf); | |
105 return(0); | |
106 } | |
107 if (inf->len) { | |
108 inf->rawloc = le32toh(fl->dataptr); | |
109 if (old_16bit_location) | |
110 inf->rawloc >>= 16; | |
111 if (inf->rawloc > 0x0FFFFFFF) { | |
112 invdptr: fprintf(stderr, | |
113 "warning: inode #%x: invalid data pointer, skipping\n", | |
114 ino); | |
115 free(inf); | |
116 return(0); | |
117 } | |
118 inf->offset = inf->rawloc << 4; | |
119 if (inf->offset >= total_ffs_size) | |
120 goto invdptr; | |
121 if (inf->offset + inf->len > total_ffs_size) { | |
122 fprintf(stderr, | |
123 "warning: inode #%x: data pointer + length > FFS total size, skipping\n", | |
124 ino); | |
125 free(inf); | |
126 return(0); | |
127 } | |
128 inf->dataptr = image + inf->offset; | |
129 } | |
130 inode_info[ino] = inf; | |
131 return(1); | |
132 } | |
133 | |
134 find_root_inode() | |
135 { | |
136 int ino; | |
137 | |
138 if (root_inode) { | |
139 if (!validate_inode(root_inode)) { | |
140 fprintf(stderr, | |
141 "error: root inode specified with -r is invalid\n"); | |
142 exit(1); | |
143 } | |
144 return(1); | |
145 } | |
146 for (ino = 1; ino < inode_limit; ino++) { | |
147 if (!validate_inode(ino)) | |
148 continue; | |
149 if (inode_info[ino]->type != 0xF2) | |
150 continue; | |
151 if (*inode_info[ino]->dataptr != '/') | |
152 continue; | |
153 root_inode = ino; | |
154 if (verbose) | |
155 fprintf(stderr, "Found root inode at #%x\n", ino); | |
156 if (inode_info[ino]->sibling) | |
157 fprintf(stderr, | |
158 "warning: root inode #%x has a non-null sibling pointer\n", | |
159 ino); | |
160 return(0); | |
161 } | |
162 fprintf(stderr, "error: no root inode found; try -r\n"); | |
163 exit(1); | |
164 } |