comparison target-utils/libmpffs/basicfind.c @ 101:7029fe8ae0bc

pirexplore: FFS find command implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 02 Sep 2013 00:33:54 +0000
parents
children 7f75ffdd674f
comparison
equal deleted inserted replaced
100:02ece4d8c755 101:7029fe8ae0bc
1 #include <sys/types.h>
2 #include "types.h"
3 #include "struct.h"
4 #include "globals.h"
5 #include "macros.h"
6
7 extern char *index();
8
9 static u8 *
10 find_endofchunk(ino)
11 {
12 struct inode *irec = mpffs_active_index + ino;
13 u8 *p;
14 int i;
15
16 p = inode_to_dataptr(irec) + irec->len;
17 for (i = 0; i < 16; i++) {
18 p--;
19 if (!*p)
20 return(p);
21 if (*p != 0xFF)
22 break;
23 }
24 printf("Error: inode #%x has no valid termination\n", ino);
25 return(p); /* XXX */
26 }
27
28 static
29 find_named_child(start, seekname)
30 char *seekname;
31 {
32 int ino;
33 struct inode *irec;
34
35 for (ino = start; ino != 0xFFFF; ino = irec->sibling) {
36 irec = mpffs_active_index + ino;
37 if (!irec->type)
38 continue;
39 if (!strcmp(inode_to_dataptr(irec), seekname))
40 return(ino);
41 }
42 return(0);
43 }
44
45 mpffs_pathname_to_inode(pathname)
46 char *pathname;
47 {
48 int ino, stat;
49 struct inode *irec;
50 char *cur, *next;
51
52 stat = mpffs_init();
53 if (stat < 0)
54 return(stat);
55 cur = pathname;
56 if (*cur == '/')
57 cur++;
58 for (ino = mpffs_root_ino; cur; cur = next) {
59 if (!*cur)
60 break;
61 next = index(cur, '/');
62 if (next == cur) {
63 printf("malformed pathname: multiple adjacent slashes\n");
64 return(-1);
65 }
66 if (next)
67 *next++ = '\0';
68 irec = mpffs_active_index + ino;
69 if (irec->type != OBJTYPE_DIR) {
70 printf("Error: non-terminal non-directory\n");
71 if (next)
72 next[-1] = '/';
73 return(-1);
74 }
75 ino = find_named_child(irec->descend, cur);
76 if (next)
77 next[-1] = '/';
78 if (!ino) {
79 printf("Error: pathname component not found\n");
80 return(-1);
81 }
82 }
83 return(ino);
84 }
85
86 mpffs_find_file(pathname, startret, sizeret, continue_ret)
87 char *pathname;
88 u8 **startret;
89 size_t *sizeret;
90 int *continue_ret;
91 {
92 int ino, cont;
93 struct inode *irec;
94 u8 *start, *end;
95 size_t size;
96
97 ino = mpffs_pathname_to_inode(pathname);
98 if (ino <= 0)
99 return(-1);
100 irec = mpffs_active_index + ino;
101 if (irec->type != OBJTYPE_FILE) {
102 printf("Error: %s is not a regular file\n", pathname);
103 return(-1);
104 }
105 start = inode_to_dataptr(irec);
106 start += strlen(start) + 1;
107 end = find_endofchunk(ino);
108 size = end - start;
109 if (size < 0)
110 size = 0;
111 cont = irec->descend;
112 if (cont == 0xFFFF)
113 cont = 0;
114 if (startret)
115 *startret = start;
116 if (sizeret)
117 *sizeret = size;
118 if (continue_ret)
119 *continue_ret = cont;
120 return(0);
121 }
122
123 mpffs_get_segment(ino, startret, sizeret, continue_ret)
124 int ino;
125 u8 **startret;
126 size_t *sizeret;
127 int *continue_ret;
128 {
129 int cont;
130 struct inode *irec;
131 u8 *start, *end;
132 size_t size;
133
134 for (;;) {
135 irec = mpffs_active_index + ino;
136 if (irec->type)
137 break;
138 if (irec->sibling == 0xFFFF) {
139 printf("Error: segment inode #%d: deleted and no sibling\n",
140 ino);
141 return(-1);
142 }
143 ino = irec->sibling;
144 }
145 if (irec->type != OBJTYPE_SEGMENT) {
146 printf("Error: inode #%x is not a segment\n", ino);
147 return(-1);
148 }
149 start = inode_to_dataptr(irec);
150 end = find_endofchunk(ino);
151 size = end - start;
152 if (size <= 0) {
153 printf("Error: segment inode #%x: bad length\n", ino);
154 return(-1);
155 }
156 cont = irec->descend;
157 if (cont == 0xFFFF)
158 cont = 0;
159 if (startret)
160 *startret = start;
161 if (sizeret)
162 *sizeret = size;
163 if (continue_ret)
164 *continue_ret = cont;
165 return(0);
166 }