#include "stdinc.h"
#include "vac.h"
#include "dat.h"
#include "fns.h"

typedef struct Sink Sink;
typedef struct MetaSink MetaSink;
typedef struct DirSink DirSink;

struct Sink {
	VtSession *z;
	VtEntry dir;
	uchar *buf;
	uchar *pbuf[VtPointerDepth+1];
};

struct DirSink {
	Sink *sink;
	MetaSink *msink;
	ulong nentry;
	uchar *buf;
	uchar *p;	/* current pointer */
	uchar *ep;	/* end pointer */
};

struct MetaSink {
	Sink *sink;
	uchar *buf;
	int maxindex;
	int nindex;
	uchar *rp;	/* start of current record */
	uchar *p;	/* current pointer */
	uchar *ep;	/* end pointer */
};

static void usage(void);
static int strpCmp(void*, void*);
static void warn(char *fmt, ...);
static void cleanup(void);
static u64int unittoull(char *s);
static int vac(VtSession *z, char *argv[]);
static void vacFile(DirSink *dsink, char *lname, char *sname, VacFile*);
static void vacStdin(DirSink *dsink, char *name, VacFile *vf);
static void vacData(DirSink *dsink, int fd, char *lname, VacFile*, Dir*);
static void vacDir(DirSink *dsink, int fd, char *lname, char *sname, VacFile*);
static int vacMerge(DirSink *dsink, char *lname, char *sname);

Sink *sinkAlloc(VtSession *z, int psize, int dsize);
void sinkWrite(Sink *k, uchar *data, int n);
void sinkWriteScore(Sink *k, uchar *score, int n);
void sinkClose(Sink *k);
void sinkFree(Sink *k);

DirSink *dirSinkAlloc(VtSession *z, int psize, int dsize);
void dirSinkWrite(DirSink *k, VtEntry*);
void dirSinkWriteSink(DirSink *k, Sink*);
int dirSinkWriteFile(DirSink *k, VacFile *vf);
void dirSinkClose(DirSink *k);
void dirSinkFree(DirSink *k);

MetaSink *metaSinkAlloc(VtSession *z, int psize, int dsize);
void metaSinkPutc(MetaSink *k, int c);
void metaSinkPutString(MetaSink *k, char *s);
void metaSinkPutUint32(MetaSink *k, ulong x);
void metaSinkPutUint64(MetaSink *k, uvlong x);
void metaSinkWrite(MetaSink *k, uchar *data, int n);
void metaSinkWriteDir(MetaSink *ms, VacDir *vd);
void metaSinkEOR(MetaSink *k);
void metaSinkClose(MetaSink *k);
void metaSinkFree(MetaSink *k);
void plan9ToVacDir(VacDir*, Dir*, ulong entry, uvlong qid);

enum {
	Version = 8,
	BlockSize = 8*1024,
	MaxExclude = 1000
};

struct {
	ulong	file;
	ulong	sfile;
	ulong	data;
	ulong	sdata;
	ulong	skip;
	ulong	meta;
} stats;

int bsize = BlockSize;
int maxbsize;
char *oname, *dfile;
int verbose;
uvlong fileid = 1;
int qdiff;
char *exclude[MaxExclude];
int nexclude;
int nowrite;
int merge;
char *isi;

void
main(int argc, char *argv[])
{
	VtSession *z;
	char *p;
	char *host = nil;
	int statsFlag = 0;

	atexit(cleanup);

	ARGBEGIN{
	default:
		usage();
	case 'b':
		p = ARGF();
		if(p == 0)
			usage();
		bsize = unittoull(p);
		if(bsize == ~0)
			usage();
		break;
	case 'd':
		dfile = ARGF();
		if(dfile == nil)
			usage();
		break;
	case 'e':
		if(nexclude >= MaxExclude)
			sysfatal("too many exclusions\n");
		exclude[nexclude] = ARGF();
		if(exclude[nexclude] == nil)
			usage();
		nexclude++;
		break;
	case 'f':
		oname = ARGF();
		if(oname == 0)
			usage();
		break;
	case 'h':
		host = ARGF();
		if(host == nil)
			usage();
		break;
	case 'i':
		isi = ARGF();
		if(isi == nil)
			usage();
		break;
	case 'n':
		nowrite++;
		break;
	case 'm':
		merge++;
		break;
	case 'q':
		qdiff++;
		break;
	case 's':
		statsFlag++;
		break;
	case 'v':
		verbose++;
		break;
	}ARGEND;

	if(bsize < 512)
		bsize = 512;
	if(bsize > VtMaxLumpSize)
		bsize = VtMaxLumpSize;
	maxbsize = bsize;

	vtAttach();

	fmtinstall('V', vtScoreFmt);
	fmtinstall('R', vtErrFmt);

	z = vtDial(host, 0);
	if(z == nil)
		vtFatal("could not connect to server: %R");

	if(!vtConnect(z, 0))
		vtFatal("vtConnect: %R");

	qsort(exclude, nexclude, sizeof(char*), strpCmp);

	vac(z, argv);
	if(!vtSync(z))
		fprint(2, "warning: could not ask server to flush pending writes: %R\n");

	if(statsFlag)
		fprint(2, "files %ld:%ld data %ld:%ld:%ld meta %ld\n", stats.file, stats.sfile,
			stats.data, stats.skip, stats.sdata, stats.meta);
/*packetStats(); */
	vtClose(z);
	vtDetach();

	exits(0);
}

void
static usage(void)
{
	fprint(2, "usage: %s [-amqsv] [-h host] [-d vacfile] [-b blocksize] [-i name] [-e exclude] [-f vacfile] file ... \n", argv0);
	exits("usage");
}

static
int strpCmp(void *p0, void *p1)
{
	return strcmp(*(char**)p0, *(char**)p1);
}


int
readBlock(int fd, uchar *buf, int n)
{
	int m, t = 0;

	while(t < n){
		m = read(fd, buf+t, n-t);
		if(m < 0)
			return -1;
		if(m == 0)
			break;
		t += m;
	}
	return t;
}

int
vacWrite(VtSession *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
{
assert(n > 0);
	if(nowrite) {
		vtSha1(score, buf, n);
		return 1;
	}
	if(!vtWrite(z, score, type, buf, n))
		return 0;
	if(!vtSha1Check(score, buf, n)) {
		uchar score2[VtScoreSize];
		
		vtSha1(score2, buf, n);
fprint(2, "vtSha1Check: n = %d %V %V\n", n, score, score2);
		vtSetError("vtSha1Check failed");
		return 0;
	}
	return 1;
}


static int
vac(VtSession *z, char *argv[])
{
	DirSink *dsink, *ds;
	MetaSink *ms;
	VtRoot root;
	uchar score[VtScoreSize], buf[VtRootSize];
	char cwd[2048];
	int cd, i;
	char *cp2, *cp;
	VacFS *fs;
	VacFile *vff;
	int fd;
	Dir *dir;
	VacDir vd;

	if(getwd(cwd, sizeof(cwd)) == 0)
		sysfatal("can't find current directory: %r\n");

	dsink = dirSinkAlloc(z, bsize, bsize);

	fs = nil;
	if(dfile != nil) {
		fs = vfsOpen(z, dfile, 1, 10000);
		if(fs == nil)
			fprint(2, "could not open diff: %s: %s\n", dfile, vtGetError());
	}
		

	if(oname != nil) {
		fd = create(oname, OWRITE, 0666);
		if(fd < 0)
			sysfatal("could not create file: %s: %r", oname);
	} else 
		fd = 1;

	dir = dirfstat(fd);
	if(dir == nil)
		sysfatal("dirfstat failed: %r");

	for(; *argv; argv++) {
		cp2 = *argv;
		cd = 0;
		for (cp = *argv; *cp; cp++)
			if (*cp == '/')
				cp2 = cp;
		if (cp2 != *argv) {
			*cp2 = '\0';
			chdir(*argv);
			*cp2 = '/';
			cp2++;
			cd = 1;
		}
		vff = nil;
		if(fs)
			vff = vfOpen(fs, cp2);
		vacFile(dsink, argv[0], cp2, vff);
		if(vff)
			vfDecRef(vff);
		if(cd && chdir(cwd) < 0)
			sysfatal("can't cd back to %s: %r\n", cwd);
	}
	
	if(isi) {
		vff = nil;
		if(fs)
			vff = vfOpen(fs, isi);
		vacStdin(dsink, isi, vff);
		if(vff)
			vfDecRef(vff);
	}

	dirSinkClose(dsink);

	/* build meta information for the root */
	ms = metaSinkAlloc(z, bsize, bsize);
	/* fake into a directory */
	dir->mode |= (dir->mode&0444)>>2;
	dir->qid.type |= QTDIR;
	dir->mode |= DMDIR;
	plan9ToVacDir(&vd, dir, 0, fileid++);
	if(strcmp(vd.elem, "/") == 0){
		vtMemFree(vd.elem);
		vd.elem = vtStrDup("root");
	}
	metaSinkWriteDir(ms, &vd);
	vdCleanup(&vd);
	metaSinkClose(ms);
	
	ds = dirSinkAlloc(z, bsize, bsize);
	dirSinkWriteSink(ds, dsink->sink);
	dirSinkWriteSink(ds, dsink->msink->sink);
	dirSinkWriteSink(ds, ms->sink);
	dirSinkClose(ds);

	memset(&root, 0, sizeof(root));		
	root.version = VtRootVersion;
	strncpy(root.name, dir->name, sizeof(root.name));
	root.name[sizeof(root.name)-1] = 0;
	free(dir);
	sprint(root.type, "vac");
	memmove(root.score, ds->sink->dir.score, VtScoreSize);
	root.blockSize = maxbsize;
	if(fs != nil)
		vfsGetScore(fs, root.prev);

	metaSinkFree(ms);
	dirSinkFree(ds);
	dirSinkFree(dsink);
	if(fs != nil)
		vfsClose(fs);
	
	vtRootPack(&root, buf);
	if(!vacWrite(z, score, VtRootType, buf, VtRootSize))
		vtFatal("vacWrite failed: %s", vtGetError());

	fprint(fd, "vac:");
	for(i=0; i<VtScoreSize; i++)
		fprint(fd, "%.2x", score[i]);
	fprint(fd, "\n");
	
	/* avoid remove at cleanup */
	oname = nil;
	return 1;
}

static int
isExcluded(char *name)
{
	int bot, top, i, x;

	bot = 0;	
	top = nexclude;
	while(bot < top) {
		i = (bot+top)>>1;
		x = strcmp(exclude[i], name);
		if(x == 0)
			return 1;
		if(x < 0)
			bot = i + 1;
		else /* x > 0 */
			top = i;
	}
	return 0;
}

static void
vacFile(DirSink *dsink, char *lname, char *sname, VacFile *vf)
{
	int fd;
	Dir *dir;
	VacDir vd;
	ulong entry;

	if(isExcluded(lname)) {
		warn("excluding: %s", lname);
		return;
	}

	if(merge && vacMerge(dsink, lname, sname))
		return;

	fd = open(sname, OREAD);
	if(fd < 0) {
		warn("could not open file: %s: %s", lname, vtOSError());
		return;
	}

	if(verbose)
		fprint(2, "%s\n", lname);

	dir = dirfstat(fd);
	if(dir == nil) {
		warn("can't stat %s: %r", lname);
		close(fd);
		return;
	}

	entry = dsink->nentry;

	if(dir->mode & DMDIR) 
		vacDir(dsink, fd, lname, sname, vf);
	else
		vacData(dsink, fd, lname, vf, dir);

	plan9ToVacDir(&vd, dir, entry, fileid++);
	metaSinkWriteDir(dsink->msink, &vd);
	vdCleanup(&vd);

	free(dir);
	close(fd);
}

static void
vacStdin(DirSink *dsink, char *name, VacFile *vf)
{
	Dir *dir;
	VacDir vd;
	ulong entry;

	if(verbose)
		fprint(2, "%s\n", "<stdio>");

	dir = dirfstat(0);
	if(dir == nil) {
		warn("can't stat <stdio>: %r");
		return;
	}

	entry = dsink->nentry;

	vacData(dsink, 0, "<stdin>", vf, dir);

	plan9ToVacDir(&vd, dir, entry, fileid++);
	vd.elem = vtStrDup(name);
	metaSinkWriteDir(dsink->msink, &vd);
	vdCleanup(&vd);

	free(dir);
}

static ulong
vacDataSkip(Sink *sink, VacFile *vf, int fd, ulong blocks, uchar *buf, char *lname)
{
	int n;
	ulong i;
	uchar score[VtScoreSize];

	/* skip blocks for append only files */
	if(seek(fd, (blocks-1)*bsize, 0) != (blocks-1)*bsize) {
		warn("error seeking: %s", lname);
		goto Err;
	}
	n = readBlock(fd, buf, bsize);
	if(n < bsize) {
		warn("error checking append only file: %s", lname);
		goto Err;
	}
	if(!vfGetBlockScore(vf, blocks-1, score) || !vtSha1Check(score, buf, n)) {
		warn("last block of append file did not match: %s", lname);
		goto Err;
	}

	for(i=0; i<blocks; i++) {
		if(!vfGetBlockScore(vf, i, score)) {
			warn("could not get score: %s: %lud", lname, i);
			seek(fd, i*bsize, 0);
			return i;
		}
		stats.skip++;
		sinkWriteScore(sink, score, bsize);
	}

	return i;
Err:
	seek(fd, 0, 0);
	return 0;
}

static void
vacData(DirSink *dsink, int fd, char *lname, VacFile *vf, Dir *dir)
{
	uchar *buf;
	Sink *sink;
	int n;
	uchar score[VtScoreSize];
	ulong block, same;
	VacDir vd;
	ulong vfblocks;

	vfblocks = 0;
	if(vf != nil && qdiff) {
		vfGetDir(vf, &vd);
		if(vd.mtime == dir->mtime)
		if(vd.size == dir->length)
		if(!vd.plan9 || /* vd.p9path == dir->qid.path && */ vd.p9version == dir->qid.vers)
		if(dirSinkWriteFile(dsink, vf)) {
			stats.sfile++;
			vdCleanup(&vd);
			return;
		}

		/* look for an append only file */
		if((dir->mode&DMAPPEND) != 0)
		if(vd.size < dir->length)
		if(vd.plan9)
		if(vd.p9path == dir->qid.path)
			vfblocks = vd.size/bsize;

		vdCleanup(&vd);
	}
	stats.file++;

	buf = vtMemAlloc(bsize);
	sink = sinkAlloc(dsink->sink->z, bsize, bsize);
	block = 0;
	same = stats.sdata+stats.skip;

	if(vfblocks > 1)
		block += vacDataSkip(sink, vf, fd, vfblocks, buf, lname);

if(0) fprint(2, "vacData: %s: %ld\n", lname, block);
	for(;;) {
		n = readBlock(fd, buf, bsize);
		if(0 && n < 0)
			warn("file truncated due to read error: %s: %s", lname, vtOSError());
		if(n <= 0)
			break;
		if(vf != nil && vfGetBlockScore(vf, block, score) && vtSha1Check(score, buf, n)) {
			stats.sdata++;
			sinkWriteScore(sink, score, n);
		} else
			sinkWrite(sink, buf, n);
		block++;
	}
	same = stats.sdata+stats.skip - same;

	if(same && (dir->mode&DMAPPEND) != 0)
		if(0)fprint(2, "%s: total %lud same %lud:%lud diff %lud\n",
			lname, block, same, vfblocks, block-same);

	sinkClose(sink);
	dirSinkWriteSink(dsink, sink);
	sinkFree(sink);
	free(buf);
}


static void
vacDir(DirSink *dsink, int fd, char *lname, char *sname, VacFile *vf)
{
	Dir *dirs;
	char *ln, *sn;
	int i, nd;
	DirSink *ds;
	VacFile *vvf;
	char *name;

	ds = dirSinkAlloc(dsink->sink->z, bsize, bsize);
	while((nd = dirread(fd, &dirs)) > 0){
		for(i = 0; i < nd; i++){
			name = dirs[i].name;
			/* check for bad file names */
			if(name[0] == 0 || strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
				continue;
			ln = vtMemAlloc(strlen(lname) + strlen(name) + 2);
			sn = vtMemAlloc(strlen(sname) + strlen(name) + 2);
			sprint(ln, "%s/%s", lname, name);
			sprint(sn, "%s/%s", sname, name);
			if(vf != nil)
				vvf = vfWalk(vf, name);
			else
				vvf = nil;
			vacFile(ds, ln, sn, vvf);
			if(vvf != nil)
				vfDecRef(vvf);
			vtMemFree(ln);
			vtMemFree(sn);
		}
		free(dirs);
	}
	dirSinkClose(ds);
	dirSinkWriteSink(dsink, ds->sink);
	dirSinkWriteSink(dsink, ds->msink->sink);
	dirSinkFree(ds);
}

static int
vacMergeFile(DirSink *dsink, VacFile *vf, VacDir *dir, uvlong offset, uvlong *max)
{
	uchar buf[VtEntrySize];
	VtEntry dd, md;
	int e;

	if(vfRead(vf, buf, VtEntrySize, (uvlong)dir->entry*VtEntrySize) != VtEntrySize) {
		warn("could not read venti dir entry: %s\n", dir->elem);
		return 0;
	}
	vtEntryUnpack(&dd, buf, 0);

	if(dir->mode & ModeDir)	{
		e = dir->mentry;
		if(e == 0)
			e = dir->entry + 1;
		
		if(vfRead(vf, buf, VtEntrySize, e*VtEntrySize) != VtEntrySize) {
			warn("could not read venti dir entry: %s\n", dir->elem);
			return 0;
		}
		vtEntryUnpack(&md, buf, 0);
	}

	/* max might incorrect in some old dumps */
	if(dir->qid >= *max) {
		warn("qid out of range: %s", dir->elem);
		*max = dir->qid;
	}

	dir->qid += offset;
	dir->entry = dsink->nentry;

	if(dir->qidSpace) {
		dir->qidOffset += offset;
	} else {
		dir->qidSpace = 1;
		dir->qidOffset = offset;
		dir->qidMax = *max;
	}

	dirSinkWrite(dsink, &dd);
	if(dir->mode & ModeDir)	
		dirSinkWrite(dsink, &md);
	metaSinkWriteDir(dsink->msink, dir);
	
	return 1;
}

static int
vacMerge(DirSink *dsink, char *lname, char *sname)
{
	char *p;
	VacFS *fs;
	VacFile *vf;
	VacDirEnum *d;
	VacDir dir;
	uvlong max;

	p = strrchr(sname, '.');
	if(p == 0 || strcmp(p, ".vac"))
		return 0;

	d = nil;
	fs = vfsOpen(dsink->sink->z, sname, 1, 100);
	if(fs == nil)
		return 0;

	vf = vfOpen(fs, "/");
	if(vf == nil)
		goto Done;
	max = vfGetId(vf);
	d = vdeOpen(fs, "/");
	if(d == nil)
		goto Done;

	if(verbose)
		fprint(2, "merging: %s\n", lname);

	if(maxbsize < vfsGetBlockSize(fs))
		maxbsize = vfsGetBlockSize(fs);

	for(;;) {
		if(vdeRead(d, &dir, 1) < 1)
			break;
		vacMergeFile(dsink, vf, &dir, fileid, &max);
		vdCleanup(&dir);	
	}
	fileid += max;

Done:
	if(d != nil)
		vdeFree(d);
	if(vf != nil)
		vfDecRef(vf);
	vfsClose(fs);
	return 1;
}

Sink *
sinkAlloc(VtSession *z, int psize, int dsize)
{
	Sink *k;
	int i;

	if(psize < 512 || psize > VtMaxLumpSize)
		vtFatal("sinkAlloc: bad psize");
	if(dsize < 512 || dsize > VtMaxLumpSize)
		vtFatal("sinkAlloc: bad psize");

	psize = VtScoreSize*(psize/VtScoreSize);

	k = vtMemAllocZ(sizeof(Sink));
	k->z = z;
	k->dir.flags = VtEntryActive;
	k->dir.psize = psize;
	k->dir.dsize = dsize;
	k->buf = vtMemAllocZ(VtPointerDepth*k->dir.psize + VtScoreSize);
	for(i=0; i<=VtPointerDepth; i++)
		k->pbuf[i] = k->buf + i*k->dir.psize;
	return k;
}

void
sinkWriteScore(Sink *k, uchar score[VtScoreSize], int n)
{
	int i;
	uchar *p;
	VtEntry *d;

	memmove(k->pbuf[0], score, VtScoreSize);

	d = &k->dir;

	for(i=0; i<VtPointerDepth; i++) {
		k->pbuf[i] += VtScoreSize;
		if(k->pbuf[i] < k->buf + d->psize*(i+1))
			break;
		if(i == VtPointerDepth-1)
			vtFatal("file too big");
		p = k->buf+i*d->psize;
		stats.meta++;
		if(!vacWrite(k->z, k->pbuf[i+1], VtPointerType0+i, p, d->psize))
			vtFatal("vacWrite failed: %s", vtGetError());
		k->pbuf[i] = p;
	}

	/* round size up to multiple of dsize */
	d->size = d->dsize * ((d->size + d->dsize-1)/d->dsize);
	
	d->size += n;
}

void
sinkWrite(Sink *k, uchar *p, int n)
{
	int type;
	uchar score[VtScoreSize];

	if(n > k->dir.dsize)
		vtFatal("sinkWrite: size too big");

	if(k->dir.flags & VtEntryDir) {
		type = VtDirType;
		stats.meta++;
	} else {
		type = VtDataType;
		stats.data++;
	}
	if(!vacWrite(k->z, score, type, p, n))
		vtFatal("vacWrite failed: %s", vtGetError());

	sinkWriteScore(k, score, n);
}

static int
sizeToDepth(uvlong s, int psize, int dsize)
{
	int np;
	int d;
	
	/* determine pointer depth */
	np = psize/VtScoreSize;
	s = (s + dsize - 1)/dsize;
	for(d = 0; s > 1; d++)
		s = (s + np - 1)/np;
	return d;
}

void
sinkClose(Sink *k)
{
	int i, n;
	uchar *p;
	VtEntry *kd;

	kd = &k->dir;

	/* empty */
	if(kd->size == 0) {
		memmove(kd->score, vtZeroScore, VtScoreSize);
		return;
	}

	for(n=VtPointerDepth-1; n>0; n--)
		if(k->pbuf[n] > k->buf + kd->psize*n)
			break;

	kd->depth = sizeToDepth(kd->size, kd->psize, kd->dsize);

	/* skip full part of tree */
	for(i=0; i<n && k->pbuf[i] == k->buf + kd->psize*i; i++)
		;

	/* is the tree completely full */
	if(i == n && k->pbuf[n] == k->buf + kd->psize*n + VtScoreSize) {
		memmove(kd->score, k->pbuf[n] - VtScoreSize, VtScoreSize);
		return;
	}
	n++;

	/* clean up the edge */
	for(; i<n; i++) {
		p = k->buf+i*kd->psize;
		stats.meta++;
		if(!vacWrite(k->z, k->pbuf[i+1], VtPointerType0+i, p, k->pbuf[i]-p))
			vtFatal("vacWrite failed: %s", vtGetError());
		k->pbuf[i+1] += VtScoreSize;
	}
	memmove(kd->score, k->pbuf[i] - VtScoreSize, VtScoreSize);
}

void
sinkFree(Sink *k)
{
	vtMemFree(k->buf);
	vtMemFree(k);
}

DirSink *
dirSinkAlloc(VtSession *z, int psize, int dsize)
{
	DirSink *k;
	int ds;

	ds = VtEntrySize*(dsize/VtEntrySize);

	k = vtMemAllocZ(sizeof(DirSink));
	k->sink = sinkAlloc(z, psize, ds);
	k->sink->dir.flags |= VtEntryDir;
	k->msink = metaSinkAlloc(z, psize, dsize);
	k->buf = vtMemAlloc(ds);
	k->p = k->buf;
	k->ep = k->buf + ds;
	return k;
}

void
dirSinkWrite(DirSink *k, VtEntry *dir)
{
	if(k->p + VtEntrySize > k->ep) {
		sinkWrite(k->sink, k->buf, k->p - k->buf);
		k->p = k->buf;
	}
	vtEntryPack(dir, k->p, 0);
	k->nentry++;
	k->p += VtEntrySize;
}

void
dirSinkWriteSink(DirSink *k, Sink *sink)
{
	dirSinkWrite(k, &sink->dir);
}

int
dirSinkWriteFile(DirSink *k, VacFile *vf)
{
	VtEntry dir;

	if(!vfGetVtEntry(vf, &dir))
		return 0;
	dirSinkWrite(k, &dir);
	return 1;
}

void
dirSinkClose(DirSink *k)
{
	metaSinkClose(k->msink);
	if(k->p != k->buf)
		sinkWrite(k->sink, k->buf, k->p - k->buf);
	sinkClose(k->sink);
}

void
dirSinkFree(DirSink *k)
{
	sinkFree(k->sink);
	metaSinkFree(k->msink);
	vtMemFree(k->buf);
	vtMemFree(k);
}

MetaSink *
metaSinkAlloc(VtSession *z, int psize, int dsize)
{
	MetaSink *k;

	k = vtMemAllocZ(sizeof(MetaSink));
	k->sink = sinkAlloc(z, psize, dsize);
	k->buf = vtMemAlloc(dsize);
	k->maxindex = dsize/100;	/* 100 byte entries seems reasonable */
	if(k->maxindex < 1)
		k->maxindex = 1;
	k->rp = k->p = k->buf + MetaHeaderSize + k->maxindex*MetaIndexSize;
	k->ep = k->buf + dsize;
	return k;
}

/* hack to get base to compare routine - not reentrant */
uchar *blockBase;

int
dirCmp(void *p0, void *p1)
{
	uchar *q0, *q1;
	int n0, n1, r;

	/* name is first element of entry */
	q0 = p0;
	q0 = blockBase + (q0[0]<<8) + q0[1];
	n0 = (q0[6]<<8) + q0[7];
	q0 += 8;

	q1 = p1;
	q1 = blockBase + (q1[0]<<8) + q1[1];
	n1 = (q1[6]<<8) + q1[7];
	q1 += 8;

	if(n0 == n1)
		return memcmp(q0, q1, n0);
	else if (n0 < n1) {
		r = memcmp(q0, q1, n0);
		return (r==0)?1:r;
	} else  {
		r = memcmp(q0, q1, n1);
		return (r==0)?-1:r;
	}
}

void
metaSinkFlush(MetaSink *k)
{
	uchar *p;
	int n;
	MetaBlock mb;

	if(k->nindex == 0)
		return;
	assert(k->nindex <= k->maxindex);

	p = k->buf;
	n = k->rp - p;

	mb.size = n;
	mb.free = 0;
	mb.nindex = k->nindex;
	mb.maxindex = k->maxindex;
	mb.buf = p;
	mbPack(&mb);
	
	p += MetaHeaderSize;

	/* XXX this is not reentrant! */
	blockBase = k->buf;
	qsort(p, k->nindex, MetaIndexSize, dirCmp);
	p += k->nindex*MetaIndexSize;
	
	memset(p, 0, (k->maxindex-k->nindex)*MetaIndexSize);
	p += (k->maxindex-k->nindex)*MetaIndexSize;

	sinkWrite(k->sink, k->buf, n);

	/* move down partial entry */
	n = k->p - k->rp;
	memmove(p, k->rp, n);
	k->rp = p;
	k->p = p + n;
	k->nindex = 0;
}

void
metaSinkPutc(MetaSink *k, int c)
{
	if(k->p+1 > k->ep)
		metaSinkFlush(k);
	if(k->p+1 > k->ep)
		vtFatal("directory entry too large");
	k->p[0] = c;
	k->p++;
}

void
metaSinkPutString(MetaSink *k, char *s)
{
	int n = strlen(s);
	metaSinkPutc(k, n>>8);
	metaSinkPutc(k, n);
	metaSinkWrite(k, (uchar*)s, n);
}

void
metaSinkPutUint32(MetaSink *k, ulong x)
{
	metaSinkPutc(k, x>>24);
	metaSinkPutc(k, x>>16);
	metaSinkPutc(k, x>>8);
	metaSinkPutc(k, x);
}

void
metaSinkPutUint64(MetaSink *k, uvlong x)
{
	metaSinkPutUint32(k, x>>32);
	metaSinkPutUint32(k, x);
}

void
metaSinkWrite(MetaSink *k, uchar *data, int n)
{
	if(k->p + n > k->ep)
		metaSinkFlush(k);
	if(k->p + n > k->ep)
		vtFatal("directory entry too large");
	
	memmove(k->p, data, n);
	k->p += n;
}

void
metaSinkWriteDir(MetaSink *ms, VacDir *dir)
{
	metaSinkPutUint32(ms, DirMagic);
	metaSinkPutc(ms, Version>>8);
	metaSinkPutc(ms, Version);		
	metaSinkPutString(ms, dir->elem);
	metaSinkPutUint32(ms, dir->entry);
	metaSinkPutUint64(ms, dir->qid);
	metaSinkPutString(ms, dir->uid);
	metaSinkPutString(ms, dir->gid);
	metaSinkPutString(ms, dir->mid);
	metaSinkPutUint32(ms, dir->mtime);
	metaSinkPutUint32(ms, dir->mcount);
	metaSinkPutUint32(ms, dir->ctime);
	metaSinkPutUint32(ms, dir->atime);
	metaSinkPutUint32(ms, dir->mode);

	if(dir->plan9) {
		metaSinkPutc(ms, DirPlan9Entry);	/* plan9 extra info */
		metaSinkPutc(ms, 0);			/* plan9 extra size */
		metaSinkPutc(ms, 12);			/* plan9 extra size */
		metaSinkPutUint64(ms, dir->p9path);
		metaSinkPutUint32(ms, dir->p9version);
	}

	if(dir->qidSpace != 0) {
		metaSinkPutc(ms, DirQidSpaceEntry);
		metaSinkPutc(ms, 0);
		metaSinkPutc(ms, 16);
		metaSinkPutUint64(ms, dir->qidOffset);
		metaSinkPutUint64(ms, dir->qidMax);
	}

	if(dir->gen != 0) {
		metaSinkPutc(ms, DirGenEntry);
		metaSinkPutc(ms, 0);
		metaSinkPutc(ms, 4);
		metaSinkPutUint32(ms, dir->gen);
	}

	metaSinkEOR(ms);
}


void
plan9ToVacDir(VacDir *vd, Dir *dir, ulong entry, uvlong qid)
{
	memset(vd, 0, sizeof(VacDir));

	vd->elem = vtStrDup(dir->name);
	vd->entry = entry;
	vd->qid = qid;
	vd->uid = vtStrDup(dir->uid);
	vd->gid = vtStrDup(dir->gid);
	vd->mid = vtStrDup(dir->muid);
	vd->mtime = dir->mtime;
	vd->mcount = 0;
	vd->ctime = dir->mtime;		/* ctime: not available on plan 9 */
	vd->atime = dir->atime;

	vd->mode = dir->mode & 0777;
	if(dir->mode & DMDIR)
		vd->mode |= ModeDir;
	if(dir->mode & DMAPPEND)
		vd->mode |= ModeAppend;
	if(dir->mode & DMEXCL)
		vd->mode |= ModeExclusive;

	vd->plan9 = 1;
	vd->p9path = dir->qid.path;
	vd->p9version = dir->qid.vers;
}


void
metaSinkEOR(MetaSink *k)
{
	uchar *p;
	int o, n;

	p = k->buf + MetaHeaderSize;
	p += k->nindex * MetaIndexSize;
	o = k->rp-k->buf; 	/* offset from start of block */
	n = k->p-k->rp;		/* size of entry */
	p[0] = o >> 8;
	p[1] = o;
	p[2] = n >> 8;
	p[3] = n;
	k->rp = k->p;
	k->nindex++;
	if(k->nindex == k->maxindex)
		metaSinkFlush(k);
}

void
metaSinkClose(MetaSink *k)
{
	metaSinkFlush(k);
	sinkClose(k->sink);
}

void
metaSinkFree(MetaSink *k)
{
	sinkFree(k->sink);
	vtMemFree(k->buf);
	vtMemFree(k);
}

static void
warn(char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	fprint(2, "%s: ", argv0);
	vfprint(2, fmt, arg);
	fprint(2, "\n");
	va_end(arg);
}

static void
cleanup(void)
{
	if(oname != nil)
		remove(oname);
}

#define TWID64	((u64int)~(u64int)0)

static u64int
unittoull(char *s)
{
	char *es;
	u64int n;

	if(s == nil)
		return TWID64;
	n = strtoul(s, &es, 0);
	if(*es == 'k' || *es == 'K'){
		n *= 1024;
		es++;
	}else if(*es == 'm' || *es == 'M'){
		n *= 1024*1024;
		es++;
	}else if(*es == 'g' || *es == 'G'){
		n *= 1024*1024*1024;
		es++;
	}
	if(*es != '\0')
		return TWID64;
	return n;
}
