Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "stdinc.h"
2
#include "dat.h"
3
#include "fns.h"
4
#include "error.h"
5
 
6
/*
7
 * integer conversion routines
8
 */
9
#define	U8GET(p)	((p)[0])
10
#define	U16GET(p)	(((p)[0]<<8)|(p)[1])
11
#define	U32GET(p)	(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
12
#define	U48GET(p)	(((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2))
13
#define	U64GET(p)	(((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4))
14
 
15
#define	U8PUT(p,v)	(p)[0]=(v)
16
#define	U16PUT(p,v)	(p)[0]=(v)>>8;(p)[1]=(v)
17
#define	U32PUT(p,v)	(p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
18
#define	U48PUT(p,v,t32)	t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
19
#define	U64PUT(p,v,t32)	t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
20
 
21
void
22
headerPack(Header *h, uchar *p)
23
{
24
	memset(p, 0, HeaderSize);
25
	U32PUT(p, HeaderMagic);
26
	U16PUT(p+4, HeaderVersion);
27
	U16PUT(p+6, h->blockSize);
28
	U32PUT(p+8, h->super);
29
	U32PUT(p+12, h->label);
30
	U32PUT(p+16, h->data);
31
	U32PUT(p+20, h->end);
32
}
33
 
34
int
35
headerUnpack(Header *h, uchar *p)
36
{
37
	if(U32GET(p) != HeaderMagic){
38
		vtSetError("vac header bad magic");
39
		return 0;
40
	}
41
	h->version = U16GET(p+4);
42
	if(h->version != HeaderVersion){
43
		vtSetError("vac header bad version");
44
		return 0;
45
	}
46
	h->blockSize = U16GET(p+6);
47
	h->super = U32GET(p+8);
48
	h->label = U32GET(p+12);
49
	h->data = U32GET(p+16);
50
	h->end = U32GET(p+20);
51
	return 1;
52
}
53
 
54
void
55
labelPack(Label *l, uchar *p, int i)
56
{
57
	p += i*LabelSize;
58
	U8PUT(p, l->state);
59
	U8PUT(p+1, l->type);
60
	U32PUT(p+2, l->epoch);
61
	U32PUT(p+6, l->epochClose);
62
	U32PUT(p+10, l->tag);
63
}
64
 
65
int
66
labelUnpack(Label *l, uchar *p, int i)
67
{
68
	p += i*LabelSize;
69
	l->state = p[0];
70
	l->type = p[1];
71
	l->epoch = U32GET(p+2);
72
	l->epochClose = U32GET(p+6);
73
	l->tag = U32GET(p+10);
74
 
75
	if(l->type > BtMax){
76
Bad:
77
		vtSetError(EBadLabel);
78
		fprint(2, "%s: labelUnpack: bad label: 0x%.2ux 0x%.2ux 0x%.8ux "
79
			"0x%.8ux 0x%.8ux\n", argv0, l->state, l->type, l->epoch,
80
			l->epochClose, l->tag);
81
		return 0;
82
	}
83
	if(l->state != BsBad && l->state != BsFree){
84
		if(!(l->state&BsAlloc) || l->state & ~BsMask)
85
			goto Bad;
86
		if(l->state&BsClosed){
87
			if(l->epochClose == ~(u32int)0)
88
				goto Bad;
89
		}else{
90
			if(l->epochClose != ~(u32int)0)
91
				goto Bad;
92
		}
93
	}
94
	return 1;
95
}
96
 
97
u32int
98
globalToLocal(uchar score[VtScoreSize])
99
{
100
	int i;
101
 
102
	for(i=0; i<VtScoreSize-4; i++)
103
		if(score[i] != 0)
104
			return NilBlock;
105
 
106
	return U32GET(score+VtScoreSize-4);
107
}
108
 
109
void
110
localToGlobal(u32int addr, uchar score[VtScoreSize])
111
{
112
	memset(score, 0, VtScoreSize-4);
113
	U32PUT(score+VtScoreSize-4, addr);
114
}
115
 
116
void
117
entryPack(Entry *e, uchar *p, int index)
118
{
119
	ulong t32;
120
	int flags;
121
 
122
	p += index * VtEntrySize;
123
 
124
	U32PUT(p, e->gen);
125
	U16PUT(p+4, e->psize);
126
	U16PUT(p+6, e->dsize);
127
	flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
128
	U8PUT(p+8, flags);
129
	memset(p+9, 0, 5);
130
	U48PUT(p+14, e->size, t32);
131
 
132
	if(flags & VtEntryLocal){
133
		if(globalToLocal(e->score) == NilBlock)
134
			abort();
135
		memset(p+20, 0, 7);
136
		U8PUT(p+27, e->archive);
137
		U32PUT(p+28, e->snap);
138
		U32PUT(p+32, e->tag);
139
		memmove(p+36, e->score+16, 4);
140
	}else
141
		memmove(p+20, e->score, VtScoreSize);
142
}
143
 
144
int
145
entryUnpack(Entry *e, uchar *p, int index)
146
{
147
	p += index * VtEntrySize;
148
 
149
	e->gen = U32GET(p);
150
	e->psize = U16GET(p+4);
151
	e->dsize = U16GET(p+6);
152
	e->flags = U8GET(p+8);
153
	e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
154
	e->flags &= ~VtEntryDepthMask;
155
	e->size = U48GET(p+14);
156
 
157
	if(e->flags & VtEntryLocal){
158
		e->archive = p[27];
159
		e->snap = U32GET(p+28);
160
		e->tag = U32GET(p+32);
161
		memset(e->score, 0, 16);
162
		memmove(e->score+16, p+36, 4);
163
	}else{
164
		e->archive = 0;
165
		e->snap = 0;
166
		e->tag = 0;
167
		memmove(e->score, p+20, VtScoreSize);
168
	}
169
 
170
	return 1;
171
}
172
 
173
int
174
entryType(Entry *e)
175
{
176
	return (((e->flags & VtEntryDir) != 0) << 3) | e->depth;
177
}
178
 
179
 
180
void
181
superPack(Super *s, uchar *p)
182
{
183
	u32int t32;
184
 
185
	memset(p, 0, SuperSize);
186
	U32PUT(p, SuperMagic);
187
	assert(s->version == SuperVersion);
188
	U16PUT(p+4, s->version);
189
	U32PUT(p+6, s->epochLow);
190
	U32PUT(p+10, s->epochHigh);
191
	U64PUT(p+14, s->qid, t32);
192
	U32PUT(p+22, s->active);
193
	U32PUT(p+26, s->next);
194
	U32PUT(p+30, s->current);
195
	memmove(p+34, s->last, VtScoreSize);
196
	memmove(p+54, s->name, sizeof(s->name));
197
}
198
 
199
int
200
superUnpack(Super *s, uchar *p)
201
{
202
	memset(s, 0, sizeof(*s));
203
	if(U32GET(p) != SuperMagic)
204
		goto Err;
205
	s->version = U16GET(p+4);
206
	if(s->version != SuperVersion)
207
		goto Err;
208
	s->epochLow = U32GET(p+6);
209
	s->epochHigh = U32GET(p+10);
210
	s->qid = U64GET(p+14);
211
	if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0)
212
		goto Err;
213
	s->active = U32GET(p+22);
214
	s->next = U32GET(p+26);
215
	s->current = U32GET(p+30);
216
	memmove(s->last, p+34, VtScoreSize);
217
	memmove(s->name, p+54, sizeof(s->name));
218
	s->name[sizeof(s->name)-1] = 0;
219
	return 1;
220
Err:
221
	memset(s, 0, sizeof(*s));
222
	vtSetError(EBadSuper);
223
	return 0;
224
}
225