Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include "cvt.h"
6 static int
7 checksize(int n)
8 {
9 if(n < 256 || n > VtMaxLumpSize) {
10 werrstr("bad block size %#ux", n);
11 return -1;
12 }
13 return 0;
14 }
16 void
17 vtentrypack(VtEntry *e, uchar *p, int index)
18 {
19 ulong t32;
20 int flags;
21 uchar *op;
22 int depth;
24 p += index * VtEntrySize;
25 op = p;
27 U32PUT(p, e->gen);
28 p += 4;
29 U16PUT(p, e->psize);
30 p += 2;
31 U16PUT(p, e->dsize);
32 p += 2;
33 depth = e->type&VtTypeDepthMask;
34 flags = (e->flags&~(_VtEntryDir|_VtEntryDepthMask));
35 flags |= depth << _VtEntryDepthShift;
36 if(e->type - depth == VtDirType)
37 flags |= _VtEntryDir;
38 U8PUT(p, flags);
39 p++;
40 memset(p, 0, 5);
41 p += 5;
42 U48PUT(p, e->size, t32);
43 p += 6;
44 memmove(p, e->score, VtScoreSize);
45 p += VtScoreSize;
47 assert(p-op == VtEntrySize);
48 }
50 int
51 vtentryunpack(VtEntry *e, uchar *p, int index)
52 {
53 uchar *op;
55 p += index * VtEntrySize;
56 op = p;
58 e->gen = U32GET(p);
59 p += 4;
60 e->psize = U16GET(p);
61 p += 2;
62 e->dsize = U16GET(p);
63 p += 2;
64 e->flags = U8GET(p);
65 e->type = (e->flags&_VtEntryDir) ? VtDirType : VtDataType;
66 e->type += (e->flags & _VtEntryDepthMask) >> _VtEntryDepthShift;
67 e->flags &= ~(_VtEntryDir|_VtEntryDepthMask);
68 p++;
69 p += 5;
70 e->size = U48GET(p);
71 p += 6;
72 memmove(e->score, p, VtScoreSize);
73 p += VtScoreSize;
75 assert(p-op == VtEntrySize);
77 if(!(e->flags & VtEntryActive))
78 return 0;
80 /*
81 * Some old vac files use psize==0 and dsize==0 when the
82 * file itself has size 0 or is zeros. Just to make programs not
83 * have to figure out what block sizes of 0 means, rewrite them.
84 */
85 if(e->psize == 0 && e->dsize == 0
86 && memcmp(e->score, vtzeroscore, VtScoreSize) == 0){
87 e->psize = 4096;
88 e->dsize = 4096;
89 }
90 if(checksize(e->psize) < 0 || checksize(e->dsize) < 0)
91 return -1;
93 return 0;
94 }