FreeCalypso > hg > freecalypso-sw
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 } |