#include "sam.h"

#define	NSYSFILE	3
#define	NOFILE		128

void
checkqid(File *f)
{
	int i, w;
	File *g;

	w = whichmenu(f);
	for(i=1; i<file.nused; i++){
		g = file.filepptr[i];
		if(w == i)
			continue;
		if(f->dev==g->dev && f->qidpath==g->qidpath)
			warn_SS(Wdupfile, &f->name, &g->name);
	}
}

void
writef(File *f)
{
	Posn n;
	char *name;
	int i, samename, newfile;
	ulong dev;
	uvlong qid;
	long mtime, appendonly, length;

	newfile = 0;
	samename = Strcmp(&genstr, &f->name) == 0;
	name = Strtoc(&f->name);
	i = statfile(name, &dev, &qid, &mtime, 0, 0);
	if(i == -1)
		newfile++;
	else if(samename &&
	        (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
		f->dev = dev;
		f->qidpath = qid;
		f->mtime = mtime;
		warn_S(Wdate, &genstr);
		return;
	}
	if(genc)
		free(genc);
	genc = Strtoc(&genstr);
	if((io=create(genc, 1, 0666L)) < 0)
		error_r(Ecreate, genc);
	dprint("%s: ", genc);
	if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
		error(Eappend);
	n = writeio(f);
	if(f->name.s[0]==0 || samename){
		if(addr.r.p1==0 && addr.r.p2==f->b.nc)
			f->cleanseq = f->seq;
		state(f, f->cleanseq==f->seq? Clean : Dirty);
	}
	if(newfile)
		dprint("(new file) ");
	if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
		warn(Wnotnewline);
	closeio(n);
	if(f->name.s[0]==0 || samename){
		if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
			f->dev = dev;
			f->qidpath = qid;
			f->mtime = mtime;
			checkqid(f);
		}
	}
}

Posn
readio(File *f, int *nulls, int setdate, int toterm)
{
	int n, b, w;
	Rune *r;
	Posn nt;
	Posn p = addr.r.p2;
	ulong dev;
	uvlong qid;
	long mtime;
	char buf[BLOCKSIZE+1], *s;

	*nulls = FALSE;
	b = 0;
	if(f->unread){
		nt = bufload(&f->b, 0, io, nulls);
		if(toterm)
			raspload(f);
	}else
		for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
			n += b;
			b = 0;
			r = genbuf;
			s = buf;
			while(n > 0){
				if((*r = *(uchar*)s) < Runeself){
					if(*r)
						r++;
					else
						*nulls = TRUE;
					--n;
					s++;
					continue;
				}
				if(fullrune(s, n)){
					w = chartorune(r, s);
					if(*r)
						r++;
					else
						*nulls = TRUE;
					n -= w;
					s += w;
					continue;
				}
				b = n;
				memmove(buf, s, b);
				break;
			}
			loginsert(f, p, genbuf, r-genbuf);
		}
	if(b)
		*nulls = TRUE;
	if(*nulls)
		warn(Wnulls);
	if(setdate){
		if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
			f->dev = dev;
			f->qidpath = qid;
			f->mtime = mtime;
			checkqid(f);
		}
	}
	return nt;
}

Posn
writeio(File *f)
{
	int m, n;
	Posn p = addr.r.p1;
	char *c;

	while(p < addr.r.p2){
		if(addr.r.p2-p>BLOCKSIZE)
			n = BLOCKSIZE;
		else
			n = addr.r.p2-p;
		bufread(&f->b, p, genbuf, n);
		c = Strtoc(tmprstr(genbuf, n));
		m = strlen(c);
		if(Write(io, c, m) != m){
			free(c);
			if(p > 0)
				p += n;
			break;
		}
		free(c);
		p += n;
	}
	return p-addr.r.p1;
}
void
closeio(Posn p)
{
	close(io);
	io = 0;
	if(p >= 0)
		dprint("#%lud\n", p);
}

int	remotefd0 = 0;
int	remotefd1 = 1;

void
bootterm(char *machine, char **argv)
{
	int ph2t[2], pt2h[2];

	if(machine){
		dup(remotefd0, 0);
		dup(remotefd1, 1);
		close(remotefd0);
		close(remotefd1);
		argv[0] = "samterm";
		execvp(samterm, argv);
		fprint(2, "can't exec %s: %r\n", samterm);
		_exits("damn");
	}
	if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
		panic("pipe");
	switch(fork()){
	case 0:
		dup(ph2t[0], 0);
		dup(pt2h[1], 1);
		close(ph2t[0]);
		close(ph2t[1]);
		close(pt2h[0]);
		close(pt2h[1]);
		argv[0] = "samterm";
		execvp(samterm, argv);
		fprint(2, "can't exec: ");
		perror(samterm);
		_exits("damn");
	case -1:
		panic("can't fork samterm");
	}
	dup(pt2h[0], 0);
	dup(ph2t[1], 1);
	close(ph2t[0]);
	close(ph2t[1]);
	close(pt2h[0]);
	close(pt2h[1]);
}

void
connectto(char *machine, char **argv)
{
	int p1[2], p2[2];
	char **av;
	int ac;

	// count args
	for(av = argv; *av; av++)
		;
	av = malloc(sizeof(char*)*((av-argv) + 10));
	if(av == nil){
		dprint("out of memory\n");
		exits("fork/exec");
	}
	ac = 0;
	av[ac++] = RX;
	av[ac++] = machine;
	if(rxopt)
		av[ac++] = rxopt;
	av[ac++] = rsamname;
	av[ac++] = "-R";
	while(*argv)
		av[ac++] = *argv++;
	av[ac] = 0;
	if(pipe(p1)<0 || pipe(p2)<0){
		dprint("can't pipe\n");
		exits("pipe");
	}
	remotefd0 = p1[0];
	remotefd1 = p2[1];
	switch(fork()){
	case 0:
		dup(p2[0], 0);
		dup(p1[1], 1);
		close(p1[0]);
		close(p1[1]);
		close(p2[0]);
		close(p2[1]);
		execvp(RXPATH, av);
		dprint("can't exec %s\n", RXPATH);
		exits("exec");

	case -1:
		dprint("can't fork\n");
		exits("fork");
	}
	free(av);
	close(p1[1]);
	close(p2[0]);
}

void
startup(char *machine, int Rflag, char **argv, char **files)
{
	if(machine)
		connectto(machine, files);
	if(!Rflag)
		bootterm(machine, argv);
	downloaded = 1;
	outTs(Hversion, VERSION);
}
