Blame


1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro
3 6f4d00ee 2013-09-23 0intro typedef struct MetaChunk MetaChunk;
4 6f4d00ee 2013-09-23 0intro
5 6f4d00ee 2013-09-23 0intro struct MetaChunk {
6 6f4d00ee 2013-09-23 0intro ushort offset;
7 6f4d00ee 2013-09-23 0intro ushort size;
8 6f4d00ee 2013-09-23 0intro ushort index;
9 6f4d00ee 2013-09-23 0intro };
10 6f4d00ee 2013-09-23 0intro
11 6f4d00ee 2013-09-23 0intro static int stringUnpack(char **s, uchar **p, int *n);
12 6f4d00ee 2013-09-23 0intro static int meCmp(MetaEntry*, char *s);
13 6f4d00ee 2013-09-23 0intro static int meCmpOld(MetaEntry*, char *s);
14 6f4d00ee 2013-09-23 0intro
15 6f4d00ee 2013-09-23 0intro
16 6f4d00ee 2013-09-23 0intro
17 6f4d00ee 2013-09-23 0intro static char EBadMeta[] = "corrupted meta data";
18 6f4d00ee 2013-09-23 0intro static char ENoFile[] = "file does not exist";
19 6f4d00ee 2013-09-23 0intro
20 6f4d00ee 2013-09-23 0intro /*
21 6f4d00ee 2013-09-23 0intro * integer conversion routines
22 6f4d00ee 2013-09-23 0intro */
23 6f4d00ee 2013-09-23 0intro #define U8GET(p) ((p)[0])
24 6f4d00ee 2013-09-23 0intro #define U16GET(p) (((p)[0]<<8)|(p)[1])
25 6f4d00ee 2013-09-23 0intro #define U32GET(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
26 6f4d00ee 2013-09-23 0intro #define U48GET(p) (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2))
27 6f4d00ee 2013-09-23 0intro #define U64GET(p) (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4))
28 6f4d00ee 2013-09-23 0intro
29 6f4d00ee 2013-09-23 0intro #define U8PUT(p,v) (p)[0]=(v)
30 6f4d00ee 2013-09-23 0intro #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
31 b29ebaab 2013-10-23 0intro #define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
32 6f4d00ee 2013-09-23 0intro #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
33 6f4d00ee 2013-09-23 0intro #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
34 6f4d00ee 2013-09-23 0intro
35 6f4d00ee 2013-09-23 0intro static int
36 6f4d00ee 2013-09-23 0intro stringUnpack(char **s, uchar **p, int *n)
37 6f4d00ee 2013-09-23 0intro {
38 6f4d00ee 2013-09-23 0intro int nn;
39 6f4d00ee 2013-09-23 0intro
40 6f4d00ee 2013-09-23 0intro if(*n < 2)
41 6f4d00ee 2013-09-23 0intro return 0;
42 6f4d00ee 2013-09-23 0intro
43 6f4d00ee 2013-09-23 0intro nn = U16GET(*p);
44 6f4d00ee 2013-09-23 0intro *p += 2;
45 6f4d00ee 2013-09-23 0intro *n -= 2;
46 6f4d00ee 2013-09-23 0intro if(nn > *n)
47 6f4d00ee 2013-09-23 0intro return 0;
48 4b576658 2013-09-23 0intro *s = vtmalloc(nn+1);
49 6f4d00ee 2013-09-23 0intro memmove(*s, *p, nn);
50 6f4d00ee 2013-09-23 0intro (*s)[nn] = 0;
51 6f4d00ee 2013-09-23 0intro *p += nn;
52 6f4d00ee 2013-09-23 0intro *n -= nn;
53 6f4d00ee 2013-09-23 0intro return 1;
54 6f4d00ee 2013-09-23 0intro }
55 6f4d00ee 2013-09-23 0intro
56 6f4d00ee 2013-09-23 0intro static int
57 6f4d00ee 2013-09-23 0intro stringPack(char *s, uchar *p)
58 6f4d00ee 2013-09-23 0intro {
59 6f4d00ee 2013-09-23 0intro int n;
60 6f4d00ee 2013-09-23 0intro
61 6f4d00ee 2013-09-23 0intro n = strlen(s);
62 6f4d00ee 2013-09-23 0intro U16PUT(p, n);
63 6f4d00ee 2013-09-23 0intro memmove(p+2, s, n);
64 6f4d00ee 2013-09-23 0intro return n+2;
65 6f4d00ee 2013-09-23 0intro }
66 6f4d00ee 2013-09-23 0intro
67 6f4d00ee 2013-09-23 0intro int
68 6f4d00ee 2013-09-23 0intro mbSearch(MetaBlock *mb, char *elem, int *ri, MetaEntry *me)
69 6f4d00ee 2013-09-23 0intro {
70 6f4d00ee 2013-09-23 0intro int i;
71 6f4d00ee 2013-09-23 0intro int b, t, x;
72 6f4d00ee 2013-09-23 0intro if(0)fprint(2, "mbSearch %s\n", elem);
73 6f4d00ee 2013-09-23 0intro
74 6f4d00ee 2013-09-23 0intro /* binary search within block */
75 6f4d00ee 2013-09-23 0intro b = 0;
76 6f4d00ee 2013-09-23 0intro t = mb->nindex;
77 6f4d00ee 2013-09-23 0intro while(b < t){
78 6f4d00ee 2013-09-23 0intro i = (b+t)>>1;
79 6f4d00ee 2013-09-23 0intro meUnpack(me, mb, i);
80 6f4d00ee 2013-09-23 0intro
81 6f4d00ee 2013-09-23 0intro if(mb->botch)
82 6f4d00ee 2013-09-23 0intro x = meCmpOld(me, elem);
83 6f4d00ee 2013-09-23 0intro else
84 6f4d00ee 2013-09-23 0intro x = meCmp(me, elem);
85 6f4d00ee 2013-09-23 0intro
86 6f4d00ee 2013-09-23 0intro if(x == 0){
87 6f4d00ee 2013-09-23 0intro *ri = i;
88 6f4d00ee 2013-09-23 0intro return 1;
89 6f4d00ee 2013-09-23 0intro }
90 6f4d00ee 2013-09-23 0intro
91 6f4d00ee 2013-09-23 0intro if(x < 0)
92 6f4d00ee 2013-09-23 0intro b = i+1;
93 6f4d00ee 2013-09-23 0intro else /* x > 0 */
94 6f4d00ee 2013-09-23 0intro t = i;
95 6f4d00ee 2013-09-23 0intro }
96 6f4d00ee 2013-09-23 0intro
97 6f4d00ee 2013-09-23 0intro assert(b == t);
98 6f4d00ee 2013-09-23 0intro
99 6f4d00ee 2013-09-23 0intro *ri = b; /* b is the index to insert this entry */
100 6f4d00ee 2013-09-23 0intro memset(me, 0, sizeof(*me));
101 6f4d00ee 2013-09-23 0intro
102 4b576658 2013-09-23 0intro werrstr(ENoFile);
103 6f4d00ee 2013-09-23 0intro return 0;
104 6f4d00ee 2013-09-23 0intro }
105 6f4d00ee 2013-09-23 0intro
106 6f4d00ee 2013-09-23 0intro void
107 6f4d00ee 2013-09-23 0intro mbInit(MetaBlock *mb, uchar *p, int n, int ne)
108 6f4d00ee 2013-09-23 0intro {
109 6f4d00ee 2013-09-23 0intro memset(p, 0, n);
110 6f4d00ee 2013-09-23 0intro mb->maxsize = n;
111 6f4d00ee 2013-09-23 0intro mb->maxindex = ne;
112 6f4d00ee 2013-09-23 0intro mb->nindex = 0;
113 6f4d00ee 2013-09-23 0intro mb->free = 0;
114 6f4d00ee 2013-09-23 0intro mb->size = MetaHeaderSize + ne*MetaIndexSize;
115 6f4d00ee 2013-09-23 0intro mb->buf = p;
116 6f4d00ee 2013-09-23 0intro mb->botch = 0;
117 6f4d00ee 2013-09-23 0intro }
118 6f4d00ee 2013-09-23 0intro
119 6f4d00ee 2013-09-23 0intro int
120 6f4d00ee 2013-09-23 0intro mbUnpack(MetaBlock *mb, uchar *p, int n)
121 6f4d00ee 2013-09-23 0intro {
122 6f4d00ee 2013-09-23 0intro u32int magic;
123 6f4d00ee 2013-09-23 0intro int i;
124 6f4d00ee 2013-09-23 0intro int eo, en, omin;
125 6f4d00ee 2013-09-23 0intro uchar *q;
126 6f4d00ee 2013-09-23 0intro
127 6f4d00ee 2013-09-23 0intro mb->maxsize = n;
128 6f4d00ee 2013-09-23 0intro mb->buf = p;
129 6f4d00ee 2013-09-23 0intro
130 6f4d00ee 2013-09-23 0intro if(n == 0){
131 6f4d00ee 2013-09-23 0intro memset(mb, 0, sizeof(MetaBlock));
132 6f4d00ee 2013-09-23 0intro return 1;
133 6f4d00ee 2013-09-23 0intro }
134 6f4d00ee 2013-09-23 0intro
135 6f4d00ee 2013-09-23 0intro magic = U32GET(p);
136 6f4d00ee 2013-09-23 0intro if(magic != MetaMagic && magic != MetaMagic-1)
137 6f4d00ee 2013-09-23 0intro goto Err;
138 6f4d00ee 2013-09-23 0intro mb->size = U16GET(p+4);
139 6f4d00ee 2013-09-23 0intro mb->free = U16GET(p+6);
140 6f4d00ee 2013-09-23 0intro mb->maxindex = U16GET(p+8);
141 6f4d00ee 2013-09-23 0intro mb->nindex = U16GET(p+10);
142 6f4d00ee 2013-09-23 0intro mb->botch = magic != MetaMagic;
143 6f4d00ee 2013-09-23 0intro if(mb->size > n)
144 6f4d00ee 2013-09-23 0intro goto Err;
145 6f4d00ee 2013-09-23 0intro
146 6f4d00ee 2013-09-23 0intro omin = MetaHeaderSize + mb->maxindex*MetaIndexSize;
147 6f4d00ee 2013-09-23 0intro if(n < omin)
148 6f4d00ee 2013-09-23 0intro goto Err;
149 6f4d00ee 2013-09-23 0intro
150 6f4d00ee 2013-09-23 0intro
151 6f4d00ee 2013-09-23 0intro p += MetaHeaderSize;
152 6f4d00ee 2013-09-23 0intro
153 6f4d00ee 2013-09-23 0intro /* check the index table - ensures that meUnpack and meCmp never fail */
154 6f4d00ee 2013-09-23 0intro for(i=0; i<mb->nindex; i++){
155 6f4d00ee 2013-09-23 0intro eo = U16GET(p);
156 6f4d00ee 2013-09-23 0intro en = U16GET(p+2);
157 6f4d00ee 2013-09-23 0intro if(eo < omin || eo+en > mb->size || en < 8)
158 6f4d00ee 2013-09-23 0intro goto Err;
159 6f4d00ee 2013-09-23 0intro q = mb->buf + eo;
160 6f4d00ee 2013-09-23 0intro if(U32GET(q) != DirMagic)
161 6f4d00ee 2013-09-23 0intro goto Err;
162 6f4d00ee 2013-09-23 0intro p += 4;
163 6f4d00ee 2013-09-23 0intro }
164 6f4d00ee 2013-09-23 0intro
165 6f4d00ee 2013-09-23 0intro return 1;
166 6f4d00ee 2013-09-23 0intro Err:
167 4b576658 2013-09-23 0intro werrstr(EBadMeta);
168 6f4d00ee 2013-09-23 0intro return 0;
169 6f4d00ee 2013-09-23 0intro }
170 6f4d00ee 2013-09-23 0intro
171 6f4d00ee 2013-09-23 0intro
172 6f4d00ee 2013-09-23 0intro void
173 6f4d00ee 2013-09-23 0intro mbPack(MetaBlock *mb)
174 6f4d00ee 2013-09-23 0intro {
175 6f4d00ee 2013-09-23 0intro uchar *p;
176 6f4d00ee 2013-09-23 0intro
177 6f4d00ee 2013-09-23 0intro p = mb->buf;
178 6f4d00ee 2013-09-23 0intro
179 6f4d00ee 2013-09-23 0intro assert(!mb->botch);
180 6f4d00ee 2013-09-23 0intro
181 6f4d00ee 2013-09-23 0intro U32PUT(p, MetaMagic);
182 6f4d00ee 2013-09-23 0intro U16PUT(p+4, mb->size);
183 6f4d00ee 2013-09-23 0intro U16PUT(p+6, mb->free);
184 6f4d00ee 2013-09-23 0intro U16PUT(p+8, mb->maxindex);
185 6f4d00ee 2013-09-23 0intro U16PUT(p+10, mb->nindex);
186 6f4d00ee 2013-09-23 0intro }
187 6f4d00ee 2013-09-23 0intro
188 6f4d00ee 2013-09-23 0intro
189 6f4d00ee 2013-09-23 0intro void
190 6f4d00ee 2013-09-23 0intro mbDelete(MetaBlock *mb, int i)
191 6f4d00ee 2013-09-23 0intro {
192 6f4d00ee 2013-09-23 0intro uchar *p;
193 6f4d00ee 2013-09-23 0intro int n;
194 6f4d00ee 2013-09-23 0intro MetaEntry me;
195 6f4d00ee 2013-09-23 0intro
196 6f4d00ee 2013-09-23 0intro assert(i < mb->nindex);
197 6f4d00ee 2013-09-23 0intro meUnpack(&me, mb, i);
198 6f4d00ee 2013-09-23 0intro memset(me.p, 0, me.size);
199 6f4d00ee 2013-09-23 0intro
200 6f4d00ee 2013-09-23 0intro if(me.p - mb->buf + me.size == mb->size)
201 6f4d00ee 2013-09-23 0intro mb->size -= me.size;
202 6f4d00ee 2013-09-23 0intro else
203 6f4d00ee 2013-09-23 0intro mb->free += me.size;
204 6f4d00ee 2013-09-23 0intro
205 6f4d00ee 2013-09-23 0intro p = mb->buf + MetaHeaderSize + i*MetaIndexSize;
206 6f4d00ee 2013-09-23 0intro n = (mb->nindex-i-1)*MetaIndexSize;
207 6f4d00ee 2013-09-23 0intro memmove(p, p+MetaIndexSize, n);
208 6f4d00ee 2013-09-23 0intro memset(p+n, 0, MetaIndexSize);
209 6f4d00ee 2013-09-23 0intro mb->nindex--;
210 6f4d00ee 2013-09-23 0intro }
211 6f4d00ee 2013-09-23 0intro
212 6f4d00ee 2013-09-23 0intro void
213 6f4d00ee 2013-09-23 0intro mbInsert(MetaBlock *mb, int i, MetaEntry *me)
214 6f4d00ee 2013-09-23 0intro {
215 6f4d00ee 2013-09-23 0intro uchar *p;
216 6f4d00ee 2013-09-23 0intro int o, n;
217 6f4d00ee 2013-09-23 0intro
218 6f4d00ee 2013-09-23 0intro assert(mb->nindex < mb->maxindex);
219 6f4d00ee 2013-09-23 0intro
220 6f4d00ee 2013-09-23 0intro o = me->p - mb->buf;
221 6f4d00ee 2013-09-23 0intro n = me->size;
222 6f4d00ee 2013-09-23 0intro if(o+n > mb->size){
223 6f4d00ee 2013-09-23 0intro mb->free -= mb->size - o;
224 6f4d00ee 2013-09-23 0intro mb->size = o + n;
225 6f4d00ee 2013-09-23 0intro }else
226 6f4d00ee 2013-09-23 0intro mb->free -= n;
227 6f4d00ee 2013-09-23 0intro
228 6f4d00ee 2013-09-23 0intro p = mb->buf + MetaHeaderSize + i*MetaIndexSize;
229 6f4d00ee 2013-09-23 0intro n = (mb->nindex-i)*MetaIndexSize;
230 6f4d00ee 2013-09-23 0intro memmove(p+MetaIndexSize, p, n);
231 6f4d00ee 2013-09-23 0intro U16PUT(p, me->p - mb->buf);
232 6f4d00ee 2013-09-23 0intro U16PUT(p+2, me->size);
233 6f4d00ee 2013-09-23 0intro mb->nindex++;
234 6f4d00ee 2013-09-23 0intro }
235 6f4d00ee 2013-09-23 0intro
236 6f4d00ee 2013-09-23 0intro int
237 6f4d00ee 2013-09-23 0intro mbResize(MetaBlock *mb, MetaEntry *me, int n)
238 6f4d00ee 2013-09-23 0intro {
239 6f4d00ee 2013-09-23 0intro uchar *p, *ep;
240 6f4d00ee 2013-09-23 0intro
241 6f4d00ee 2013-09-23 0intro /* easy case */
242 6f4d00ee 2013-09-23 0intro if(n <= me->size){
243 6f4d00ee 2013-09-23 0intro me->size = n;
244 6f4d00ee 2013-09-23 0intro return 1;
245 6f4d00ee 2013-09-23 0intro }
246 6f4d00ee 2013-09-23 0intro
247 6f4d00ee 2013-09-23 0intro /* try and expand entry */
248 6f4d00ee 2013-09-23 0intro
249 6f4d00ee 2013-09-23 0intro p = me->p + me->size;
250 6f4d00ee 2013-09-23 0intro ep = mb->buf + mb->maxsize;
251 6f4d00ee 2013-09-23 0intro while(p < ep && *p == 0)
252 6f4d00ee 2013-09-23 0intro p++;
253 6f4d00ee 2013-09-23 0intro if(n <= p - me->p){
254 6f4d00ee 2013-09-23 0intro me->size = n;
255 6f4d00ee 2013-09-23 0intro return 1;
256 6f4d00ee 2013-09-23 0intro }
257 6f4d00ee 2013-09-23 0intro
258 6f4d00ee 2013-09-23 0intro p = mbAlloc(mb, n);
259 6f4d00ee 2013-09-23 0intro if(p != nil){
260 6f4d00ee 2013-09-23 0intro me->p = p;
261 6f4d00ee 2013-09-23 0intro me->size = n;
262 6f4d00ee 2013-09-23 0intro return 1;
263 6f4d00ee 2013-09-23 0intro }
264 6f4d00ee 2013-09-23 0intro
265 6f4d00ee 2013-09-23 0intro return 0;
266 6f4d00ee 2013-09-23 0intro }
267 6f4d00ee 2013-09-23 0intro
268 6f4d00ee 2013-09-23 0intro void
269 6f4d00ee 2013-09-23 0intro meUnpack(MetaEntry *me, MetaBlock *mb, int i)
270 6f4d00ee 2013-09-23 0intro {
271 6f4d00ee 2013-09-23 0intro uchar *p;
272 6f4d00ee 2013-09-23 0intro int eo, en;
273 6f4d00ee 2013-09-23 0intro
274 6f4d00ee 2013-09-23 0intro assert(i >= 0 && i < mb->nindex);
275 6f4d00ee 2013-09-23 0intro
276 6f4d00ee 2013-09-23 0intro p = mb->buf + MetaHeaderSize + i*MetaIndexSize;
277 6f4d00ee 2013-09-23 0intro eo = U16GET(p);
278 6f4d00ee 2013-09-23 0intro en = U16GET(p+2);
279 6f4d00ee 2013-09-23 0intro
280 6f4d00ee 2013-09-23 0intro me->p = mb->buf + eo;
281 6f4d00ee 2013-09-23 0intro me->size = en;
282 6f4d00ee 2013-09-23 0intro
283 6f4d00ee 2013-09-23 0intro /* checked by mbUnpack */
284 6f4d00ee 2013-09-23 0intro assert(me->size >= 8);
285 6f4d00ee 2013-09-23 0intro }
286 6f4d00ee 2013-09-23 0intro
287 6f4d00ee 2013-09-23 0intro /* assumes a small amount of checking has been done in mbEntry */
288 6f4d00ee 2013-09-23 0intro static int
289 6f4d00ee 2013-09-23 0intro meCmp(MetaEntry *me, char *s)
290 6f4d00ee 2013-09-23 0intro {
291 6f4d00ee 2013-09-23 0intro int n;
292 6f4d00ee 2013-09-23 0intro uchar *p;
293 6f4d00ee 2013-09-23 0intro
294 6f4d00ee 2013-09-23 0intro p = me->p;
295 6f4d00ee 2013-09-23 0intro
296 6f4d00ee 2013-09-23 0intro /* skip magic & version */
297 6f4d00ee 2013-09-23 0intro p += 6;
298 6f4d00ee 2013-09-23 0intro n = U16GET(p);
299 6f4d00ee 2013-09-23 0intro p += 2;
300 6f4d00ee 2013-09-23 0intro
301 6f4d00ee 2013-09-23 0intro if(n > me->size - 8)
302 6f4d00ee 2013-09-23 0intro n = me->size - 8;
303 6f4d00ee 2013-09-23 0intro
304 6f4d00ee 2013-09-23 0intro while(n > 0){
305 6f4d00ee 2013-09-23 0intro if(*s == 0)
306 6f4d00ee 2013-09-23 0intro return 1;
307 6f4d00ee 2013-09-23 0intro if(*p < (uchar)*s)
308 6f4d00ee 2013-09-23 0intro return -1;
309 6f4d00ee 2013-09-23 0intro if(*p > (uchar)*s)
310 6f4d00ee 2013-09-23 0intro return 1;
311 6f4d00ee 2013-09-23 0intro p++;
312 6f4d00ee 2013-09-23 0intro s++;
313 6f4d00ee 2013-09-23 0intro n--;
314 6f4d00ee 2013-09-23 0intro }
315 6f4d00ee 2013-09-23 0intro return -(*s != 0);
316 6f4d00ee 2013-09-23 0intro }
317 6f4d00ee 2013-09-23 0intro
318 6f4d00ee 2013-09-23 0intro /*
319 6f4d00ee 2013-09-23 0intro * This is the old and broken meCmp.
320 6f4d00ee 2013-09-23 0intro * This cmp routine reverse the sense of the comparison
321 6f4d00ee 2013-09-23 0intro * when one string is a prefix of the other.
322 6f4d00ee 2013-09-23 0intro * In other words, it put "ab" after "abc" rather
323 6f4d00ee 2013-09-23 0intro * than before. This behaviour is ok; binary search
324 6f4d00ee 2013-09-23 0intro * and sort still work. However, it is goes against
325 6f4d00ee 2013-09-23 0intro * the usual convention.
326 6f4d00ee 2013-09-23 0intro */
327 6f4d00ee 2013-09-23 0intro static int
328 6f4d00ee 2013-09-23 0intro meCmpOld(MetaEntry *me, char *s)
329 6f4d00ee 2013-09-23 0intro {
330 6f4d00ee 2013-09-23 0intro int n;
331 6f4d00ee 2013-09-23 0intro uchar *p;
332 6f4d00ee 2013-09-23 0intro
333 6f4d00ee 2013-09-23 0intro p = me->p;
334 6f4d00ee 2013-09-23 0intro
335 6f4d00ee 2013-09-23 0intro /* skip magic & version */
336 6f4d00ee 2013-09-23 0intro p += 6;
337 6f4d00ee 2013-09-23 0intro n = U16GET(p);
338 6f4d00ee 2013-09-23 0intro p += 2;
339 6f4d00ee 2013-09-23 0intro
340 6f4d00ee 2013-09-23 0intro if(n > me->size - 8)
341 6f4d00ee 2013-09-23 0intro n = me->size - 8;
342 6f4d00ee 2013-09-23 0intro
343 6f4d00ee 2013-09-23 0intro while(n > 0){
344 6f4d00ee 2013-09-23 0intro if(*s == 0)
345 6f4d00ee 2013-09-23 0intro return -1;
346 6f4d00ee 2013-09-23 0intro if(*p < (uchar)*s)
347 6f4d00ee 2013-09-23 0intro return -1;
348 6f4d00ee 2013-09-23 0intro if(*p > (uchar)*s)
349 6f4d00ee 2013-09-23 0intro return 1;
350 6f4d00ee 2013-09-23 0intro p++;
351 6f4d00ee 2013-09-23 0intro s++;
352 6f4d00ee 2013-09-23 0intro n--;
353 6f4d00ee 2013-09-23 0intro }
354 6f4d00ee 2013-09-23 0intro return *s != 0;
355 6f4d00ee 2013-09-23 0intro }
356 6f4d00ee 2013-09-23 0intro
357 6f4d00ee 2013-09-23 0intro static int
358 b29ebaab 2013-10-23 0intro offsetCmp(const void *s0, const void *s1)
359 6f4d00ee 2013-09-23 0intro {
360 6f4d00ee 2013-09-23 0intro MetaChunk *mc0, *mc1;
361 6f4d00ee 2013-09-23 0intro
362 b29ebaab 2013-10-23 0intro mc0 = (MetaChunk*)s0;
363 b29ebaab 2013-10-23 0intro mc1 = (MetaChunk*)s1;
364 6f4d00ee 2013-09-23 0intro if(mc0->offset < mc1->offset)
365 6f4d00ee 2013-09-23 0intro return -1;
366 6f4d00ee 2013-09-23 0intro if(mc0->offset > mc1->offset)
367 6f4d00ee 2013-09-23 0intro return 1;
368 6f4d00ee 2013-09-23 0intro return 0;
369 6f4d00ee 2013-09-23 0intro }
370 6f4d00ee 2013-09-23 0intro
371 6f4d00ee 2013-09-23 0intro static MetaChunk *
372 6f4d00ee 2013-09-23 0intro metaChunks(MetaBlock *mb)
373 6f4d00ee 2013-09-23 0intro {
374 6f4d00ee 2013-09-23 0intro MetaChunk *mc;
375 6f4d00ee 2013-09-23 0intro int oo, o, n, i;
376 6f4d00ee 2013-09-23 0intro uchar *p;
377 6f4d00ee 2013-09-23 0intro
378 4b576658 2013-09-23 0intro mc = vtmalloc(mb->nindex*sizeof(MetaChunk));
379 6f4d00ee 2013-09-23 0intro p = mb->buf + MetaHeaderSize;
380 6f4d00ee 2013-09-23 0intro for(i = 0; i<mb->nindex; i++){
381 6f4d00ee 2013-09-23 0intro mc[i].offset = U16GET(p);
382 6f4d00ee 2013-09-23 0intro mc[i].size = U16GET(p+2);
383 6f4d00ee 2013-09-23 0intro mc[i].index = i;
384 6f4d00ee 2013-09-23 0intro p += MetaIndexSize;
385 6f4d00ee 2013-09-23 0intro }
386 6f4d00ee 2013-09-23 0intro
387 6f4d00ee 2013-09-23 0intro qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);
388 6f4d00ee 2013-09-23 0intro
389 6f4d00ee 2013-09-23 0intro /* check block looks ok */
390 6f4d00ee 2013-09-23 0intro oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
391 6f4d00ee 2013-09-23 0intro o = oo;
392 6f4d00ee 2013-09-23 0intro n = 0;
393 6f4d00ee 2013-09-23 0intro for(i=0; i<mb->nindex; i++){
394 6f4d00ee 2013-09-23 0intro o = mc[i].offset;
395 6f4d00ee 2013-09-23 0intro n = mc[i].size;
396 6f4d00ee 2013-09-23 0intro if(o < oo)
397 6f4d00ee 2013-09-23 0intro goto Err;
398 6f4d00ee 2013-09-23 0intro oo += n;
399 6f4d00ee 2013-09-23 0intro }
400 6f4d00ee 2013-09-23 0intro if(o+n > mb->size)
401 6f4d00ee 2013-09-23 0intro goto Err;
402 6f4d00ee 2013-09-23 0intro if(mb->size - oo != mb->free)
403 6f4d00ee 2013-09-23 0intro goto Err;
404 6f4d00ee 2013-09-23 0intro
405 6f4d00ee 2013-09-23 0intro return mc;
406 6f4d00ee 2013-09-23 0intro Err:
407 6f4d00ee 2013-09-23 0intro fprint(2, "metaChunks failed!\n");
408 6f4d00ee 2013-09-23 0intro oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
409 6f4d00ee 2013-09-23 0intro for(i=0; i<mb->nindex; i++){
410 6f4d00ee 2013-09-23 0intro fprint(2, "\t%d: %d %d\n", i, mc[i].offset, mc[i].offset + mc[i].size);
411 6f4d00ee 2013-09-23 0intro oo += mc[i].size;
412 6f4d00ee 2013-09-23 0intro }
413 6f4d00ee 2013-09-23 0intro fprint(2, "\tused=%d size=%d free=%d free2=%d\n", oo, mb->size, mb->free, mb->size - oo);
414 4b576658 2013-09-23 0intro werrstr(EBadMeta);
415 4b576658 2013-09-23 0intro vtfree(mc);
416 6f4d00ee 2013-09-23 0intro return nil;
417 6f4d00ee 2013-09-23 0intro }
418 6f4d00ee 2013-09-23 0intro
419 6f4d00ee 2013-09-23 0intro static void
420 6f4d00ee 2013-09-23 0intro mbCompact(MetaBlock *mb, MetaChunk *mc)
421 6f4d00ee 2013-09-23 0intro {
422 6f4d00ee 2013-09-23 0intro int oo, o, n, i;
423 6f4d00ee 2013-09-23 0intro
424 6f4d00ee 2013-09-23 0intro oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
425 6f4d00ee 2013-09-23 0intro
426 6f4d00ee 2013-09-23 0intro for(i=0; i<mb->nindex; i++){
427 6f4d00ee 2013-09-23 0intro o = mc[i].offset;
428 6f4d00ee 2013-09-23 0intro n = mc[i].size;
429 6f4d00ee 2013-09-23 0intro if(o != oo){
430 6f4d00ee 2013-09-23 0intro memmove(mb->buf + oo, mb->buf + o, n);
431 6f4d00ee 2013-09-23 0intro U16PUT(mb->buf + MetaHeaderSize + mc[i].index*MetaIndexSize, oo);
432 6f4d00ee 2013-09-23 0intro }
433 6f4d00ee 2013-09-23 0intro oo += n;
434 6f4d00ee 2013-09-23 0intro }
435 6f4d00ee 2013-09-23 0intro
436 6f4d00ee 2013-09-23 0intro mb->size = oo;
437 6f4d00ee 2013-09-23 0intro mb->free = 0;
438 6f4d00ee 2013-09-23 0intro }
439 6f4d00ee 2013-09-23 0intro
440 6f4d00ee 2013-09-23 0intro uchar *
441 6f4d00ee 2013-09-23 0intro mbAlloc(MetaBlock *mb, int n)
442 6f4d00ee 2013-09-23 0intro {
443 6f4d00ee 2013-09-23 0intro int i, o;
444 6f4d00ee 2013-09-23 0intro MetaChunk *mc;
445 6f4d00ee 2013-09-23 0intro
446 6f4d00ee 2013-09-23 0intro /* off the end */
447 6f4d00ee 2013-09-23 0intro if(mb->maxsize - mb->size >= n)
448 6f4d00ee 2013-09-23 0intro return mb->buf + mb->size;
449 6f4d00ee 2013-09-23 0intro
450 6f4d00ee 2013-09-23 0intro /* check if possible */
451 6f4d00ee 2013-09-23 0intro if(mb->maxsize - mb->size + mb->free < n)
452 6f4d00ee 2013-09-23 0intro return nil;
453 6f4d00ee 2013-09-23 0intro
454 6f4d00ee 2013-09-23 0intro mc = metaChunks(mb);
455 6f4d00ee 2013-09-23 0intro if(mc == nil){
456 6f4d00ee 2013-09-23 0intro fprint(2, "mbAlloc: metaChunks failed: %r\n");
457 6f4d00ee 2013-09-23 0intro return nil;
458 6f4d00ee 2013-09-23 0intro }
459 6f4d00ee 2013-09-23 0intro
460 6f4d00ee 2013-09-23 0intro /* look for hole */
461 6f4d00ee 2013-09-23 0intro o = MetaHeaderSize + mb->maxindex*MetaIndexSize;
462 6f4d00ee 2013-09-23 0intro for(i=0; i<mb->nindex; i++){
463 6f4d00ee 2013-09-23 0intro if(mc[i].offset - o >= n){
464 4b576658 2013-09-23 0intro vtfree(mc);
465 6f4d00ee 2013-09-23 0intro return mb->buf + o;
466 6f4d00ee 2013-09-23 0intro }
467 6f4d00ee 2013-09-23 0intro o = mc[i].offset + mc[i].size;
468 6f4d00ee 2013-09-23 0intro }
469 6f4d00ee 2013-09-23 0intro
470 6f4d00ee 2013-09-23 0intro if(mb->maxsize - o >= n){
471 4b576658 2013-09-23 0intro vtfree(mc);
472 6f4d00ee 2013-09-23 0intro return mb->buf + o;
473 6f4d00ee 2013-09-23 0intro }
474 6f4d00ee 2013-09-23 0intro
475 6f4d00ee 2013-09-23 0intro /* compact and return off the end */
476 6f4d00ee 2013-09-23 0intro mbCompact(mb, mc);
477 4b576658 2013-09-23 0intro vtfree(mc);
478 6f4d00ee 2013-09-23 0intro
479 6f4d00ee 2013-09-23 0intro if(mb->maxsize - mb->size < n){
480 4b576658 2013-09-23 0intro werrstr(EBadMeta);
481 6f4d00ee 2013-09-23 0intro return nil;
482 6f4d00ee 2013-09-23 0intro }
483 6f4d00ee 2013-09-23 0intro return mb->buf + mb->size;
484 6f4d00ee 2013-09-23 0intro }
485 6f4d00ee 2013-09-23 0intro
486 6f4d00ee 2013-09-23 0intro int
487 6f4d00ee 2013-09-23 0intro deSize(DirEntry *dir)
488 6f4d00ee 2013-09-23 0intro {
489 6f4d00ee 2013-09-23 0intro int n;
490 6f4d00ee 2013-09-23 0intro
491 6f4d00ee 2013-09-23 0intro /* constant part */
492 6f4d00ee 2013-09-23 0intro
493 6f4d00ee 2013-09-23 0intro n = 4 + /* magic */
494 6f4d00ee 2013-09-23 0intro 2 + /* version */
495 6f4d00ee 2013-09-23 0intro 4 + /* entry */
496 6f4d00ee 2013-09-23 0intro 4 + /* guid */
497 6f4d00ee 2013-09-23 0intro 4 + /* mentry */
498 6f4d00ee 2013-09-23 0intro 4 + /* mgen */
499 6f4d00ee 2013-09-23 0intro 8 + /* qid */
500 6f4d00ee 2013-09-23 0intro 4 + /* mtime */
501 6f4d00ee 2013-09-23 0intro 4 + /* mcount */
502 6f4d00ee 2013-09-23 0intro 4 + /* ctime */
503 6f4d00ee 2013-09-23 0intro 4 + /* atime */
504 6f4d00ee 2013-09-23 0intro 4 + /* mode */
505 6f4d00ee 2013-09-23 0intro 0;
506 6f4d00ee 2013-09-23 0intro
507 6f4d00ee 2013-09-23 0intro /* strings */
508 6f4d00ee 2013-09-23 0intro n += 2 + strlen(dir->elem);
509 6f4d00ee 2013-09-23 0intro n += 2 + strlen(dir->uid);
510 6f4d00ee 2013-09-23 0intro n += 2 + strlen(dir->gid);
511 6f4d00ee 2013-09-23 0intro n += 2 + strlen(dir->mid);
512 6f4d00ee 2013-09-23 0intro
513 6f4d00ee 2013-09-23 0intro /* optional sections */
514 6f4d00ee 2013-09-23 0intro if(dir->qidSpace){
515 6f4d00ee 2013-09-23 0intro n += 3 + /* option header */
516 6f4d00ee 2013-09-23 0intro 8 + /* qidOffset */
517 6f4d00ee 2013-09-23 0intro 8; /* qid Max */
518 6f4d00ee 2013-09-23 0intro }
519 6f4d00ee 2013-09-23 0intro
520 6f4d00ee 2013-09-23 0intro return n;
521 6f4d00ee 2013-09-23 0intro }
522 6f4d00ee 2013-09-23 0intro
523 6f4d00ee 2013-09-23 0intro void
524 6f4d00ee 2013-09-23 0intro dePack(DirEntry *dir, MetaEntry *me)
525 6f4d00ee 2013-09-23 0intro {
526 6f4d00ee 2013-09-23 0intro uchar *p;
527 6f4d00ee 2013-09-23 0intro ulong t32;
528 6f4d00ee 2013-09-23 0intro
529 6f4d00ee 2013-09-23 0intro p = me->p;
530 6f4d00ee 2013-09-23 0intro
531 6f4d00ee 2013-09-23 0intro U32PUT(p, DirMagic);
532 6f4d00ee 2013-09-23 0intro U16PUT(p+4, 9); /* version */
533 6f4d00ee 2013-09-23 0intro p += 6;
534 6f4d00ee 2013-09-23 0intro
535 6f4d00ee 2013-09-23 0intro p += stringPack(dir->elem, p);
536 6f4d00ee 2013-09-23 0intro
537 6f4d00ee 2013-09-23 0intro U32PUT(p, dir->entry);
538 6f4d00ee 2013-09-23 0intro U32PUT(p+4, dir->gen);
539 6f4d00ee 2013-09-23 0intro U32PUT(p+8, dir->mentry);
540 6f4d00ee 2013-09-23 0intro U32PUT(p+12, dir->mgen);
541 6f4d00ee 2013-09-23 0intro U64PUT(p+16, dir->qid, t32);
542 6f4d00ee 2013-09-23 0intro p += 24;
543 6f4d00ee 2013-09-23 0intro
544 6f4d00ee 2013-09-23 0intro p += stringPack(dir->uid, p);
545 6f4d00ee 2013-09-23 0intro p += stringPack(dir->gid, p);
546 6f4d00ee 2013-09-23 0intro p += stringPack(dir->mid, p);
547 6f4d00ee 2013-09-23 0intro
548 6f4d00ee 2013-09-23 0intro U32PUT(p, dir->mtime);
549 6f4d00ee 2013-09-23 0intro U32PUT(p+4, dir->mcount);
550 6f4d00ee 2013-09-23 0intro U32PUT(p+8, dir->ctime);
551 6f4d00ee 2013-09-23 0intro U32PUT(p+12, dir->atime);
552 6f4d00ee 2013-09-23 0intro U32PUT(p+16, dir->mode);
553 6f4d00ee 2013-09-23 0intro p += 5*4;
554 6f4d00ee 2013-09-23 0intro
555 6f4d00ee 2013-09-23 0intro if(dir->qidSpace){
556 6f4d00ee 2013-09-23 0intro U8PUT(p, DeQidSpace);
557 6f4d00ee 2013-09-23 0intro U16PUT(p+1, 2*8);
558 6f4d00ee 2013-09-23 0intro p += 3;
559 6f4d00ee 2013-09-23 0intro U64PUT(p, dir->qidOffset, t32);
560 6f4d00ee 2013-09-23 0intro U64PUT(p+8, dir->qidMax, t32);
561 6f4d00ee 2013-09-23 0intro p += 16;
562 6f4d00ee 2013-09-23 0intro }
563 6f4d00ee 2013-09-23 0intro
564 6f4d00ee 2013-09-23 0intro assert(p == me->p + me->size);
565 6f4d00ee 2013-09-23 0intro }
566 6f4d00ee 2013-09-23 0intro
567 6f4d00ee 2013-09-23 0intro
568 6f4d00ee 2013-09-23 0intro int
569 6f4d00ee 2013-09-23 0intro deUnpack(DirEntry *dir, MetaEntry *me)
570 6f4d00ee 2013-09-23 0intro {
571 6f4d00ee 2013-09-23 0intro int t, nn, n, version;
572 6f4d00ee 2013-09-23 0intro uchar *p;
573 6f4d00ee 2013-09-23 0intro
574 6f4d00ee 2013-09-23 0intro p = me->p;
575 6f4d00ee 2013-09-23 0intro n = me->size;
576 6f4d00ee 2013-09-23 0intro
577 6f4d00ee 2013-09-23 0intro memset(dir, 0, sizeof(DirEntry));
578 6f4d00ee 2013-09-23 0intro
579 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack\n");
580 6f4d00ee 2013-09-23 0intro /* magic */
581 6f4d00ee 2013-09-23 0intro if(n < 4 || U32GET(p) != DirMagic)
582 6f4d00ee 2013-09-23 0intro goto Err;
583 6f4d00ee 2013-09-23 0intro p += 4;
584 6f4d00ee 2013-09-23 0intro n -= 4;
585 6f4d00ee 2013-09-23 0intro
586 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got magic\n");
587 6f4d00ee 2013-09-23 0intro /* version */
588 6f4d00ee 2013-09-23 0intro if(n < 2)
589 6f4d00ee 2013-09-23 0intro goto Err;
590 6f4d00ee 2013-09-23 0intro version = U16GET(p);
591 6f4d00ee 2013-09-23 0intro if(version < 7 || version > 9)
592 6f4d00ee 2013-09-23 0intro goto Err;
593 6f4d00ee 2013-09-23 0intro p += 2;
594 6f4d00ee 2013-09-23 0intro n -= 2;
595 6f4d00ee 2013-09-23 0intro
596 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got version\n");
597 6f4d00ee 2013-09-23 0intro
598 6f4d00ee 2013-09-23 0intro /* elem */
599 6f4d00ee 2013-09-23 0intro if(!stringUnpack(&dir->elem, &p, &n))
600 6f4d00ee 2013-09-23 0intro goto Err;
601 6f4d00ee 2013-09-23 0intro
602 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got elem\n");
603 6f4d00ee 2013-09-23 0intro
604 6f4d00ee 2013-09-23 0intro /* entry */
605 6f4d00ee 2013-09-23 0intro if(n < 4)
606 6f4d00ee 2013-09-23 0intro goto Err;
607 6f4d00ee 2013-09-23 0intro dir->entry = U32GET(p);
608 6f4d00ee 2013-09-23 0intro p += 4;
609 6f4d00ee 2013-09-23 0intro n -= 4;
610 6f4d00ee 2013-09-23 0intro
611 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got entry\n");
612 6f4d00ee 2013-09-23 0intro
613 6f4d00ee 2013-09-23 0intro if(version < 9){
614 6f4d00ee 2013-09-23 0intro dir->gen = 0;
615 6f4d00ee 2013-09-23 0intro dir->mentry = dir->entry+1;
616 6f4d00ee 2013-09-23 0intro dir->mgen = 0;
617 6f4d00ee 2013-09-23 0intro }else{
618 6f4d00ee 2013-09-23 0intro if(n < 3*4)
619 6f4d00ee 2013-09-23 0intro goto Err;
620 6f4d00ee 2013-09-23 0intro dir->gen = U32GET(p);
621 6f4d00ee 2013-09-23 0intro dir->mentry = U32GET(p+4);
622 6f4d00ee 2013-09-23 0intro dir->mgen = U32GET(p+8);
623 6f4d00ee 2013-09-23 0intro p += 3*4;
624 6f4d00ee 2013-09-23 0intro n -= 3*4;
625 6f4d00ee 2013-09-23 0intro }
626 6f4d00ee 2013-09-23 0intro
627 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got gen etc\n");
628 6f4d00ee 2013-09-23 0intro
629 6f4d00ee 2013-09-23 0intro /* size is gotten from VtEntry */
630 6f4d00ee 2013-09-23 0intro dir->size = 0;
631 6f4d00ee 2013-09-23 0intro
632 6f4d00ee 2013-09-23 0intro /* qid */
633 6f4d00ee 2013-09-23 0intro if(n < 8)
634 6f4d00ee 2013-09-23 0intro goto Err;
635 6f4d00ee 2013-09-23 0intro dir->qid = U64GET(p);
636 6f4d00ee 2013-09-23 0intro p += 8;
637 6f4d00ee 2013-09-23 0intro n -= 8;
638 6f4d00ee 2013-09-23 0intro
639 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got qid\n");
640 6f4d00ee 2013-09-23 0intro /* skip replacement */
641 6f4d00ee 2013-09-23 0intro if(version == 7){
642 6f4d00ee 2013-09-23 0intro if(n < VtScoreSize)
643 6f4d00ee 2013-09-23 0intro goto Err;
644 6f4d00ee 2013-09-23 0intro p += VtScoreSize;
645 6f4d00ee 2013-09-23 0intro n -= VtScoreSize;
646 6f4d00ee 2013-09-23 0intro }
647 6f4d00ee 2013-09-23 0intro
648 6f4d00ee 2013-09-23 0intro /* uid */
649 6f4d00ee 2013-09-23 0intro if(!stringUnpack(&dir->uid, &p, &n))
650 6f4d00ee 2013-09-23 0intro goto Err;
651 6f4d00ee 2013-09-23 0intro
652 6f4d00ee 2013-09-23 0intro /* gid */
653 6f4d00ee 2013-09-23 0intro if(!stringUnpack(&dir->gid, &p, &n))
654 6f4d00ee 2013-09-23 0intro goto Err;
655 6f4d00ee 2013-09-23 0intro
656 6f4d00ee 2013-09-23 0intro /* mid */
657 6f4d00ee 2013-09-23 0intro if(!stringUnpack(&dir->mid, &p, &n))
658 6f4d00ee 2013-09-23 0intro goto Err;
659 6f4d00ee 2013-09-23 0intro
660 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got ids\n");
661 6f4d00ee 2013-09-23 0intro if(n < 5*4)
662 6f4d00ee 2013-09-23 0intro goto Err;
663 6f4d00ee 2013-09-23 0intro dir->mtime = U32GET(p);
664 6f4d00ee 2013-09-23 0intro dir->mcount = U32GET(p+4);
665 6f4d00ee 2013-09-23 0intro dir->ctime = U32GET(p+8);
666 6f4d00ee 2013-09-23 0intro dir->atime = U32GET(p+12);
667 6f4d00ee 2013-09-23 0intro dir->mode = U32GET(p+16);
668 6f4d00ee 2013-09-23 0intro p += 5*4;
669 6f4d00ee 2013-09-23 0intro n -= 5*4;
670 6f4d00ee 2013-09-23 0intro
671 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got times\n");
672 6f4d00ee 2013-09-23 0intro /* optional meta data */
673 6f4d00ee 2013-09-23 0intro while(n > 0){
674 6f4d00ee 2013-09-23 0intro if(n < 3)
675 6f4d00ee 2013-09-23 0intro goto Err;
676 6f4d00ee 2013-09-23 0intro t = p[0];
677 6f4d00ee 2013-09-23 0intro nn = U16GET(p+1);
678 6f4d00ee 2013-09-23 0intro p += 3;
679 6f4d00ee 2013-09-23 0intro n -= 3;
680 6f4d00ee 2013-09-23 0intro if(n < nn)
681 6f4d00ee 2013-09-23 0intro goto Err;
682 6f4d00ee 2013-09-23 0intro switch(t){
683 6f4d00ee 2013-09-23 0intro case DePlan9:
684 6f4d00ee 2013-09-23 0intro /* not valid in version >= 9 */
685 6f4d00ee 2013-09-23 0intro if(version >= 9)
686 6f4d00ee 2013-09-23 0intro break;
687 6f4d00ee 2013-09-23 0intro if(dir->plan9 || nn != 12)
688 6f4d00ee 2013-09-23 0intro goto Err;
689 6f4d00ee 2013-09-23 0intro dir->plan9 = 1;
690 6f4d00ee 2013-09-23 0intro dir->p9path = U64GET(p);
691 6f4d00ee 2013-09-23 0intro dir->p9version = U32GET(p+8);
692 6f4d00ee 2013-09-23 0intro if(dir->mcount == 0)
693 6f4d00ee 2013-09-23 0intro dir->mcount = dir->p9version;
694 6f4d00ee 2013-09-23 0intro break;
695 6f4d00ee 2013-09-23 0intro case DeGen:
696 6f4d00ee 2013-09-23 0intro /* not valid in version >= 9 */
697 6f4d00ee 2013-09-23 0intro if(version >= 9)
698 6f4d00ee 2013-09-23 0intro break;
699 6f4d00ee 2013-09-23 0intro break;
700 6f4d00ee 2013-09-23 0intro case DeQidSpace:
701 6f4d00ee 2013-09-23 0intro if(dir->qidSpace || nn != 16)
702 6f4d00ee 2013-09-23 0intro goto Err;
703 6f4d00ee 2013-09-23 0intro dir->qidSpace = 1;
704 6f4d00ee 2013-09-23 0intro dir->qidOffset = U64GET(p);
705 6f4d00ee 2013-09-23 0intro dir->qidMax = U64GET(p+8);
706 6f4d00ee 2013-09-23 0intro break;
707 6f4d00ee 2013-09-23 0intro }
708 6f4d00ee 2013-09-23 0intro p += nn;
709 6f4d00ee 2013-09-23 0intro n -= nn;
710 6f4d00ee 2013-09-23 0intro }
711 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: got options\n");
712 6f4d00ee 2013-09-23 0intro
713 6f4d00ee 2013-09-23 0intro if(p != me->p + me->size)
714 6f4d00ee 2013-09-23 0intro goto Err;
715 6f4d00ee 2013-09-23 0intro
716 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: correct size\n");
717 6f4d00ee 2013-09-23 0intro return 1;
718 6f4d00ee 2013-09-23 0intro Err:
719 6f4d00ee 2013-09-23 0intro if(0)print("deUnpack: XXXXXXXXXXXX EBadMeta\n");
720 4b576658 2013-09-23 0intro werrstr(EBadMeta);
721 6f4d00ee 2013-09-23 0intro deCleanup(dir);
722 6f4d00ee 2013-09-23 0intro return 0;
723 6f4d00ee 2013-09-23 0intro }
724 6f4d00ee 2013-09-23 0intro
725 6f4d00ee 2013-09-23 0intro void
726 6f4d00ee 2013-09-23 0intro deCleanup(DirEntry *dir)
727 6f4d00ee 2013-09-23 0intro {
728 4b576658 2013-09-23 0intro vtfree(dir->elem);
729 6f4d00ee 2013-09-23 0intro dir->elem = nil;
730 4b576658 2013-09-23 0intro vtfree(dir->uid);
731 6f4d00ee 2013-09-23 0intro dir->uid = nil;
732 4b576658 2013-09-23 0intro vtfree(dir->gid);
733 6f4d00ee 2013-09-23 0intro dir->gid = nil;
734 4b576658 2013-09-23 0intro vtfree(dir->mid);
735 6f4d00ee 2013-09-23 0intro dir->mid = nil;
736 6f4d00ee 2013-09-23 0intro }
737 6f4d00ee 2013-09-23 0intro
738 6f4d00ee 2013-09-23 0intro void
739 6f4d00ee 2013-09-23 0intro deCopy(DirEntry *dst, DirEntry *src)
740 6f4d00ee 2013-09-23 0intro {
741 6f4d00ee 2013-09-23 0intro *dst = *src;
742 4b576658 2013-09-23 0intro dst->elem = vtstrdup(src->elem);
743 4b576658 2013-09-23 0intro dst->uid = vtstrdup(src->uid);
744 4b576658 2013-09-23 0intro dst->gid = vtstrdup(src->gid);
745 4b576658 2013-09-23 0intro dst->mid = vtstrdup(src->mid);
746 6f4d00ee 2013-09-23 0intro }