Example #1
0
File: pack.c Project: 99years/plan9
int
entryUnpack(Entry *e, uchar *p, int index)
{
	p += index * VtEntrySize;

	e->gen = U32GET(p);
	e->psize = U16GET(p+4);
	e->dsize = U16GET(p+6);
	e->flags = U8GET(p+8);
	e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
	e->flags &= ~VtEntryDepthMask;
	e->size = U48GET(p+14);

	if(e->flags & VtEntryLocal){
		e->archive = p[27];
		e->snap = U32GET(p+28);
		e->tag = U32GET(p+32);
		memset(e->score, 0, 16);
		memmove(e->score+16, p+36, 4);
	}else{
		e->archive = 0;
		e->snap = 0;
		e->tag = 0;
		memmove(e->score, p+20, VtScoreSize);
	}

	return 1;
}
Example #2
0
File: pack.c Project: 99years/plan9
int
labelUnpack(Label *l, uchar *p, int i)
{
	p += i*LabelSize;
	l->state = p[0];
	l->type = p[1];
	l->epoch = U32GET(p+2);
	l->epochClose = U32GET(p+6);
	l->tag = U32GET(p+10);

	if(l->type > BtMax){
Bad:
		vtSetError(EBadLabel);
		fprint(2, "%s: labelUnpack: bad label: 0x%.2ux 0x%.2ux 0x%.8ux "
			"0x%.8ux 0x%.8ux\n", argv0, l->state, l->type, l->epoch,
			l->epochClose, l->tag);
		return 0;
	}
	if(l->state != BsBad && l->state != BsFree){
		if(!(l->state&BsAlloc) || l->state & ~BsMask)
			goto Bad;
		if(l->state&BsClosed){
			if(l->epochClose == ~(u32int)0)
				goto Bad;
		}else{
			if(l->epochClose != ~(u32int)0)
				goto Bad;
		}
	}
	return 1;
}
Example #3
0
int
mbUnpack(MetaBlock *mb, uchar *p, int n)
{
	u32int magic;
	int i;
	int eo, en, omin;
	uchar *q;

	mb->maxsize = n;
	mb->buf = p;

	if(n == 0){
		memset(mb, 0, sizeof(MetaBlock));
		return 1;
	}

	magic = U32GET(p);
	if(magic != MetaMagic && magic != MetaMagic-1)
		goto Err;
	mb->size = U16GET(p+4);
	mb->free = U16GET(p+6);
	mb->maxindex = U16GET(p+8);
	mb->nindex = U16GET(p+10);
	mb->botch = magic != MetaMagic;
	if(mb->size > n)
		goto Err;

	omin = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	if(n < omin)
		goto Err;


	p += MetaHeaderSize;

	/* check the index table - ensures that meUnpack and meCmp never fail */
	for(i=0; i<mb->nindex; i++){
		eo = U16GET(p);
		en = U16GET(p+2);
		if(eo < omin || eo+en > mb->size || en < 8)
			goto Err;
		q = mb->buf + eo;
		if(U32GET(q) != DirMagic)
			goto Err;
		p += 4;
	}

	return 1;
Err:
	vtSetError(EBadMeta);
	return 0;
}
Example #4
0
/*
 * read in the chained buffers for bucket b,
 * and return it's total number of IEntries
 */
static uint32_t
readiebuck(IEBucks *ib, int b)
{
	uint32_t head, m, n;

	head = ib->bucks[b].head;
	n = 0;
	m = ib->bucks[b].used;
	if(m == 0)
		m = ib->usable;
	if(0) if(ib->bucks[b].total)
		fprint(2, "\tbucket %d: %lld entries\n", b, ib->bucks[b].total/IEntrySize);
	while(head != TWID32){
		if(readpart(ib->part, (uint64_t)head * ib->size, &ib->buf[n], m+U32Size) < 0){
			seterr(EOk, "can't read index sort bucket: %r");
			return TWID32;
		}
		n += m;
		head = U32GET(&ib->buf[n]);
		m = ib->usable;
	}
	if(n != ib->bucks[b].total)
		fprint(2, "\tbucket %d: expected %d entries, got %d\n",
			b, (int)ib->bucks[b].total/IEntrySize, n/IEntrySize);
	return n / IEntrySize;
}
Example #5
0
File: pack.c Project: 99years/plan9
int
headerUnpack(Header *h, uchar *p)
{
	if(U32GET(p) != HeaderMagic){
		vtSetError("vac header bad magic");
		return 0;
	}
	h->version = U16GET(p+4);
	if(h->version != HeaderVersion){
		vtSetError("vac header bad version");
		return 0;
	}
	h->blockSize = U16GET(p+6);
	h->super = U32GET(p+8);
	h->label = U32GET(p+12);
	h->data = U32GET(p+16);
	h->end = U32GET(p+20);
	return 1;
}
Example #6
0
File: pack.c Project: 99years/plan9
u32int
globalToLocal(uchar score[VtScoreSize])
{
	int i;

	for(i=0; i<VtScoreSize-4; i++)
		if(score[i] != 0)
			return NilBlock;

	return U32GET(score+VtScoreSize-4);
}
Example #7
0
uint32_t
globalToLocal(uint8_t score[VtScoreSize])
{
	int i;

	for(i=0; i<VtScoreSize-4; i++)
		if(score[i] != 0)
			return NilBlock;
			//return (int64_t)NilBlock;
	return U32GET(score+VtScoreSize-4);
}
Example #8
0
File: pack.c Project: 99years/plan9
int
superUnpack(Super *s, uchar *p)
{
	memset(s, 0, sizeof(*s));
	if(U32GET(p) != SuperMagic)
		goto Err;
	s->version = U16GET(p+4);
	if(s->version != SuperVersion)
		goto Err;
	s->epochLow = U32GET(p+6);
	s->epochHigh = U32GET(p+10);
	s->qid = U64GET(p+14);
	if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0)
		goto Err;
	s->active = U32GET(p+22);
	s->next = U32GET(p+26);
	s->current = U32GET(p+30);
	memmove(s->last, p+34, VtScoreSize);
	memmove(s->name, p+54, sizeof(s->name));
	s->name[sizeof(s->name)-1] = 0;
	return 1;
Err:
	memset(s, 0, sizeof(*s));
	vtSetError(EBadSuper);
	return 0;
}
Example #9
0
int
vtentryunpack(VtEntry *e, uchar *p, int index)
{
	uchar *op;

	p += index * VtEntrySize;
	op = p;

	e->gen = U32GET(p);
	p += 4;
	e->psize = U16GET(p);
	p += 2;
	e->dsize = U16GET(p);
	p += 2;
	e->flags = U8GET(p);
	p++;
	if(e->flags & _VtEntryBig) {
		e->psize = (e->psize>>5)<<(e->psize & 31);
		e->dsize = (e->dsize>>5)<<(e->dsize & 31);
	}
Example #10
0
int
deUnpack(DirEntry *dir, MetaEntry *me)
{
	int t, nn, n, version;
	uchar *p;

	p = me->p;
	n = me->size;

	memset(dir, 0, sizeof(DirEntry));

if(0)print("deUnpack\n");
	/* magic */
	if(n < 4 || U32GET(p) != DirMagic)
		goto Err;
	p += 4;
	n -= 4;

if(0)print("deUnpack: got magic\n");
	/* version */
	if(n < 2)
		goto Err;
	version = U16GET(p);
	if(version < 7 || version > 9)
		goto Err;
	p += 2;
	n -= 2;

if(0)print("deUnpack: got version\n");

	/* elem */
	if(!stringUnpack(&dir->elem, &p, &n))
		goto Err;

if(0)print("deUnpack: got elem\n");

	/* entry  */
	if(n < 4)
		goto Err;
	dir->entry = U32GET(p);
	p += 4;
	n -= 4;

if(0)print("deUnpack: got entry\n");

	if(version < 9){
		dir->gen = 0;
		dir->mentry = dir->entry+1;
		dir->mgen = 0;
	}else{
		if(n < 3*4)
			goto Err;
		dir->gen = U32GET(p);
		dir->mentry = U32GET(p+4);
		dir->mgen = U32GET(p+8);
		p += 3*4;
		n -= 3*4;
	}

if(0)print("deUnpack: got gen etc\n");

	/* size is gotten from VtEntry */
	dir->size = 0;

	/* qid */
	if(n < 8)
		goto Err;
	dir->qid = U64GET(p);
	p += 8;
	n -= 8;

if(0)print("deUnpack: got qid\n");
	/* skip replacement */
	if(version == 7){
		if(n < VtScoreSize)
			goto Err;
		p += VtScoreSize;
		n -= VtScoreSize;
	}

	/* uid */
	if(!stringUnpack(&dir->uid, &p, &n))
		goto Err;

	/* gid */
	if(!stringUnpack(&dir->gid, &p, &n))
		goto Err;

	/* mid */
	if(!stringUnpack(&dir->mid, &p, &n))
		goto Err;

if(0)print("deUnpack: got ids\n");
	if(n < 5*4)
		goto Err;
	dir->mtime = U32GET(p);
	dir->mcount = U32GET(p+4);
	dir->ctime = U32GET(p+8);
	dir->atime = U32GET(p+12);
	dir->mode = U32GET(p+16);
	p += 5*4;
	n -= 5*4;

if(0)print("deUnpack: got times\n");
	/* optional meta data */
	while(n > 0){
		if(n < 3)
			goto Err;
		t = p[0];
		nn = U16GET(p+1);
		p += 3;
		n -= 3;
		if(n < nn)
			goto Err;
		switch(t){
		case DePlan9:
			/* not valid in version >= 9 */
			if(version >= 9)
				break;
			if(dir->plan9 || nn != 12)
				goto Err;
			dir->plan9 = 1;
			dir->p9path = U64GET(p);
			dir->p9version = U32GET(p+8);
			if(dir->mcount == 0)
				dir->mcount = dir->p9version;
			break;
		case DeGen:
			/* not valid in version >= 9 */
			if(version >= 9)
				break;
			break;
		case DeQidSpace:
			if(dir->qidSpace || nn != 16)
				goto Err;
			dir->qidSpace = 1;
			dir->qidOffset = U64GET(p);
			dir->qidMax = U64GET(p+8);
			break;
		}
		p += nn;
		n -= nn;
	}
if(0)print("deUnpack: got options\n");

	if(p != me->p + me->size)
		goto Err;

if(0)print("deUnpack: correct size\n");
	return 1;
Err:
if(0)print("deUnpack: XXXXXXXXXXXX EBadMeta\n");
	vtSetError(EBadMeta);
	deCleanup(dir);
	return 0;
}
Example #11
0
/* 
 * BUG: currently this expects to be called from replies only.
 * e.g., the type is adjusted to account for this.
 */
int
convP2C(uint8 *ap, Pcall *c)
{
	uint8 *p = ap;
	uint size;
	uint32 chk, chk1;

	c->type = 0xff + *p++;
	if(*p++ != 0)
		return 0;
	c->tag = *p++;
	size = c->size = *p++;

	if(pumpchk(p-4, 4, &chk) == 0){
		/* TODO: soft error/warning when we don't have it. */
		if(chk != U32GETLE(p)){
			werrstr("header checksum mismatch: got %8ux, expected %8ux", 
				chk, U32GETLE(p));
			return -1;
		}
	}
	
	p += 4;
	
	if(size > 0){
		chk = crc32(p, size);
		chk1 = U32GET(p+size);
		if(chk != chk1){
			werrstr("payload checksum mismatch: got %8ux, expected %8ux",
				chk1, chk);
			return -1;
		}
	}
	
	c->err = Eok;
	switch(c->type){
	default: break;
	
	case Rkeepalive:
		c->backoffms = U16GETLE(p);
		break;
		
	case Rbolus:
	{
		Mbolus *b = &c->bolus;
		p += 2;
		b->insulin = U16GETLE(p);
		p += 2;
		b->minutes = U16GETLE(p)*6;
		break;
	}
	
	case Rdeliverystatus:
	{
		p += 1;
		switch(*p){
		case 0x01:	c->deliverystatus = DeliveryBusy; break;
		case 0x02:	c->deliverystatus = DeliveryDone; break;
		default:		c->deliverystatus = DeliveryUnknown; break;
		}
	}

	/* TODO: check against sizes */
	case Rstatus:
	{
		Mstatus *s = &c->status;

		/* 4 bytes unknown */

		s->year = 2007 + (p[4]&0xf);
		s->month = 1 + (p[4]>>4);
		s->day = p[5];
		s->hour = p[6];
		s->minute = p[7];

		/* 5 bytes unknown */

		s->basal = (p[13]<<8) | p[12];
		s->insulin = p[14];
		
		/* 3 bytes unknown */
		
		if(!(p[17]&0x1))
			s->temp = 0;
		else if(p[18] > 128)
			s->temp = (int8)-(256-p[18]);
		else
			s->temp = p[18];
		
		/* 2 bytes unknown */

		s->temptotal = p[22]*60 + p[23];
		s->temptime = s->temptotal-(p[20]*60 + p[21]);
		
		break;
	}

	case Rstatus1:
	{
		Mstatus1  *s = &c->status1;

		s->prognum = p[1];

		s->insulin = p[6];
		s->daily = 10*((p[3]<<8) | p[2]);
		s->hourly = (p[5]<<8) | p[4];
		
		/* p[7] unknown. */

		memcpy(s->progname, p+8, 10);
		s->progname[10] = 0;

		 break;
	}
	
	case Rstatus2:
	{
		Mstatus2 *s = &c->status2;

		// Last bolus 
		s->year = 2007 + (p[6]&0xf);
		s->month = 1 + (p[6]>>4);
		s->day = p[7];
		s->hour = p[8];
		s->minute = p[9];
		s->bolus = (p[5]<<8) | p[4];
		s->iob = 10* ((p[17]<<8) | p[16]);
		break;
	}

	case Rstatus3:
	{
		Mstatus3 *s = &c->status3;

		s->bolus = U32GETLE(p+4);
		s->basal = U32GETLE(p+8); 
		panic("bug");
		s->temp = p[2] & 0x1;
		s->suspend = p[2] & 0x2;
	}

	case Rstatus4:
	{
		Mstatus4 *s = &c->status4;
		
		s->active = p[1] == 0x01; /* tbd. */
		
		s->year = 2007+(p[2]&0xf);
		s->month = 1+(p[2]>>4);
		
		s->starthour = p[4];
		s->startminute = p[5];
		s->endhour = p[6];
		s->endminute = p[7];
		
		s->delivered = U16GETLE(p+8);
		s->total = U16GETLE(p+10);

	}


	}

	/* Fill status bits where we (think) we have them. */
	switch(c->type){
	case Rbolus:
	case R2c:
	case Rdeliverystatus:
	case Rstatus:
		if(p[0] & BIT(4))
			c->flag |= Fwarn;	
	}
	
	/* TODO: check against size */

	return 0;
}
Example #12
0
static int
diskarenaclump(HConnect *c, Arena *arena, vlong off, char *scorestr)
{
	uchar *blk, *blk2;
	Clump cl;
	char err[ERRMAX];
	uchar xscore[VtScoreSize], score[VtScoreSize];
	Unwhack uw;
	int n;
	
	if(scorestr){
		if(vtparsescore(scorestr, nil, score) < 0){
			hprint(&c->hout, "bad score %s: %r\n", scorestr);
			return -1;
		}
		if(off < 0){
			off = findintoc(c, arena, score);
			if(off < 0){
				hprint(&c->hout, "score %V not found in arena %s\n", score, arena->name);
				return -1;
			}
			hprint(&c->hout, "score %V at %#llx\n", score, off);
		}
	}else
		memset(score, 0, sizeof score);

	if(off < 0){
		hprint(&c->hout, "bad offset %#llx\n", off);
		return -1;
	}
	
	off += arena->base;

	blk = vtmalloc(ClumpSize + VtMaxLumpSize);
	if(readpart(arena->part, off, blk, ClumpSize + VtMaxLumpSize) != ClumpSize + VtMaxLumpSize){
		hprint(&c->hout, "reading at %#llx: %r\n", off);
		vtfree(blk);
		return -1;
	}

	if(unpackclump(&cl, blk, arena->clumpmagic) < 0){
		hprint(&c->hout, "unpackclump: %r\n<br>");
		rerrstr(err, sizeof err);
		if(strstr(err, "magic")){
			hprint(&c->hout, "trying again with magic=%#ux<br>\n", U32GET(blk));
			if(unpackclump(&cl, blk, U32GET(blk)) < 0){
				hprint(&c->hout, "unpackclump: %r\n<br>\n");
				goto error;
			}
		}else
			goto error;
	}

	hprint(&c->hout, "<pre>type=%d size=%d uncsize=%d score=%V\n", cl.info.type, cl.info.size, cl.info.uncsize, cl.info.score);
	hprint(&c->hout, "encoding=%d creator=%d time=%d %s</pre>\n", cl.encoding, cl.creator, cl.time, fmttime(err, cl.time));
	
	if(cl.info.type == VtCorruptType)
		hprint(&c->hout, "clump is marked corrupt<br>\n");
	
	if(cl.info.size >= VtMaxLumpSize){
		hprint(&c->hout, "clump too big\n");
		goto error;
	}
	
	switch(cl.encoding){
	case ClumpECompress:
		blk2 = vtmalloc(VtMaxLumpSize);
		unwhackinit(&uw);
		n = unwhack(&uw, blk2, cl.info.uncsize, blk+ClumpSize, cl.info.size);
		if(n < 0){
			hprint(&c->hout, "decompression failed\n");
			vtfree(blk2);
			goto error;
		}
		if(n != cl.info.uncsize){
			hprint(&c->hout, "got wrong amount: %d wanted %d\n", n, cl.info.uncsize);
			// hhex(blk2, n);
			vtfree(blk2);
			goto error;
		}
		scoremem(xscore, blk2, cl.info.uncsize);
		vtfree(blk2);
		break;
	case ClumpENone:
		scoremem(xscore, blk+ClumpSize, cl.info.size);
		break;
	}
	
	hprint(&c->hout, "score=%V<br>\n", xscore);
	if(scorestr && scorecmp(score, xscore) != 0)
		hprint(&c->hout, "score does NOT match expected %V\n", score);

	vtfree(blk);
	return 0;

error:
	// hhex(blk, ClumpSize + VtMaxLumpSize);
	vtfree(blk);
	return -1;
}