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 }