/*
 * Multiplexor for sftp sessions.
 * Assumes can parse session with sftp> prompts.
 * Assumes clients are well-behaved and don't hang up the system.
 *
 * Stupid sftp bug: sftp invokes ssh, which always set O_NONBLOCK
 * on 0, 1, and 2.  Ssh inherits sftp's 2, so we can't use the output pipe
 * on fd 2, since it will get set O_NONBLOCK, sftp won't notice, and 
 * writes will be lost.  So instead we use a separate pipe for errors
 * and consult it after each command.  Assume the pipe buffer is 
 * big enough to hold the error output.
 */
#include <u.h>
#include <fcntl.h>
#include <libc.h>
#include <bio.h>

#undef pipe

int debug;
#define dprint if(debug)print
int sftpfd;
int sftperr;
Biobuf bin;

void
usage(void)
{
	fprint(2, "usage: sftpcache system\n");
	exits("usage");
}

char*
Brd(Biobuf *bin)
{
	static char buf[1000];
	int c, tot;
	
	tot = 0;
	while((c = Bgetc(bin)) >= 0 && tot<sizeof buf){
		buf[tot++] = c;
		if(c == '\n'){
			buf[tot] = 0;
			dprint("OUT %s", buf);
			return buf;
		}
		if(c == ' ' && tot == 6 && memcmp(buf, "sftp> ", 5) == 0){
			buf[tot] = 0;
			dprint("OUT %s\n", buf);
			return buf;
		}
	}
	if(tot == sizeof buf)
		sysfatal("response too long");
	return nil;
}

int
readstr(int fd, char *a, int n)
{
	int i;
	
	for(i=0; i<n; i++){
		if(read(fd, a+i, 1) != 1)
			return -1;
		if(a[i] == '\n'){
			a[i] = 0;
			return i;
		}
	}
	return n;
}

void
doerrors(int fd)
{
	char buf[100];
	int n, first;
	
	first = 1;
	while((n = read(sftperr, buf, sizeof buf)) > 0){
		if(debug){
			if(first){
				first = 0;
				fprint(2, "OUT errors:\n");
			}
			write(1, buf, n);
		}
		write(fd, buf, n);
	}
}

void
bell(void *x, char *msg)
{
	if(strcmp(msg, "sys: child") == 0 || strcmp(msg, "sys: write on closed pipe") == 0)
		sysfatal("sftp exited");
	if(strcmp(msg, "alarm") == 0)
		noted(NCONT);
	noted(NDFLT);
}

void
main(int argc, char **argv)
{
	char buf[200], cmd[1000], *q, *s;
	char dir[100], ndir[100];
	int p[2], px[2], pe[2], pid, ctl, nctl, fd, n;
	
	notify(bell);
	fmtinstall('H', encodefmt);

	ARGBEGIN{
	case 'D':
		debug = 1;
		break;
	default:
		usage();
	}ARGEND
	
	if(argc != 1)
		usage();
	
	if(pipe(p) < 0 || pipe(px) < 0 || pipe(pe) < 0)
		sysfatal("pipe: %r");
	pid = fork();
	if(pid < 0)
		sysfatal("fork: %r");
	if(pid == 0){
		close(p[1]);
		close(px[0]);
		close(pe[0]);
		dup(p[0], 0);
		dup(px[1], 1);
		dup(pe[1], 2);
		if(p[0] > 2)
			close(p[0]);
		if(px[1] > 2)
			close(px[1]);
		if(pe[1] > 2)
			close(pe[1]);
		execl("sftp", "sftp", "-b", "/dev/stdin", argv[0], nil);
		sysfatal("exec sftp: %r");
	}

	close(p[0]);
	close(px[1]);
	close(pe[1]);

	sftpfd = p[1];
	sftperr = pe[0];
	Binit(&bin, px[0], OREAD);

	fcntl(sftperr, F_SETFL, fcntl(sftperr, F_GETFL, 0)|O_NONBLOCK);

	do
		q = Brd(&bin);
	while(q && strcmp(q, "sftp> ") != 0);
	if(q == nil)
		sysfatal("unexpected eof");

	snprint(buf, sizeof buf, "unix!%s/%s.sftp", getns(), argv[0]);
	ctl = announce(buf, dir);
	if(ctl < 0)
		sysfatal("announce %s: %r", buf);

	pid = fork();
	if(pid < 0)
		sysfatal("fork");
	if(pid != 0)
		exits(nil);
		
	for(;;){
		nctl = listen(dir, ndir);
		if(nctl < 0)
			sysfatal("listen %s: %r", buf);
		fd = accept(ctl, ndir);
		close(nctl);
		if(fd < 0)
			continue;
		for(;;){
		/*	alarm(1000); */
			n = readstr(fd, cmd, sizeof cmd);
		/*	alarm(0); */
			if(n <= 0)
				break;
			dprint("CMD %s\n", cmd);
			if(strcmp(cmd, "DONE") == 0){
				fprint(fd, "DONE\n");
				break;
			}
			fprint(sftpfd, "-%s\n", cmd);
			q = Brd(&bin);
			if(*q==0 || q[strlen(q)-1] != '\n')
				sysfatal("unexpected response");
			q[strlen(q)-1] = 0;
			if(q[0] != '-' || strcmp(q+1, cmd) != 0)
				sysfatal("unexpected response");
			while((q = Brd(&bin)) != nil){
				if(strcmp(q, "sftp> ") == 0){
					doerrors(fd);
					break;
				}
				s = q+strlen(q);
				while(s > q && (s[-1] == ' ' || s[-1] == '\n' || s[-1] == '\t' || s[-1] == '\r'))
					s--;
				*s = 0;
				fprint(fd, "%s\n", q);
			}
			if(q == nil){
				fprint(fd, "!!! unexpected eof\n");
				sysfatal("unexpected eof");
			}
		}
		close(fd);
	}
}

