| #include <u.h> | 
 | #include <libc.h> | 
 | #include <venti.h> | 
 | #include "cvt.h" | 
 |  | 
 | static int | 
 | checksize(int n) | 
 | { | 
 | 	if(n < 256) { | 
 | 		werrstr("bad block size"); | 
 | 		return -1; | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 | extern int vttobig(ulong); | 
 |  | 
 | void | 
 | vtrootpack(VtRoot *r, uchar *p) | 
 | { | 
 | 	uchar *op = p; | 
 | 	int vers, bsize; | 
 |  | 
 | 	vers = VtRootVersion; | 
 | 	bsize = r->blocksize; | 
 | 	if(bsize >= (1<<16)) { | 
 | 		vers |= _VtRootVersionBig; | 
 | 		bsize = vttobig(bsize); | 
 | 		if(bsize < 0) | 
 | 			sysfatal("invalid root blocksize: %#lx", r->blocksize); | 
 | 	} | 
 | 	U16PUT(p, vers); | 
 | 	p += 2; | 
 | 	memmove(p, r->name, sizeof(r->name)); | 
 | 	p += sizeof(r->name); | 
 | 	memmove(p, r->type, sizeof(r->type)); | 
 | 	p += sizeof(r->type); | 
 | 	memmove(p, r->score, VtScoreSize); | 
 | 	p +=  VtScoreSize; | 
 | 	U16PUT(p, bsize); | 
 | 	p += 2; | 
 | 	memmove(p, r->prev, VtScoreSize); | 
 | 	p += VtScoreSize; | 
 |  | 
 | 	assert(p-op == VtRootSize); | 
 | } | 
 |  | 
 | int | 
 | vtrootunpack(VtRoot *r, uchar *p) | 
 | { | 
 | 	uchar *op = p; | 
 | 	uint vers; | 
 | 	memset(r, 0, sizeof(*r)); | 
 |  | 
 | 	vers = U16GET(p); | 
 | 	if((vers&~_VtRootVersionBig) != VtRootVersion) { | 
 | 		werrstr("unknown root version"); | 
 | 		return -1; | 
 | 	} | 
 | 	p += 2; | 
 | 	memmove(r->name, p, sizeof(r->name)); | 
 | 	r->name[sizeof(r->name)-1] = 0; | 
 | 	p += sizeof(r->name); | 
 | 	memmove(r->type, p, sizeof(r->type)); | 
 | 	r->type[sizeof(r->type)-1] = 0; | 
 | 	p += sizeof(r->type); | 
 | 	memmove(r->score, p, VtScoreSize); | 
 | 	p +=  VtScoreSize; | 
 | 	r->blocksize = U16GET(p); | 
 | 	if(vers & _VtRootVersionBig) | 
 | 		r->blocksize = (r->blocksize >> 5) << (r->blocksize & 31); | 
 | 	if(checksize(r->blocksize) < 0) | 
 | 		return -1; | 
 | 	p += 2; | 
 | 	memmove(r->prev, p, VtScoreSize); | 
 | 	p += VtScoreSize; | 
 |  | 
 | 	assert(p-op == VtRootSize); | 
 | 	return 0; | 
 | } |