xref: /plan9/sys/src/cmd/import.c (revision 6bbfed0d85c6d7248503ef0614d0f1e40438b735)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier #include <libsec.h>
53e12c5d1SDavid du Colombier 
69a747e4fSDavid du Colombier enum {
79a747e4fSDavid du Colombier 	Encnone,
89a747e4fSDavid du Colombier 	Encssl,
99a747e4fSDavid du Colombier 	Enctls,
109a747e4fSDavid du Colombier };
119a747e4fSDavid du Colombier 
129a747e4fSDavid du Colombier static char *encprotos[] = {
139a747e4fSDavid du Colombier 	[Encnone] =	"clear",
149a747e4fSDavid du Colombier 	[Encssl] =	"ssl",
159a747e4fSDavid du Colombier 	[Enctls] = 	"tls",
169a747e4fSDavid du Colombier 			nil,
179a747e4fSDavid du Colombier };
189a747e4fSDavid du Colombier 
19d9306527SDavid du Colombier char		*keyspec = "";
209a747e4fSDavid du Colombier char		*filterp;
219a747e4fSDavid du Colombier char		*ealgs = "rc4_256 sha1";
229a747e4fSDavid du Colombier int		encproto = Encnone;
239a747e4fSDavid du Colombier char		*aan = "/bin/aan";
249a747e4fSDavid du Colombier AuthInfo 	*ai;
259a747e4fSDavid du Colombier int		debug;
269c06fe1dSDavid du Colombier int		doauth = 1;
27d3907fe5SDavid du Colombier int		timedout;
289a747e4fSDavid du Colombier 
299a747e4fSDavid du Colombier int	connect(char*, char*, int);
3024b9ac62SDavid du Colombier int	passive(void);
319a747e4fSDavid du Colombier int	old9p(int);
327dd7cddfSDavid du Colombier void	catcher(void*, char*);
339a747e4fSDavid du Colombier void	sysfatal(char*, ...);
343e12c5d1SDavid du Colombier void	usage(void);
359a747e4fSDavid du Colombier int	filter(int, char *, char *);
369a747e4fSDavid du Colombier 
379a747e4fSDavid du Colombier static void	mksecret(char *, uchar *);
389a747e4fSDavid du Colombier 
396c54378cSDavid du Colombier /*
406c54378cSDavid du Colombier  * based on libthread's threadsetname, but drags in less library code.
416c54378cSDavid du Colombier  * actually just sets the arguments displayed.
426c54378cSDavid du Colombier  */
436c54378cSDavid du Colombier void
procsetname(char * fmt,...)446c54378cSDavid du Colombier procsetname(char *fmt, ...)
456c54378cSDavid du Colombier {
466c54378cSDavid du Colombier 	int fd;
476c54378cSDavid du Colombier 	char *cmdname;
486c54378cSDavid du Colombier 	char buf[128];
496c54378cSDavid du Colombier 	va_list arg;
506c54378cSDavid du Colombier 
516c54378cSDavid du Colombier 	va_start(arg, fmt);
526c54378cSDavid du Colombier 	cmdname = vsmprint(fmt, arg);
536c54378cSDavid du Colombier 	va_end(arg);
546c54378cSDavid du Colombier 	if (cmdname == nil)
556c54378cSDavid du Colombier 		return;
566c54378cSDavid du Colombier 	snprint(buf, sizeof buf, "#p/%d/args", getpid());
576c54378cSDavid du Colombier 	if((fd = open(buf, OWRITE)) >= 0){
586c54378cSDavid du Colombier 		write(fd, cmdname, strlen(cmdname)+1);
596c54378cSDavid du Colombier 		close(fd);
606c54378cSDavid du Colombier 	}
616c54378cSDavid du Colombier 	free(cmdname);
626c54378cSDavid du Colombier }
636c54378cSDavid du Colombier 
649a747e4fSDavid du Colombier void
post(char * name,char * envname,int srvfd)659a747e4fSDavid du Colombier post(char *name, char *envname, int srvfd)
669a747e4fSDavid du Colombier {
679a747e4fSDavid du Colombier 	int fd;
689a747e4fSDavid du Colombier 	char buf[32];
699a747e4fSDavid du Colombier 
709a747e4fSDavid du Colombier 	fd = create(name, OWRITE, 0600);
719a747e4fSDavid du Colombier 	if(fd < 0)
729a747e4fSDavid du Colombier 		return;
739a747e4fSDavid du Colombier 	sprint(buf, "%d",srvfd);
749a747e4fSDavid du Colombier 	if(write(fd, buf, strlen(buf)) != strlen(buf))
759a747e4fSDavid du Colombier 		sysfatal("srv write: %r");
769a747e4fSDavid du Colombier 	close(fd);
779a747e4fSDavid du Colombier 	putenv(envname, name);
789a747e4fSDavid du Colombier }
799a747e4fSDavid du Colombier 
809a747e4fSDavid du Colombier static int
lookup(char * s,char * l[])819a747e4fSDavid du Colombier lookup(char *s, char *l[])
829a747e4fSDavid du Colombier {
839a747e4fSDavid du Colombier 	int i;
849a747e4fSDavid du Colombier 
859a747e4fSDavid du Colombier 	for (i = 0; l[i] != 0; i++)
869a747e4fSDavid du Colombier 		if (strcmp(l[i], s) == 0)
879a747e4fSDavid du Colombier 			return i;
889a747e4fSDavid du Colombier 	return -1;
899a747e4fSDavid du Colombier }
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier void
main(int argc,char ** argv)923e12c5d1SDavid du Colombier main(int argc, char **argv)
933e12c5d1SDavid du Colombier {
946c54378cSDavid du Colombier 	char *mntpt, *srvpost, srvfile[64];
95*6bbfed0dSDavid du Colombier 	int backwards = 0, fd, mntflags, oldserver, notree;
963e12c5d1SDavid du Colombier 
976c54378cSDavid du Colombier 	quotefmtinstall();
989a747e4fSDavid du Colombier 	srvpost = nil;
999a747e4fSDavid du Colombier 	oldserver = 0;
100*6bbfed0dSDavid du Colombier 	notree = 0;
1013e12c5d1SDavid du Colombier 	mntflags = MREPL;
1023e12c5d1SDavid du Colombier 	ARGBEGIN{
1039c06fe1dSDavid du Colombier 	case 'A':
1049c06fe1dSDavid du Colombier 		doauth = 0;
1059c06fe1dSDavid du Colombier 		break;
1063e12c5d1SDavid du Colombier 	case 'a':
1073e12c5d1SDavid du Colombier 		mntflags = MAFTER;
1083e12c5d1SDavid du Colombier 		break;
1093e12c5d1SDavid du Colombier 	case 'b':
1103e12c5d1SDavid du Colombier 		mntflags = MBEFORE;
1113e12c5d1SDavid du Colombier 		break;
1123e12c5d1SDavid du Colombier 	case 'c':
1133e12c5d1SDavid du Colombier 		mntflags |= MCREATE;
1143e12c5d1SDavid du Colombier 		break;
11580ee5cbfSDavid du Colombier 	case 'C':
11680ee5cbfSDavid du Colombier 		mntflags |= MCACHE;
11780ee5cbfSDavid du Colombier 		break;
1189a747e4fSDavid du Colombier 	case 'd':
1199a747e4fSDavid du Colombier 		debug++;
1209a747e4fSDavid du Colombier 		break;
1217dd7cddfSDavid du Colombier 	case 'f':
1229a747e4fSDavid du Colombier 		/* ignored but allowed for compatibility */
1239a747e4fSDavid du Colombier 		break;
1249a747e4fSDavid du Colombier 	case 'O':
1259a747e4fSDavid du Colombier 	case 'o':
1269a747e4fSDavid du Colombier 		oldserver = 1;
1279a747e4fSDavid du Colombier 		break;
1289a747e4fSDavid du Colombier 	case 'E':
1299a747e4fSDavid du Colombier 		if ((encproto = lookup(EARGF(usage()), encprotos)) < 0)
1309a747e4fSDavid du Colombier 			usage();
1319a747e4fSDavid du Colombier 		break;
1329a747e4fSDavid du Colombier 	case 'e':
133d9306527SDavid du Colombier 		ealgs = EARGF(usage());
1349a747e4fSDavid du Colombier 		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
1359a747e4fSDavid du Colombier 			ealgs = nil;
1369a747e4fSDavid du Colombier 		break;
137d9306527SDavid du Colombier 	case 'k':
138d9306527SDavid du Colombier 		keyspec = EARGF(usage());
139d9306527SDavid du Colombier 		break;
1409a747e4fSDavid du Colombier 	case 'p':
1419a747e4fSDavid du Colombier 		filterp = aan;
1429a747e4fSDavid du Colombier 		break;
1439a747e4fSDavid du Colombier 	case 's':
144d9306527SDavid du Colombier 		srvpost = EARGF(usage());
1457dd7cddfSDavid du Colombier 		break;
14624b9ac62SDavid du Colombier 	case 'B':
14724b9ac62SDavid du Colombier 		backwards = 1;
14824b9ac62SDavid du Colombier 		break;
149*6bbfed0dSDavid du Colombier 	case 'm':
150*6bbfed0dSDavid du Colombier 		notree = 1;
151*6bbfed0dSDavid du Colombier 		break;
1523e12c5d1SDavid du Colombier 	default:
1533e12c5d1SDavid du Colombier 		usage();
1543e12c5d1SDavid du Colombier 	}ARGEND;
1553e12c5d1SDavid du Colombier 
15624b9ac62SDavid du Colombier 	mntpt = 0;		/* to shut up compiler */
15724b9ac62SDavid du Colombier 	if(backwards){
15824b9ac62SDavid du Colombier 		switch(argc) {
159da51d93aSDavid du Colombier 		default:
16024b9ac62SDavid du Colombier 			mntpt = argv[0];
16124b9ac62SDavid du Colombier 			break;
162da51d93aSDavid du Colombier 		case 0:
16324b9ac62SDavid du Colombier 			usage();
16424b9ac62SDavid du Colombier 		}
16524b9ac62SDavid du Colombier 	} else {
1663e12c5d1SDavid du Colombier 		switch(argc) {
1673e12c5d1SDavid du Colombier 		case 2:
1683e12c5d1SDavid du Colombier 			mntpt = argv[1];
1693e12c5d1SDavid du Colombier 			break;
1703e12c5d1SDavid du Colombier 		case 3:
171*6bbfed0dSDavid du Colombier 			if(notree)
172*6bbfed0dSDavid du Colombier 				usage();
1733e12c5d1SDavid du Colombier 			mntpt = argv[2];
1743e12c5d1SDavid du Colombier 			break;
1753e12c5d1SDavid du Colombier 		default:
1763e12c5d1SDavid du Colombier 			usage();
1773e12c5d1SDavid du Colombier 		}
17824b9ac62SDavid du Colombier 	}
1793e12c5d1SDavid du Colombier 
1809a747e4fSDavid du Colombier 	if (encproto == Enctls)
18114cc0f53SDavid du Colombier 		sysfatal("%s: tls has not yet been implemented", argv[0]);
1829a747e4fSDavid du Colombier 
1837dd7cddfSDavid du Colombier 	notify(catcher);
184219b2ee8SDavid du Colombier 	alarm(60*1000);
18524b9ac62SDavid du Colombier 
18624b9ac62SDavid du Colombier 	if(backwards)
18724b9ac62SDavid du Colombier 		fd = passive();
188*6bbfed0dSDavid du Colombier 	else if(notree)
189*6bbfed0dSDavid du Colombier 		fd = connect(argv[0], nil, oldserver);
19024b9ac62SDavid du Colombier 	else
1919a747e4fSDavid du Colombier 		fd = connect(argv[0], argv[1], oldserver);
1927dd7cddfSDavid du Colombier 
1939a747e4fSDavid du Colombier 	if (!oldserver)
1946c54378cSDavid du Colombier 		fprint(fd, "impo %s %s\n", filterp? "aan": "nofilter",
1956c54378cSDavid du Colombier 			encprotos[encproto]);
1969a747e4fSDavid du Colombier 
1979a747e4fSDavid du Colombier 	if (encproto != Encnone && ealgs && ai) {
1989a747e4fSDavid du Colombier 		uchar key[16];
1999a747e4fSDavid du Colombier 		uchar digest[SHA1dlen];
2009a747e4fSDavid du Colombier 		char fromclientsecret[21];
2019a747e4fSDavid du Colombier 		char fromserversecret[21];
2029a747e4fSDavid du Colombier 		int i;
2039a747e4fSDavid du Colombier 
2049a747e4fSDavid du Colombier 		memmove(key+4, ai->secret, ai->nsecret);
2059a747e4fSDavid du Colombier 
2069a747e4fSDavid du Colombier 		/* exchange random numbers */
2079a747e4fSDavid du Colombier 		srand(truerand());
2089a747e4fSDavid du Colombier 		for(i = 0; i < 4; i++)
2099a747e4fSDavid du Colombier 			key[i] = rand();
2109a747e4fSDavid du Colombier 		if(write(fd, key, 4) != 4)
2119a747e4fSDavid du Colombier 			sysfatal("can't write key part: %r");
2129a747e4fSDavid du Colombier 		if(readn(fd, key+12, 4) != 4)
2139a747e4fSDavid du Colombier 			sysfatal("can't read key part: %r");
2149a747e4fSDavid du Colombier 
2159a747e4fSDavid du Colombier 		/* scramble into two secrets */
2169a747e4fSDavid du Colombier 		sha1(key, sizeof(key), digest, nil);
2179a747e4fSDavid du Colombier 		mksecret(fromclientsecret, digest);
2189a747e4fSDavid du Colombier 		mksecret(fromserversecret, digest+10);
2199a747e4fSDavid du Colombier 
2209a747e4fSDavid du Colombier 		if (filterp)
2219a747e4fSDavid du Colombier 			fd = filter(fd, filterp, argv[0]);
2229a747e4fSDavid du Colombier 
2239a747e4fSDavid du Colombier 		/* set up encryption */
2246c54378cSDavid du Colombier 		procsetname("pushssl");
2259a747e4fSDavid du Colombier 		fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
2269a747e4fSDavid du Colombier 		if(fd < 0)
2279a747e4fSDavid du Colombier 			sysfatal("can't establish ssl connection: %r");
2289a747e4fSDavid du Colombier 	}
2299a747e4fSDavid du Colombier 	else if (filterp)
2309a747e4fSDavid du Colombier 		fd = filter(fd, filterp, argv[0]);
2319a747e4fSDavid du Colombier 
2329a747e4fSDavid du Colombier 	if(srvpost){
2339a747e4fSDavid du Colombier 		sprint(srvfile, "/srv/%s", srvpost);
2349a747e4fSDavid du Colombier 		remove(srvfile);
2359a747e4fSDavid du Colombier 		post(srvfile, srvpost, fd);
2369a747e4fSDavid du Colombier 	}
2376c54378cSDavid du Colombier 	procsetname("mount on %s", mntpt);
2389a747e4fSDavid du Colombier 	if(mount(fd, -1, mntpt, mntflags, "") < 0)
2399a747e4fSDavid du Colombier 		sysfatal("can't mount %s: %r", argv[1]);
240219b2ee8SDavid du Colombier 	alarm(0);
241da51d93aSDavid du Colombier 
242da51d93aSDavid du Colombier 	if(backwards && argc > 1){
2435a6005aaSDavid du Colombier 		exec(argv[1], &argv[1]);
244da51d93aSDavid du Colombier 		sysfatal("exec: %r");
245da51d93aSDavid du Colombier 	}
2463e12c5d1SDavid du Colombier 	exits(0);
2473e12c5d1SDavid du Colombier }
2483e12c5d1SDavid du Colombier 
2497dd7cddfSDavid du Colombier void
catcher(void *,char * msg)2507dd7cddfSDavid du Colombier catcher(void*, char *msg)
2517dd7cddfSDavid du Colombier {
252d3907fe5SDavid du Colombier 	timedout = 1;
2537dd7cddfSDavid du Colombier 	if(strcmp(msg, "alarm") == 0)
2547dd7cddfSDavid du Colombier 		noted(NCONT);
2557dd7cddfSDavid du Colombier 	noted(NDFLT);
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier 
2583e12c5d1SDavid du Colombier int
old9p(int fd)2599a747e4fSDavid du Colombier old9p(int fd)
2607dd7cddfSDavid du Colombier {
2617dd7cddfSDavid du Colombier 	int p[2];
2627dd7cddfSDavid du Colombier 
2636c54378cSDavid du Colombier 	procsetname("old9p");
2647dd7cddfSDavid du Colombier 	if(pipe(p) < 0)
2659a747e4fSDavid du Colombier 		sysfatal("pipe: %r");
2667dd7cddfSDavid du Colombier 
2679a747e4fSDavid du Colombier 	switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
2687dd7cddfSDavid du Colombier 	case -1:
2699a747e4fSDavid du Colombier 		sysfatal("rfork srvold9p: %r");
2707dd7cddfSDavid du Colombier 	case 0:
2719a747e4fSDavid du Colombier 		if(fd != 1){
2727dd7cddfSDavid du Colombier 			dup(fd, 1);
2737dd7cddfSDavid du Colombier 			close(fd);
2749a747e4fSDavid du Colombier 		}
2759a747e4fSDavid du Colombier 		if(p[0] != 0){
2767dd7cddfSDavid du Colombier 			dup(p[0], 0);
2777dd7cddfSDavid du Colombier 			close(p[0]);
2789a747e4fSDavid du Colombier 		}
2797dd7cddfSDavid du Colombier 		close(p[1]);
2809a747e4fSDavid du Colombier 		if(0){
2819a747e4fSDavid du Colombier 			fd = open("/sys/log/cpu", OWRITE);
2829a747e4fSDavid du Colombier 			if(fd != 2){
2839a747e4fSDavid du Colombier 				dup(fd, 2);
2849a747e4fSDavid du Colombier 				close(fd);
2859a747e4fSDavid du Colombier 			}
286f19e7b74SDavid du Colombier 			execl("/bin/srvold9p", "srvold9p", "-ds", nil);
2879a747e4fSDavid du Colombier 		} else
288f19e7b74SDavid du Colombier 			execl("/bin/srvold9p", "srvold9p", "-s", nil);
2899a747e4fSDavid du Colombier 		sysfatal("exec srvold9p: %r");
2907dd7cddfSDavid du Colombier 	default:
2917dd7cddfSDavid du Colombier 		close(fd);
2927dd7cddfSDavid du Colombier 		close(p[0]);
2937dd7cddfSDavid du Colombier 	}
2947dd7cddfSDavid du Colombier 	return p[1];
2957dd7cddfSDavid du Colombier }
2969a747e4fSDavid du Colombier 
2979a747e4fSDavid du Colombier int
connect(char * system,char * tree,int oldserver)2989a747e4fSDavid du Colombier connect(char *system, char *tree, int oldserver)
2999a747e4fSDavid du Colombier {
3009a747e4fSDavid du Colombier 	char buf[ERRMAX], dir[128], *na;
3019a747e4fSDavid du Colombier 	int fd, n;
3029a747e4fSDavid du Colombier 	char *authp;
3039a747e4fSDavid du Colombier 
3049a747e4fSDavid du Colombier 	na = netmkaddr(system, 0, "exportfs");
3056c54378cSDavid du Colombier 	procsetname("dial %s", na);
3069a747e4fSDavid du Colombier 	if((fd = dial(na, 0, dir, 0)) < 0)
3079a747e4fSDavid du Colombier 		sysfatal("can't dial %s: %r", system);
3089a747e4fSDavid du Colombier 
3099c06fe1dSDavid du Colombier 	if(doauth){
3109a747e4fSDavid du Colombier 		if(oldserver)
3119a747e4fSDavid du Colombier 			authp = "p9sk2";
3129a747e4fSDavid du Colombier 		else
3139a747e4fSDavid du Colombier 			authp = "p9any";
3149a747e4fSDavid du Colombier 
3156c54378cSDavid du Colombier 		procsetname("auth_proxy auth_getkey proto=%q role=client %s",
3166c54378cSDavid du Colombier 			authp, keyspec);
317d3907fe5SDavid du Colombier 		ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s",
318d3907fe5SDavid du Colombier 			authp, keyspec);
3199a747e4fSDavid du Colombier 		if(ai == nil)
3209a747e4fSDavid du Colombier 			sysfatal("%r: %s", system);
3219c06fe1dSDavid du Colombier 	}
3229a747e4fSDavid du Colombier 
323*6bbfed0dSDavid du Colombier 	if(tree != nil){
3246c54378cSDavid du Colombier 		procsetname("writing tree name %s", tree);
3259a747e4fSDavid du Colombier 		n = write(fd, tree, strlen(tree));
3269a747e4fSDavid du Colombier 		if(n < 0)
3279a747e4fSDavid du Colombier 			sysfatal("can't write tree: %r");
3289a747e4fSDavid du Colombier 
3299a747e4fSDavid du Colombier 		strcpy(buf, "can't read tree");
3309a747e4fSDavid du Colombier 
3316c54378cSDavid du Colombier 		procsetname("awaiting OK for %s", tree);
3329a747e4fSDavid du Colombier 		n = read(fd, buf, sizeof buf - 1);
3339a747e4fSDavid du Colombier 		if(n!=2 || buf[0]!='O' || buf[1]!='K'){
334d3907fe5SDavid du Colombier 			if (timedout)
335d3907fe5SDavid du Colombier 				sysfatal("timed out connecting to %s", na);
3369a747e4fSDavid du Colombier 			buf[sizeof buf - 1] = '\0';
3379a747e4fSDavid du Colombier 			sysfatal("bad remote tree: %s", buf);
3389a747e4fSDavid du Colombier 		}
339*6bbfed0dSDavid du Colombier 	}
3409a747e4fSDavid du Colombier 
3419a747e4fSDavid du Colombier 	if(oldserver)
3429a747e4fSDavid du Colombier 		return old9p(fd);
3439a747e4fSDavid du Colombier 	return fd;
3449a747e4fSDavid du Colombier }
3459a747e4fSDavid du Colombier 
34624b9ac62SDavid du Colombier int
passive(void)34724b9ac62SDavid du Colombier passive(void)
34824b9ac62SDavid du Colombier {
34924b9ac62SDavid du Colombier 	int fd;
35024b9ac62SDavid du Colombier 
3519c06fe1dSDavid du Colombier 	/*
3529c06fe1dSDavid du Colombier 	 * Ignore doauth==0 on purpose.  Is it useful here?
3539c06fe1dSDavid du Colombier 	 */
3549c06fe1dSDavid du Colombier 
3556c54378cSDavid du Colombier 	procsetname("auth_proxy auth_getkey proto=p9any role=server");
35624b9ac62SDavid du Colombier 	ai = auth_proxy(0, auth_getkey, "proto=p9any role=server");
35724b9ac62SDavid du Colombier 	if(ai == nil)
35824b9ac62SDavid du Colombier 		sysfatal("auth_proxy: %r");
35924b9ac62SDavid du Colombier 	if(auth_chuid(ai, nil) < 0)
36024b9ac62SDavid du Colombier 		sysfatal("auth_chuid: %r");
36124b9ac62SDavid du Colombier 	putenv("service", "import");
36224b9ac62SDavid du Colombier 
36324b9ac62SDavid du Colombier 	fd = dup(0, -1);
36424b9ac62SDavid du Colombier 	close(0);
365da51d93aSDavid du Colombier 	open("/dev/null", ORDWR);
36624b9ac62SDavid du Colombier 	close(1);
367da51d93aSDavid du Colombier 	open("/dev/null", ORDWR);
36824b9ac62SDavid du Colombier 
36924b9ac62SDavid du Colombier 	return fd;
37024b9ac62SDavid du Colombier }
37124b9ac62SDavid du Colombier 
3729a747e4fSDavid du Colombier void
usage(void)3739a747e4fSDavid du Colombier usage(void)
3749a747e4fSDavid du Colombier {
375*6bbfed0dSDavid du Colombier 	fprint(2, "usage: import [-abcCm] [-A] [-E clear|ssl|tls] "
3766c54378cSDavid du Colombier "[-e 'crypt auth'|clear] [-k keypattern] [-p] host remotefs [mountpoint]\n");
3779a747e4fSDavid du Colombier 	exits("usage");
3789a747e4fSDavid du Colombier }
3799a747e4fSDavid du Colombier 
3809a747e4fSDavid du Colombier /* Network on fd1, mount driver on fd0 */
3819a747e4fSDavid du Colombier int
filter(int fd,char * cmd,char * host)3829a747e4fSDavid du Colombier filter(int fd, char *cmd, char *host)
3839a747e4fSDavid du Colombier {
3849a747e4fSDavid du Colombier 	int p[2], len, argc;
3859a747e4fSDavid du Colombier 	char newport[256], buf[256], *s;
3869a747e4fSDavid du Colombier 	char *argv[16], *file, *pbuf;
3879a747e4fSDavid du Colombier 
3889a747e4fSDavid du Colombier 	if ((len = read(fd, newport, sizeof newport - 1)) < 0)
38914cc0f53SDavid du Colombier 		sysfatal("filter: cannot write port; %r");
3909a747e4fSDavid du Colombier 	newport[len] = '\0';
3919a747e4fSDavid du Colombier 
3929a747e4fSDavid du Colombier 	if ((s = strchr(newport, '!')) == nil)
39314cc0f53SDavid du Colombier 		sysfatal("filter: illegally formatted port %s", newport);
3949a747e4fSDavid du Colombier 
3954d44ba9bSDavid du Colombier 	strecpy(buf, buf+sizeof buf, netmkaddr(host, "tcp", "0"));
3969a747e4fSDavid du Colombier 	pbuf = strrchr(buf, '!');
3974d44ba9bSDavid du Colombier 	strecpy(pbuf, buf+sizeof buf, s);
3989a747e4fSDavid du Colombier 
3999a747e4fSDavid du Colombier 	if(debug)
4009a747e4fSDavid du Colombier 		fprint(2, "filter: remote port %s\n", newport);
4019a747e4fSDavid du Colombier 
4029a747e4fSDavid du Colombier 	argc = tokenize(cmd, argv, nelem(argv)-2);
4039a747e4fSDavid du Colombier 	if (argc == 0)
4049a747e4fSDavid du Colombier 		sysfatal("filter: empty command");
4059a747e4fSDavid du Colombier 	argv[argc++] = "-c";
4069a747e4fSDavid du Colombier 	argv[argc++] = buf;
4079a747e4fSDavid du Colombier 	argv[argc] = nil;
4089a747e4fSDavid du Colombier 	file = argv[0];
4099a747e4fSDavid du Colombier 	if (s = strrchr(argv[0], '/'))
4109a747e4fSDavid du Colombier 		argv[0] = s+1;
4119a747e4fSDavid du Colombier 
4129a747e4fSDavid du Colombier 	if(pipe(p) < 0)
4139a747e4fSDavid du Colombier 		sysfatal("pipe: %r");
4149a747e4fSDavid du Colombier 
4159a747e4fSDavid du Colombier 	switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {
4169a747e4fSDavid du Colombier 	case -1:
4179a747e4fSDavid du Colombier 		sysfatal("rfork record module: %r");
4189a747e4fSDavid du Colombier 	case 0:
4199a747e4fSDavid du Colombier 		dup(p[0], 1);
4209a747e4fSDavid du Colombier 		dup(p[0], 0);
4219a747e4fSDavid du Colombier 		close(p[0]);
4229a747e4fSDavid du Colombier 		close(p[1]);
4239a747e4fSDavid du Colombier 		exec(file, argv);
4249a747e4fSDavid du Colombier 		sysfatal("exec record module: %r");
4259a747e4fSDavid du Colombier 	default:
4269a747e4fSDavid du Colombier 		close(fd);
4279a747e4fSDavid du Colombier 		close(p[0]);
4289a747e4fSDavid du Colombier 	}
4299a747e4fSDavid du Colombier 	return p[1];
4309a747e4fSDavid du Colombier }
4319a747e4fSDavid du Colombier 
4329a747e4fSDavid du Colombier static void
mksecret(char * t,uchar * f)4339a747e4fSDavid du Colombier mksecret(char *t, uchar *f)
4349a747e4fSDavid du Colombier {
4359a747e4fSDavid du Colombier 	sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
4369a747e4fSDavid du Colombier 		f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
4379a747e4fSDavid du Colombier }
438