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