Beispiel #1
0
int
loadbloom(Bloom *b)
{
	int i, n;
	uint ones;
	uchar *data;
	u32int *a;
	
	data = vtmallocz(b->size);
	if(readpart(b->part, 0, data, b->size) < 0){
		vtfree(b);
		vtfree(data);
		return -1;
	}
	b->data = data;

	a = (u32int*)b->data;
	n = b->size/4;
	ones = 0;
	for(i=0; i<n; i++)
		ones += countbits(a[i]); 
	addstat(StatBloomOnes, ones);

	if(b->size == MaxBloomSize)	/* 2^32 overflows ulong */
		addstat(StatBloomBits, b->size*8-1);
	else
		addstat(StatBloomBits, b->size*8);
		
	return 0;
}
Beispiel #2
0
static vlong
findintoc(HConnect *c, Arena *arena, uchar *score)
{
	uchar *blk;
	int i;
	vlong off;
	vlong coff;
	ClumpInfo ci;

	blk = vtmalloc(arena->blocksize);
	off = arena->base + arena->size;
	coff = 0;
	for(i=0; i<arena->memstats.clumps; i++){
		if(i%arena->clumpmax == 0){
			off -= arena->blocksize;
			if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){
				if(c)
					hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n",
						off);
				break;
			}
		}
		unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize);
		if(scorecmp(ci.score, score) == 0){
			vtfree(blk);
			return coff;
		}
		coff += ClumpSize + ci.size;
	}
	vtfree(blk);
	return -1;
}
Beispiel #3
0
void
deeClose(DirEntryEnum *dee)
{
	int i;
	if(dee == nil)
		return;
	for(i=dee->i; i<dee->n; i++)
		deCleanup(dee->buf+i);
	vtfree(dee->buf);
	fileDecRef(dee->file);
	vtfree(dee);
}
Beispiel #4
0
int
main(int argc, char *argv[])
{
    struct vt  vt ALIGNED(CLSIZE);
//    struct vt *vt;
    long       nrow;
    long       ncol;
//    long       nbufrow;

    memset(&vt, 0, sizeof(struct vt));
    vtgetopt(&vt, argc, argv);
    if (!vtinit(&vt, argc, argv)) {
        fprintf(stderr, "failed to initialise VT\n");

        exit(1);
    }
#if 0
    nbufrow = vt.textbuf.nrow;
    if (!nbufrow) {
        nbufnrow = VTDEFBUFNROW;
    }
#endif
    ncol = vt.state.ncol;
    if (!ncol) {
        ncol = VTDEFNCOL;
        vt.state.ncol = ncol;
    }
    nrow = vt.state.nrow;
    if (!nrow) {
        nrow = VTDEFNROW;
        vt.state.nrow = nrow;
    }
    if (!uiinittextbuf(&vt.textbuf, nrow, ncol, 0)) {
        vtfree(&vt);

        exit(1);
    }
    vtprintinfo(&vt);
#if 0
    vt.state.nrow = 24;
    vt.state.ncol = 80;
    vt.textbuf.nrow = VTDEFBUFNROW;
    vt.textbuf.nrow = 24;
#endif
    vt.state.w = vt.state.ncol * vt.font.boxw;
    vt.state.h = vt.state.nrow * vt.font.boxh;
    vtfree(&vt);

    exit(1);
}
Beispiel #5
0
/* 
 * load clump info group information by scanning entire toc.
 */
static void
loadcig(Arena *arena)
{
	uint32_t i, j, ncig, nci;
	ArenaCIG *cig;
	ClumpInfo *ci;
	uint64_t offset;
	int ms;

	if(arena->cig || arena->ncig < 0)
		return;

//	fprint(2, "loadcig %s\n", arena->name);
	
	ncig = (arena->memstats.clumps+ArenaCIGSize-1) / ArenaCIGSize;
	if(ncig == 0){
		arena->cig = vtmalloc(1);
		arena->ncig = 0;
		return;
	}

	ms = msec();
	cig = vtmalloc(ncig*sizeof cig[0]);
	ci = vtmalloc(ArenaCIGSize*sizeof ci[0]);
	offset = 0;
	for(i=0; i<ncig; i++){
		nci = readclumpinfos(arena, i*ArenaCIGSize, ci, ArenaCIGSize);
		cig[i].offset = offset;
		for(j=0; j<nci; j++)
			offset += ClumpSize + ci[j].size;
		if(nci < ArenaCIGSize){
			if(i != ncig-1){
				vtfree(ci);
				vtfree(cig);
				arena->ncig = -1;
				fprint(2, "loadcig %s: got %ud cigs, expected %ud\n", arena->name, i+1, ncig);
				goto out;
			}
		}
	}
	vtfree(ci);
	
	arena->ncig = ncig;
	arena->cig = cig;

out:
	ms = msec() - ms;
	addstat2(StatCigLoad, 1, StatCigLoadTime, ms);
}
Beispiel #6
0
void
vtrespond(VtReq *r)
{
	Packet *p;
	VtSconn *sc;

	sc = r->sc;
	if(r->rx.tag != r->tx.tag)
		abort();
	if(r->rx.msgtype != r->tx.msgtype+1 && r->rx.msgtype != VtRerror)
		abort();
	if(chattyventi)
		fprint(2, "%s -> %F\n", argv0, &r->rx);
	if((p = vtfcallpack(&r->rx)) == nil){
		vtlog(VtServerLog, "%s: vtfcallpack %F: %r<br>\n", sc->c->addr, &r->rx);
		fprint(2, "fcallpack on %s: %r\n", sc->dir);
		packetfree(p);
		vtfcallclear(&r->rx);
		return;
	}
	vtlog(VtServerLog, "<font size=-1>%T %s:</font> send packet %p (%F)<br>\n", sc->c->addr, p, &r->rx);
	if(vtsend(sc->c, p) < 0)
		fprint(2, "vtsend %F: %r\n", &r->rx);
	scdecref(sc);
	vtfcallclear(&r->tx);
	vtfcallclear(&r->rx);
	vtfree(r);
}
Beispiel #7
0
int
fileMetaFlush(File *f, int rec)
{
	File **kids, *p;
	int nkids;
	int i, rv;

	fileMetaLock(f);
	rv = fileMetaFlush2(f, nil);
	fileMetaUnlock(f);

	if(!rec || !fileIsDir(f))
		return rv;

	if(!fileLock(f))
		return rv;
	nkids = 0;
	for(p=f->down; p; p=p->next)
		nkids++;
	kids = vtmalloc(nkids*sizeof(File*));
	i = 0;
	for(p=f->down; p; p=p->next){
		kids[i++] = p;
		p->ref++;
	}
	fileUnlock(f);

	for(i=0; i<nkids; i++){
		rv |= fileMetaFlush(kids[i], 1);
		fileDecRef(kids[i]);
	}
	vtfree(kids);
	return rv;
}
Beispiel #8
0
Bloom*
readbloom(Part *p)
{
	uchar buf[512];
	Bloom *b;
	
	b = vtmallocz(sizeof *b);
	if(readpart(p, 0, buf, sizeof buf) < 0)
		return nil;
	/*
	 * pass buf as b->data so that bloominit
	 * can parse header.  won't be used for
	 * accessing bits (cleared below).
	 */
	if(bloominit(b, 0, buf) < 0){
		vtfree(b);
		return nil;
	}else{
		/*
		 * default block size is system page size.
		 * the bloom filter is usually very big.
		 * bump the block size up to speed i/o.
		 */
		if(p->blocksize < (1<<20)){
			p->blocksize = 1<<20;
			if(p->blocksize > p->size)
				p->blocksize = p->size;
		}
	}
	b->part = p;
	b->data = nil;
	return b;
}
Beispiel #9
0
static void
fileFree(File *f)
{
	sourceClose(f->source);
	sourceClose(f->msource);
	deCleanup(&f->dir);

	memset(f, ~0, sizeof(File));
	vtfree(f);
}
Beispiel #10
0
static void
scdecref(VtSconn *sc)
{
	qlock(&sc->lk);
	if(--sc->ref > 0){
		qunlock(&sc->lk);
		return;
	}
	if(sc->c)
		vtfreeconn(sc->c);
	vtfree(sc);
}
Beispiel #11
0
void
vtfreeconn(VtConn *z)
{
	vthangup(z);
	qlock(&z->lk);
	/*
	 * Wait for send and recv procs to notice
	 * the hangup and clear out the queues.
	 */
	while(z->readq || z->writeq){
		if(z->readq)
			_vtqhangup(z->readq);
		if(z->writeq)
			_vtqhangup(z->writeq);
		rsleep(&z->rpcfork);
	}
	packetfree(z->part);
	vtfree(z->version);
	vtfree(z->sid);
	qunlock(&z->lk);
	vtfree(z);
}
Beispiel #12
0
static int
deeFill(DirEntryEnum *dee)
{
	int i, n;
	Source *meta, *source;
	MetaBlock mb;
	MetaEntry me;
	File *f;
	Block *b;
	DirEntry *de;

	/* clean up first */
	for(i=dee->i; i<dee->n; i++)
		deCleanup(dee->buf+i);
	vtfree(dee->buf);
	dee->buf = nil;
	dee->i = 0;
	dee->n = 0;

	f = dee->file;

	source = f->source;
	meta = f->msource;

	b = sourceBlock(meta, dee->boff, OReadOnly);
	if(b == nil)
		goto Err;
	if(!mbUnpack(&mb, b->data, meta->dsize))
		goto Err;

	n = mb.nindex;
	dee->buf = vtmalloc(n * sizeof(DirEntry));

	for(i=0; i<n; i++){
		de = dee->buf + i;
		meUnpack(&me, &mb, i);
		if(!deUnpack(de, &me))
			goto Err;
		dee->n++;
		if(!(de->mode & ModeDir))
		if(!dirEntrySize(source, de->entry, de->gen, &de->size))
			goto Err;
	}
	dee->boff++;
	blockPut(b);
	return 1;
Err:
	blockPut(b);
	return 0;
}
Beispiel #13
0
char *
rclunk(Fid *f)
{
	f->busy = 0;
	f->open = 0;
	vtfree(f->user);
	f->user = nil;
	if(f->file)
		vacfiledecref(f->file);
	f->file = nil;
	vdeclose(f->vde);
	f->vde = nil;
	return 0;
}
Beispiel #14
0
int
vtsrvhello(VtConn *z)
{
	VtFcall tx, rx;
	Packet *p;

	if((p = vtrecv(z)) == nil)
		return -1;

	if(vtfcallunpack(&tx, p) < 0){
		packetfree(p);
		return -1;
	}
	packetfree(p);

	if(tx.msgtype != VtThello){
		vtfcallclear(&tx);
		werrstr("bad packet type %d; want Thello %d", tx.msgtype, VtThello);
		return -1;
	}
	if(tx.tag != 0){
		vtfcallclear(&tx);
		werrstr("bad tag in hello");
		return -1;
	}
	if(strcmp(tx.version, z->version) != 0){
		vtfcallclear(&tx);
		werrstr("bad version in hello");
		return -1;
	}
	vtfree(z->uid);
	z->uid = tx.uid;
	tx.uid = nil;
	vtfcallclear(&tx);

	memset(&rx, 0, sizeof rx);
	rx.msgtype = VtRhello;
	rx.tag = tx.tag;
	rx.sid = "anonymous";
	if((p = vtfcallpack(&rx)) == nil)
		return -1;
	if(vtsend(z, p) < 0)
		return -1;

	return 0;
}
Beispiel #15
0
void
vtfileclose(VtFile *r)
{
	if(r == nil)
		return;
	qlock(&r->lk);
	r->ref--;
	if(r->ref){
		qunlock(&r->lk);
		return;
	}
	assert(r->ref == 0);
	qunlock(&r->lk);
	if(r->parent)
		vtfileclose(r->parent);
	memset(r, ~0, sizeof(*r));
	vtfree(r);
}
Beispiel #16
0
void
vtloghlist(Hio *h)
{
	char **p;
	int i, n;
	
	hprint(h, "<html><head>\n");
	hprint(h, "<title>Venti Server Logs</title>\n");
	hprint(h, "</head><body>\n");
	hprint(h, "<b>Venti Server Logs</b>\n<p>\n");
	
	p = vtlognames(&n);
	qsort(p, n, sizeof(p[0]), strpcmp);
	for(i=0; i<n; i++)
		hprint(h, "<a href=\"/log?log=%s\">%s</a><br>\n", p[i], p[i]);
	vtfree(p);
	hprint(h, "</body></html>\n");
}
Beispiel #17
0
void
io(void)
{
	char *err;
	int n;

	for(;;){
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n <= 0)
			break;
		if(convM2S(mdata, n, &rhdr) != n)
			sysfatal("convM2S conversion error");

		if(dflag)
			fprint(2, "vacfs:<-%F\n", &rhdr);

		thdr.data = (char*)mdata + IOHDRSZ;
		if(!fcalls[rhdr.type])
			err = "bad fcall type";
		else
			err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
		if(err){
			thdr.type = Rerror;
			thdr.ename = err;
#ifdef PLAN9PORT
			thdr.errornum = 0;
#endif
		}else{
			thdr.type = rhdr.type + 1;
			thdr.fid = rhdr.fid;
		}
		thdr.tag = rhdr.tag;
		if(dflag)
			fprint(2, "vacfs:->%F\n", &thdr);
		n = convS2M(&thdr, mdata, messagesize);
		if(n <= BIT16SZ)
			sysfatal("convS2M conversion error");
		if(err)
			vtfree(err);

		if(write(mfd[1], mdata, n) != n)
			sysfatal("mount write: %r");
	}
}
Beispiel #18
0
/*
 * f->source and f->msource must NOT be locked.
 * see fileMetaLock.
 */
static void
fileWAccess(File* f, char *mid)
{
	if(f->mode == OReadOnly)
		return;

	fileMetaLock(f);
	f->dir.atime = f->dir.mtime = time(0L);
	if(strcmp(f->dir.mid, mid) != 0){
		vtfree(f->dir.mid);
		f->dir.mid = vtstrdup(mid);
	}
	f->dir.mcount++;
	f->dirty = 1;
	fileMetaUnlock(f);

/*RSC: let's try this */
/*presotto - lets not
	if(f->up)
		fileWAccess(f->up, mid);
*/
}
Beispiel #19
0
static char*
readap(Part *p, ArenaPart *ap)
{
	uchar *blk;
	char *table;
	
	blk = vtmalloc(8192);
	if(readpart(p, PartBlank, blk, 8192) != 8192)
		return nil;
	if(unpackarenapart(ap, blk) < 0){
		werrstr("corrupt arena part header: %r");
		return nil;
	}
	vtfree(blk);
	ap->tabbase = (PartBlank+HeadSize+ap->blocksize-1)&~(ap->blocksize-1);
	ap->tabsize = ap->arenabase - ap->tabbase;
	table = vtmalloc(ap->tabsize+1);
	if(readpart(p, ap->tabbase, (uchar*)table, ap->tabsize) != ap->tabsize){
		werrstr("reading arena part directory: %r");
		return nil;
	}
	table[ap->tabsize] = 0;
	return table;
}
Beispiel #20
0
struct vt *
vtinit(struct vt *vt, int argc, char *argv[])
{
    long  newvt = (vt) ? 0 : 1;
    void *ptr;

    if (!vt) {
        vt = calloc(1, sizeof(struct vt));
        if (!vt) {

            return NULL;
        }
    }
    vt->atr.fd = -1;
    if (!vtinitbuf(vt)
        || !vtinitpty(vt)) {
        vtfree(vt);
        if (newvt) {
            free(vt);
        }

        return NULL;
    }
    vt->state.mode = VTDEFMODE;
    vt->state.fgcolor = VTDEFFGCOLOR;
    vt->state.bgcolor = VTDEFBGCOLOR;
    vt->state.textatr = VTDEFTEXTATR;
    uisetsys(&vt->ui, UI_SYS_XORG);
    uiinit(&vt->ui, argc, argv);
    if (!vtinitcolors(vt)) {
        vtfree(vt);
        if (newvt) {
            free(vt);
        }
        
        return NULL;
    }
    if (!vtinitfonts(vt)) {
        vtfree(vt);
        if (newvt) {
            free(vt);
        }
        
        return NULL;
    }
    ptr = calloc(rounduppow2(vt->state.ncol, 32) >> 5, sizeof(uint32_t));
    if (!ptr) {
        vtfree(vt);
        if (newvt) {
            free(vt);
        }
        
        return NULL;
    }
    vt->state.tabmap = ptr;
    vtinitesc(vt);
    vt->state.scrolltop = 0;
    vt->state.scrollbottom = vt->state.ncol - 1;

    return vt;
}
Beispiel #21
0
static void
periodicFree(Periodic *p)
{
	vtfree(p);
}
Beispiel #22
0
static int
diskarenapart(HConnect *c, char *disk, Part *p)
{
	char *arenaname;
	ArenaPart ap;
	ArenaHead head;
	Arena arena;
	char *table;
	char *score;
	char *clump;
	uchar *blk;
	vlong start, end, off;
	char tbuf[60];

	hprint(&c->hout, "<h1>arena partition %s</h1>\n", disk);

	if((table = readap(p, &ap)) == nil){
		hprint(&c->hout, "%r\n");
		goto out;
	}
	
	hprint(&c->hout, "<pre>\n");
	hprint(&c->hout, "version=%d blocksize=%d base=%d\n",
		ap.version, ap.blocksize, ap.arenabase);
	hprint(&c->hout, "</pre>\n");

	arenaname = hargstr(c, "arena", "");
	if(arenaname[0] == 0){
		diskarenatable(c, disk, table);
		goto out;
	}
	
	if(xfindarena(table, arenaname, &start, &end) < 0){
		hprint(&c->hout, "no such arena %s\n", arenaname);
		goto out;
	}
	
	hprint(&c->hout, "<h2>arena %s</h2>\n", arenaname);
	hprint(&c->hout, "<pre>start=%#llx end=%#llx<pre>\n", start, end);
	if(end < start || end - start < HeadSize){
		hprint(&c->hout, "bad size %#llx\n", end - start);
		goto out;
	}

	// read arena header, tail
	blk = vtmalloc(HeadSize);
	if(readpart(p, start, blk, HeadSize) != HeadSize){
		hprint(&c->hout, "reading header: %r\n");
		vtfree(blk);
		goto out;
	}
	if(unpackarenahead(&head, blk) < 0){
		hprint(&c->hout, "corrupt arena header: %r\n");
		// hhex(blk, HeadSize);
		vtfree(blk);
		goto out;
	}
	vtfree(blk);

	hprint(&c->hout, "head:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s blocksize=%d size=%#llx clumpmagic=%#ux\n",
		head.version, head.name, head.blocksize, head.size, 
		head.clumpmagic);
	hprint(&c->hout, "</pre><br><br>\n");

	if(head.blocksize > MaxIoSize || head.blocksize >= end - start){
		hprint(&c->hout, "corrupt block size %d\n", head.blocksize);
		goto out;
	}

	blk = vtmalloc(head.blocksize);
	if(readpart(p, end - head.blocksize, blk, head.blocksize) < 0){
		hprint(&c->hout, "reading tail: %r\n");
		vtfree(blk);
		goto out;
	}
	memset(&arena, 0, sizeof arena);
	arena.part = p;
	arena.blocksize = head.blocksize;
	arena.clumpmax = head.blocksize / ClumpInfoSize;
	arena.base = start + head.blocksize;
	arena.size = end - start - 2 * head.blocksize;
	if(unpackarena(&arena, blk) < 0){
		vtfree(blk);
		goto out;
	}
	scorecp(arena.score, blk+head.blocksize - VtScoreSize);

	vtfree(blk);
	
	hprint(&c->hout, "tail:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s\n", arena.version, arena.name);
	hprint(&c->hout, "ctime=%d %s\n", arena.ctime, fmttime(tbuf, arena.ctime));
	hprint(&c->hout, "wtime=%d %s\n", arena.wtime, fmttime(tbuf, arena.wtime));
	hprint(&c->hout, "clumpmagic=%#ux\n", arena.clumpmagic);
	hprint(&c->hout, "score %V\n", arena.score);
	hprint(&c->hout, "diskstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.diskstats.clumps, arena.diskstats.cclumps,
		arena.diskstats.used, arena.diskstats.uncsize,
		arena.diskstats.sealed);
	hprint(&c->hout, "memstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.memstats.clumps, arena.memstats.cclumps,
		arena.memstats.used, arena.memstats.uncsize,
		arena.memstats.sealed);
	if(arena.clumpmax == 0){
		hprint(&c->hout, "bad clumpmax\n");
		goto out;
	}

	score = hargstr(c, "score", "");
	clump = hargstr(c, "clump", "");

	if(clump[0]){
		off = strtoull(clump, 0, 0);
		diskarenaclump(c, &arena, off, score[0] ? score : nil);
	}else if(score[0]){
		diskarenaclump(c, &arena, -1, score);
	}else{
		diskarenatoc(c, &arena);
	}

out:
	free(table);
	return 0;
}
Beispiel #23
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;
}
Beispiel #24
0
/*
 * allocate space for the clump and write it,
 * updating the arena directory
ZZZ question: should this distinguish between an arena
filling up and real errors writing the clump?
 */
uint64_t
writeaclump(Arena *arena, Clump *c, uint8_t *clbuf)
{
	DBlock *b;
	uint64_t a, aa;
	uint32_t clump, n, nn, m, off, blocksize;
	int ok;

	n = c->info.size + ClumpSize + U32Size;
	qlock(&arena->lock);
	aa = arena->memstats.used;
	if(arena->memstats.sealed
	|| aa + n + U32Size + arenadirsize(arena, arena->memstats.clumps + 1) > arena->size){
		if(!arena->memstats.sealed){
			logerr(EOk, "seal memstats %s", arena->name);
			arena->memstats.sealed = 1;
			wbarena(arena);
		}
		qunlock(&arena->lock);
		return TWID64;
	}
	if(packclump(c, &clbuf[0], arena->clumpmagic) < 0){
		qunlock(&arena->lock);
		return TWID64;
	}

	/*
	 * write the data out one block at a time
	 */
	blocksize = arena->blocksize;
	a = arena->base + aa;
	off = a & (blocksize - 1);
	a -= off;
	nn = 0;
	for(;;){
		b = getdblock(arena->part, a, off != 0 ? ORDWR : OWRITE);
		if(b == nil){
			qunlock(&arena->lock);
			return TWID64;
		}
		dirtydblock(b, DirtyArena);
		m = blocksize - off;
		if(m > n - nn)
			m = n - nn;
		memmove(&b->data[off], &clbuf[nn], m);
		ok = 0;
		putdblock(b);
		if(ok < 0){
			qunlock(&arena->lock);
			return TWID64;
		}
		nn += m;
		if(nn == n)
			break;
		off = 0;
		a += blocksize;
	}

	arena->memstats.used += c->info.size + ClumpSize;
	arena->memstats.uncsize += c->info.uncsize;
	if(c->info.size < c->info.uncsize)
		arena->memstats.cclumps++;

	clump = arena->memstats.clumps;
	if(clump % ArenaCIGSize == 0){
		if(arena->cig == nil){
			loadcig(arena);
			if(arena->cig == nil)
				goto NoCIG;
		}
		/* add aa as start of next cig */
		if(clump/ArenaCIGSize != arena->ncig){
			fprint(2, "bad arena cig computation %s: writing clump %d but %d cigs\n",
				arena->name, clump, arena->ncig);
			arena->ncig = -1;
			vtfree(arena->cig);
			arena->cig = nil;
			goto NoCIG;
		}
		arena->cig = vtrealloc(arena->cig, (arena->ncig+1)*sizeof arena->cig[0]);
		arena->cig[arena->ncig++].offset = aa;
	}
NoCIG:
	arena->memstats.clumps++;

	if(arena->memstats.clumps == 0)
		sysfatal("clumps wrapped");
	arena->wtime = now();
	if(arena->ctime == 0)
		arena->ctime = arena->wtime;

	writeclumpinfo(arena, clump, &c->info);
	wbarena(arena);

	qunlock(&arena->lock);

	return aa;
}
Beispiel #25
0
void
qfree(Queue *q)
{
	vtfree(q);
}
Beispiel #26
0
int
fileSetDir(File *f, DirEntry *dir, char *uid)
{
	File *ff;
	char *oelem;
	u32int mask;
	u64int size;

	/* can not set permissions for the root */
	if(fileIsRoot(f)){
		werrstr(ERoot);
		return 0;
	}

	if(!fileLock(f))
		return 0;

	if(f->source->mode != OReadWrite){
		werrstr(EReadOnly);
		fileUnlock(f);
		return 0;
	}

	fileMetaLock(f);

	/* check new name does not already exist */
	if(strcmp(f->dir.elem, dir->elem) != 0){
		for(ff = f->up->down; ff; ff=ff->next){
			if(strcmp(dir->elem, ff->dir.elem) == 0 && !ff->removed){
				werrstr(EExists);
				goto Err;
			}
		}

		ff = dirLookup(f->up, dir->elem);
		if(ff != nil){
			fileDecRef(ff);
			werrstr(EExists);
			goto Err;
		}
	}

	if(!sourceLock2(f->source, f->msource, -1))
		goto Err;
	if(!fileIsDir(f)){
		size = sourceGetSize(f->source);
		if(size != dir->size){
			if(!sourceSetSize(f->source, dir->size)){
				sourceUnlock(f->source);
				if(f->msource)
					sourceUnlock(f->msource);
				goto Err;
			}
			/* commited to changing it now */
		}
	}
	/* commited to changing it now */
	if((f->dir.mode&ModeTemporary) != (dir->mode&ModeTemporary))
		fileSetTmp(f, dir->mode&ModeTemporary);
	sourceUnlock(f->source);
	if(f->msource)
		sourceUnlock(f->msource);

	oelem = nil;
	if(strcmp(f->dir.elem, dir->elem) != 0){
		oelem = f->dir.elem;
		f->dir.elem = vtstrdup(dir->elem);
	}

	if(strcmp(f->dir.uid, dir->uid) != 0){
		vtfree(f->dir.uid);
		f->dir.uid = vtstrdup(dir->uid);
	}

	if(strcmp(f->dir.gid, dir->gid) != 0){
		vtfree(f->dir.gid);
		f->dir.gid = vtstrdup(dir->gid);
	}

	f->dir.mtime = dir->mtime;
	f->dir.atime = dir->atime;

//fprint(2, "mode %x %x ", f->dir.mode, dir->mode);
	mask = ~(ModeDir|ModeSnapshot);
	f->dir.mode &= ~mask;
	f->dir.mode |= mask & dir->mode;
	f->dirty = 1;
//fprint(2, "->%x\n", f->dir.mode);

	fileMetaFlush2(f, oelem);
	vtfree(oelem);

	fileMetaUnlock(f);
	fileUnlock(f);

	fileWAccess(f->up, uid);

	return 1;
Err:
	fileMetaUnlock(f);
	fileUnlock(f);
	return 0;
}
Beispiel #27
0
static void
connproc(void *v)
{
	VtSconn *sc;
	VtConn *c;
	Packet *p;
	VtReq *r;
	int fd;
static int first=1;

if(first && chattyventi){
	first=0;
	fmtinstall('F', vtfcallfmt);
}
	r = nil;
	sc = v;
	sc->c = nil;
	if(0) fprint(2, "new call %s on %d\n", sc->dir, sc->ctl);
	fd = accept(sc->ctl, sc->dir);
	close(sc->ctl);
	if(fd < 0){
		fprint(2, "accept %s: %r\n", sc->dir);
		goto out;
	}

	c = vtconn(fd, fd);
	sc->c = c;
	if(vtversion(c) < 0){
		fprint(2, "vtversion %s: %r\n", sc->dir);
		goto out;
	}
	if(vtsrvhello(c) < 0){
		fprint(2, "vtsrvhello %s: %r\n", sc->dir);
		goto out;
	}

	if(0) fprint(2, "new proc %s\n", sc->dir);
	proccreate(vtsendproc, c, STACK);
	qlock(&c->lk);
	while(!c->writeq)
		rsleep(&c->rpcfork);
	qunlock(&c->lk);

	while((p = vtrecv(c)) != nil){
		r = vtmallocz(sizeof(VtReq));
		if(vtfcallunpack(&r->tx, p) < 0){
			vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv bad packet %p: %r<br>\n", c->addr, p);
			fprint(2, "bad packet on %s: %r\n", sc->dir);
			packetfree(p);
			continue;
		}
		vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv packet %p (%F)<br>\n", c->addr, p, &r->tx);
		if(chattyventi)
			fprint(2, "%s <- %F\n", argv0, &r->tx);
		packetfree(p);
		if(r->tx.msgtype == VtTgoodbye)
			break;
		r->rx.tag = r->tx.tag;
		r->sc = sc;
		scincref(sc);
		if(_vtqsend(sc->srv->q, r) < 0){
			scdecref(sc);
			fprint(2, "hungup queue\n");
			break;
		}
		r = nil;
	}

	if(0) fprint(2, "eof on %s\n", sc->dir);

out:
	if(r){
		vtfcallclear(&r->tx);
		vtfree(r);
	}
	if(0) fprint(2, "freed %s\n", sc->dir);
	scdecref(sc);
	return;
}
Beispiel #28
0
Packet*
_vtrpc(VtConn *z, Packet *p, VtFcall *tx)
{
	int i;
	uchar tag, buf[2], *top;
	Rwait *r, *rr;

	/* must malloc because stack could be private */
	r = vtmallocz(sizeof(Rwait));

	qlock(&z->lk);
	r->r.l = &z->lk;
	tag = gettag(z, r);
	if(tx){
		/* vtfcallrpc can't print packet because it doesn't have tag */
		tx->tag = tag;
		if(chattyventi)
			fprint(2, "%s -> %F\n", argv0, tx);
	}

	/* slam tag into packet */
	top = packetpeek(p, buf, 0, 2);
	if(top == nil){
		packetfree(p);
		return nil;
	}
	if(top == buf){
		werrstr("first two bytes must be in same packet fragment");
		packetfree(p);
		vtfree(r);
		return nil;
	}
	top[1] = tag;
	qunlock(&z->lk);
	if(vtsend(z, p) < 0){
		vtfree(r);
		return nil;
	}

	qlock(&z->lk);
	/* wait for the muxer to give us our packet */
	r->sleeping = 1;
	z->nsleep++;
	while(z->muxer && !r->done)
		rsleep(&r->r);
	z->nsleep--;
	r->sleeping = 0;

	/* if not done, there's no muxer: start muxing */
	if(!r->done){
		if(z->muxer)
			abort();
		z->muxer = 1;
		while(!r->done){
			qunlock(&z->lk);
			if((p = vtrecv(z)) == nil){
				werrstr("unexpected eof on venti connection");
				z->muxer = 0;
				vtfree(r);
				return nil;
			}
			qlock(&z->lk);
			muxrpc(z, p);
		}
		z->muxer = 0;
		/* if there is anyone else sleeping, wake first unfinished to mux */
		if(z->nsleep)
		for(i=0; i<256; i++){
			rr = z->wait[i];
			if(rr && rr->sleeping && !rr->done){
				rwakeup(&rr->r);
				break;
			}
		}
	}

	p = r->p;
	puttag(z, r, tag);
	vtfree(r);
	qunlock(&z->lk);
	return p;
}
Beispiel #29
0
int
authCheck(Fcall* t, Fid* fid, Fsys* fsys)
{
	Con *con;
	Fid *afid;
	uchar buf[1];

	/*
	 * Can't lookup with FidWlock here as there may be
	 * protocol to do. Use a separate lock to protect altering
	 * the auth information inside afid.
	 */
	con = fid->con;
	if(t->afid == NOFID){
		/*
		 * If no authentication is asked for, allow
		 * "none" provided the connection has already
		 * been authenticatated.
		 *
		 * The console is allowed to attach without
		 * authentication.
		 */
		rlock(&con->alock);
		if(con->isconsole){
			/* anything goes */
		}else if((con->flags&ConNoneAllow) || con->aok){
			static int noneprint;

			if(noneprint++ < 10)
				consPrint("attach %s as %s: allowing as none\n",
					fsysGetName(fsys), fid->uname);
			vtfree(fid->uname);
			fid->uname = vtstrdup(unamenone);
		}else{
			runlock(&con->alock);
			consPrint("attach %s as %s: connection not authenticated, not console\n",
				fsysGetName(fsys), fid->uname);
			werrstr("cannot attach as none before authentication");
			return 0;
		}
		runlock(&con->alock);

		if((fid->uid = uidByUname(fid->uname)) == nil){
			consPrint("attach %s as %s: unknown uname\n",
				fsysGetName(fsys), fid->uname);
			werrstr("unknown user");
			return 0;
		}
		return 1;
	}

	if((afid = fidGet(con, t->afid, 0)) == nil){
		consPrint("attach %s as %s: bad afid\n",
			fsysGetName(fsys), fid->uname);
		werrstr("bad authentication fid");
		return 0;
	}

	/*
	 * Check valid afid;
	 * check uname and aname match.
	 */
	if(!(afid->qid.type & QTAUTH)){
		consPrint("attach %s as %s: afid not an auth file\n",
			fsysGetName(fsys), fid->uname);
		fidPut(afid);
		werrstr("bad authentication fid");
		return 0;
	}
	if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
		consPrint("attach %s as %s: afid is for %s as %s\n",
			fsysGetName(fsys), fid->uname,
			fsysGetName(afid->fsys), afid->uname);
		fidPut(afid);
		werrstr("attach/auth mismatch");
		return 0;
	}

	qlock(&afid->alock);
	if(afid->cuname == nil){
		if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
			qunlock(&afid->alock);
			consPrint("attach %s as %s: %r\n",
				fsysGetName(fsys), fid->uname);
			fidPut(afid);
			werrstr("fossil authCheck: auth protocol not finished");
			return 0;
		}
	}
	qunlock(&afid->alock);

	assert(fid->uid == nil);
	if((fid->uid = uidByUname(afid->cuname)) == nil){
		consPrint("attach %s as %s: unknown cuname %s\n",
			fsysGetName(fsys), fid->uname, afid->cuname);
		fidPut(afid);
		werrstr("unknown user");
		return 0;
	}

	vtfree(fid->uname);
	fid->uname = vtstrdup(afid->cuname);
	fidPut(afid);

	/*
	 * Allow "none" once the connection has been authenticated.
	 */
	wlock(&con->alock);
	con->aok = 1;
	wunlock(&con->alock);

	return 1;
}
Beispiel #30
0
struct vt *
vtrun(struct vt *vt)
{
    char         *path;
    struct vtbuf *buf;
//    pid_t        pid;

    if (!vt) {
        vt = malloc(sizeof(struct vt));
    }
//    vt-> = vt;
    /* set signals up */
    vtsetsigs();
    /*
     * set input field separator for shell to TAB for old shells that don't
     * reset it. This is for security reasons to prevent users from setting
     * IFS to make system() execute a different program.
     */
    putenv("IFS= \t");
    /* export terminal type */
    putenv("TERM=vt100");
    /* allocate buffer */
    buf = calloc(1, sizeof(struct vtbuf));
    if (!buf) {
        vtfree(vt);
        fprintf(stderr, "out of memory\n");

        exit(1);
    }
    vt->buf = buf;
    /* allocate and read path */
    path = malloc(PATH_MAX);
    if (!path) {
        vtfree(vt);
        fprintf(stderr, "out of memory\n");

        exit(1);
    }
    if (!getcwd(path, PATH_MAX)) {
        vtfree(vt);
        free(path);
        fprintf(stderr, "out of memory\n");

        exit(1);
    }
    vt->path = path;
    /* initialise desktop connection */
    vtinitconn(vt);
    /* initialise terminal screens */
    if (!vtinitscr(vt, TERMNSCREEN)) {
        vtfree(vt);
        free(path);

        exit(1);
    }
    /* initialise terminal windows */
    if (!vtinitwin(vt)) {
        vtfree(vt);
        free(path);
        vtfreescr(vt);

        exit(1);
    }
    /* map terminal windows */
    vtmapwin(vt);
    /* synchronize desktop */
    vtsyncwin(vt);

    return vt;
}