comparison ffstools/tiffs-rd/ls.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 the ls and lsino commands.
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10 #include "types.h"
11 #include "struct.h"
12 #include "globals.h"
13 #include "pathname.h"
14
15 static void
16 segment_size_callback(inf, opaque)
17 struct inode_info *inf;
18 u_long opaque;
19 {
20 size_t *accump = (size_t *) opaque;
21 struct chunkinfo chi;
22
23 size_extra_chunk(inf, &chi);
24 *accump += chi.len;
25 }
26
27 size_t
28 get_file_size(seghead_ino, deleted)
29 {
30 struct chunkinfo chi;
31 size_t accum;
32
33 size_head_chunk(inode_info[seghead_ino], &chi);
34 accum = chi.len;
35 iterate_seg_file(seghead_ino, segment_size_callback, (u_long) &accum,
36 deleted, 0);
37 return(accum);
38 }
39
40 static void
41 segment_ls_callback(inf, opaque)
42 struct inode_info *inf;
43 u_long opaque;
44 {
45 struct chunkinfo chi;
46
47 size_extra_chunk(inf, &chi);
48 if (verbose2 > 1)
49 printf("seg #%04x @%08x length=%lu\n", inf->ino, inf->offset,
50 (u_long) chi.len);
51 else
52 printf("seg #%04x length=%lu\n", inf->ino, (u_long) chi.len);
53 }
54
55 ls_seg_file(seghead_ino, deleted)
56 {
57 struct inode_info *inf = inode_info[seghead_ino];
58 struct chunkinfo chi;
59
60 size_head_chunk(inf, &chi);
61 printf("%lu bytes in seghead", (u_long) chi.len);
62 if (verbose2 > 1)
63 printf(", starting at offset %lx",
64 (u_long)(inf->byte_after_name - image));
65 putchar('\n');
66 iterate_seg_file(seghead_ino, segment_ls_callback, 0L, deleted,
67 verbose2 > 1);
68 }
69
70 void
71 ls_tree_callback(pathname, ino, depth)
72 char *pathname;
73 {
74 struct inode_info *inf = inode_info[ino];
75 u_long size;
76 char readonly;
77
78 if (inf->type & 0x10)
79 readonly = ' ';
80 else
81 readonly = 'r';
82 switch (inf->type) {
83 case 0xE1:
84 case 0xF1:
85 size = get_file_size(ino, 0);
86 printf("f%c %7lu %s\n", readonly, size, pathname);
87 if (verbose2)
88 ls_seg_file(ino, 0);
89 return;
90 case 0xE2:
91 case 0xF2:
92 printf("d%c %s\n", readonly, pathname);
93 return;
94 case 0xE3:
95 case 0xF3:
96 printf("l%c %s\n", readonly, pathname);
97 return;
98 default:
99 fprintf(stderr,
100 "BUG: bad inode byte %02X reached ls_tree_callback()\n",
101 inf->type);
102 exit(1);
103 }
104 }
105
106 ls_by_pathname(pathname)
107 char *pathname;
108 {
109 int ino;
110 struct inode_info *inf;
111 char *type;
112
113 printf("%s\n", pathname);
114 ino = find_pathname(pathname);
115 printf("inode #%x\n", ino);
116 inf = inode_info[ino];
117 switch (inf->type) {
118 case 0xE1:
119 type = "read-only file";
120 break;
121 case 0xF1:
122 type = "file";
123 break;
124 case 0xF2:
125 type = "directory";
126 break;
127 case 0xF3:
128 type = "symlink";
129 break;
130 default:
131 type = "???";
132 }
133 printf("object type %02X (%s)\n", inf->type, type);
134 if (!validate_obj_name(ino, ino == root_inode)) {
135 printf("No valid object name in the chunk!\n");
136 exit(1);
137 }
138 printf("object name: %s\n", inf->dataptr);
139 if (inf->type == 0xF1 || inf->type == 0xE1) {
140 printf("total size: %lu bytes\n",
141 (u_long) get_file_size(ino, 0));
142 if (verbose2)
143 ls_seg_file(ino, 0);
144 }
145 putchar('\n');
146 }
147
148 cmd_ls(argc, argv)
149 char **argv;
150 {
151 extern int optind;
152 int c;
153
154 read_ffs_image();
155 find_inode_block();
156 alloc_inode_table();
157 find_root_inode();
158
159 optind = 0;
160 while ((c = getopt(argc, argv, "v")) != EOF)
161 switch (c) {
162 case 'v':
163 verbose2++;
164 continue;
165 default:
166 fprintf(stderr, "usage: ls [-v[v]] [pathname...]\n");
167 exit(1);
168 }
169 if (optind >= argc) {
170 traverse_visible_tree(ls_tree_callback);
171 exit(0);
172 }
173 for (; optind < argc; optind++)
174 ls_by_pathname(argv[optind]);
175 exit(0);
176 }
177
178 lsino_all()
179 {
180 int ino, last_ino = 0;
181 struct inode_info *inf;
182 char pathname[PATHNAME_BUF_SIZE], typech;
183 int pathstat;
184 char descend_str[8], sibling_str[8];
185
186 for (ino = 1; ino < inode_limit; ino++) {
187 if (!validate_inode(ino))
188 continue;
189 if (ino != last_ino + 1)
190 printf("GAP in inode numbers\n");
191 inf = inode_info[ino];
192 pathstat = pathname_of_inode(ino, pathname);
193 if (pathstat < 0)
194 strcpy(pathname, "-nopath-");
195 switch (inf->type) {
196 case 0x00:
197 typech = '~';
198 break;
199 case 0xE1:
200 case 0xF1:
201 typech = 'f';
202 break;
203 case 0xF2:
204 typech = 'd';
205 break;
206 case 0xF3:
207 typech = 'l';
208 break;
209 case 0xF4:
210 typech = '.';
211 break;
212 default:
213 typech = '?';
214 }
215 printf("#%04x %c %s\n", ino, typech, pathname);
216 if (inf->type && !(inf->type & 0x10))
217 printf("\tread-only object\n");
218 if (ino == root_inode)
219 printf("\tactive root\n");
220 else if (inf->nparents < 1)
221 printf("\torphan\n");
222 else if (inf->nparents > 1)
223 printf("\tparent: #%x (%d)\n", inf->parent,
224 inf->nparents);
225 else if (pathstat < 0 || verbose2)
226 printf("\tparent: #%x\n", inf->parent);
227 if (verbose2 > 1) {
228 if (inf->descend)
229 sprintf(descend_str, "#%x", inf->descend);
230 else
231 strcpy(descend_str, "null");
232 if (inf->sibling)
233 sprintf(sibling_str, "#%x", inf->sibling);
234 else
235 strcpy(sibling_str, "null");
236 printf("\tchild: %s, sibling: %s\n",
237 descend_str, sibling_str);
238 }
239 if (!inf->len)
240 printf("\treclaimed\n");
241 last_ino = ino;
242 }
243 exit(0);
244 }
245
246 void
247 lsino_one(ino, assume_file)
248 {
249 struct inode_info *inf;
250 char pathname[PATHNAME_BUF_SIZE], *type;
251
252 if (!validate_inode(ino)) {
253 fprintf(stderr, "lsino: specified inode number is invalid\n");
254 exit(1);
255 }
256 printf("inode #%x\n", ino);
257 inf = inode_info[ino];
258 if (pathname_of_inode(ino, pathname) >= 0)
259 printf("Pathname: %s\n", pathname);
260 else
261 printf("No pathname found\n");
262 inf = inode_info[ino];
263 switch (inf->type) {
264 case 0x00:
265 type = "deleted";
266 break;
267 case 0xE1:
268 type = "read-only file";
269 break;
270 case 0xF1:
271 type = "file";
272 break;
273 case 0xF2:
274 type = "directory";
275 break;
276 case 0xF3:
277 type = "symlink";
278 break;
279 case 0xF4:
280 type = "segment";
281 break;
282 default:
283 type = "???";
284 }
285 printf("object type %02X (%s)\n", inf->type, type);
286 if (!inf->len) {
287 printf("This inode has been reclaimed\n\n");
288 return;
289 }
290 if (validate_obj_name(ino, 1))
291 printf("object name: %s\n", inf->dataptr);
292 else {
293 printf("No valid object name in the chunk\n\n");
294 return;
295 }
296 if (inf->type == 0xF1 || inf->type == 0xE1 ||
297 !inf->type && assume_file) {
298 printf("total size: %lu bytes\n",
299 (u_long) get_file_size(ino, !inf->type));
300 if (verbose2)
301 ls_seg_file(ino, !inf->type);
302 }
303 putchar('\n');
304 }
305
306 cmd_lsino(argc, argv)
307 char **argv;
308 {
309 extern int optind;
310 int c, assume_file = 0, ino;
311
312 read_ffs_image();
313 find_inode_block();
314 alloc_inode_table();
315 find_root_inode();
316 treewalk_all();
317
318 optind = 0;
319 while ((c = getopt(argc, argv, "fv")) != EOF)
320 switch (c) {
321 case 'f':
322 assume_file++;
323 continue;
324 case 'v':
325 verbose2++;
326 continue;
327 default:
328 fprintf(stderr, "usage: lsino [-v[v]] [ino...]\n");
329 exit(1);
330 }
331 if (optind >= argc)
332 return lsino_all();
333 for (; optind < argc; optind++) {
334 ino = strtoul(argv[optind], 0, 16);
335 lsino_one(ino, assume_file);
336 }
337 exit(0);
338 }