Blame


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