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