xref: /plan9/sys/src/libventi/entry.c (revision 368c31ab13393dea083228fdd1c3445076f83a4b)
1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include "cvt.h"
5 
6 static int
checksize(int n)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 }
15 
16 void
vtentrypack(VtEntry * e,uchar * p,int index)17 vtentrypack(VtEntry *e, uchar *p, int index)
18 {
19 	ulong t32;
20 	int flags;
21 	uchar *op;
22 	int depth;
23 
24 	p += index * VtEntrySize;
25 	op = p;
26 
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;
46 
47 	assert(p-op == VtEntrySize);
48 }
49 
50 int
vtentryunpack(VtEntry * e,uchar * p,int index)51 vtentryunpack(VtEntry *e, uchar *p, int index)
52 {
53 	uchar *op;
54 
55 	p += index * VtEntrySize;
56 	op = p;
57 
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;
74 
75 	assert(p-op == VtEntrySize);
76 
77 	if(!(e->flags & VtEntryActive))
78 		return 0;
79 
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;
92 
93 	return 0;
94 }
95 
96