hlfw.ca

task

ref: 832e8448b3bd0aec97693691c7bd190bf8dcd504
dir: /proj.c/

View raw version
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <plumb.h>

static void
usage(void)
{
	fprint(2, "usage: %s [-p] [-i] [-n nsdir] [-w wdir] [-s srvfile] project\n", argv0);
	exits("usage");
}

void
main(int argc, char **argv)
{
	Plumbmsg *pm;
	char *ename, *arglist[16], **argp;
	char *user, *home, *wdir, *sfile, *plumb, *path;
	int n, nb, fd, stdin, pfd, pipefd[2];
	char buf[64], nsdir[64], pbuf[512];

	argp = arglist;
	home = nil;
	ename = "/bin/exportfs";
	wdir = "/mnt/work";
	sfile = "/srv/work";
	stdin = 0;
	plumb = nil;
	
	*argp++ = "exportfs";
	ARGBEGIN{
	default:
		usage();
	case 'p':
		plumb = EARGF(usage());
		break;
	case 'i':
		stdin = 1;
		break;
	case 'n':
		home = EARGF(usage());
		strcpy(nsdir, home);
		break;
	case 'w':
		wdir = EARGF(usage());
		break;
	case 's':
		sfile = EARGF(usage());
		break;
	}ARGEND

	if(argc != 1 && stdin != 1)
		usage();
	*argp++ = "-r";
	*argp++ = wdir;
	*argp = 0;

	user = getuser();
	if(!home){
		home = getenv("home");
		snprint(nsdir, sizeof nsdir, "%s/lib", home);
	}

	if(stdin){
		n = snprint(buf, sizeof buf, "%s/namespace.", nsdir);
		nb = read(0, buf+n, sizeof buf - n);
		buf[n + nb - 1] = 0;
		path = buf+n;
	} else {
		path = argv[0];
		snprint(buf, sizeof buf, "%s/namespace.%s", nsdir, argv[0]);
	}
	execl("aux/stub", "-d", wdir);
	if(addns(user, buf) < 0){
		fprint(2, "can't addns: %r\n");
		exits("addns");
	}
	if(pipe(pipefd) < 0){
		fprint(2, "can't pipe: %r\n");
		exits("pipe");
	}
	// Probably check for /srv/work existing and delete if so
	if(access(sfile, 0) == 0)
		remove(sfile);
	fd = create(sfile, OWRITE|ORCLOSE, 0600);
	if(fd < 0){
		fprint(2, "can't create /srv/work: %r\n");
		exits("create");
	}
	if(plumb){
		// Messy, blegh.
		snprint(pbuf, sizeof(pbuf), "plumb\n%s\n/mnt/work\ntext\nmessage=%s\n3\nnan", plumb, path);
		pm = plumbunpack(pbuf, strlen(pbuf));
		pfd = plumbopen("send", OWRITE);
		plumbsend(pfd, pm);
		close(pfd);
		//plumbfree(pm);
	}

	fprint(fd, "%d", pipefd[1]);
	close(pipefd[1]);

	switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFFDG)){
	case -1:
		fprint(2, "can't rfork: %r\n");
		exits("rfork");
	case 0:
		dup(pipefd[0], 0);
		dup(pipefd[0], 1);
		close(pipefd[0]);

		exec(ename, arglist);
		fprint(2, "can't exec exportfs: %r\n");
		exits("exec");
	default:
		break;
	}
	exits(0);
}