URI:
       t9import.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       t9import.c (4391B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <auth.h>
            4 #include <thread.h>
            5 
            6 enum {
            7         Encnone,
            8         Encssl,
            9         Enctls,
           10 };
           11 
           12 static char *encprotos[] = {
           13         [Encnone] =        "clear",
           14         [Encssl] =        "ssl",
           15         [Enctls] =         "tls",
           16                         nil,
           17 };
           18 
           19 char                *keyspec = "";
           20 char                *filterp;
           21 char                *ealgs = "rc4_256 sha1";
           22 int                encproto = Encnone;
           23 AuthInfo         *ai;
           24 int                debug;
           25 int                doauth = 1;
           26 int                timedout;
           27 
           28 int        connectez(char*, char*);
           29 void        sysfatal(char*, ...);
           30 void        usage(void);
           31 int        filter(int, char *, char *);
           32 
           33 int
           34 catcher(void *v, char *msg)
           35 {
           36         timedout = 1;
           37         if(strcmp(msg, "alarm") == 0)
           38                 return 1;
           39         return 0;
           40 }
           41 
           42 static int
           43 lookup(char *s, char *l[])
           44 {
           45         int i;
           46 
           47         for (i = 0; l[i] != 0; i++)
           48                 if (strcmp(l[i], s) == 0)
           49                         return i;
           50         return -1;
           51 }
           52 
           53 static char*
           54 srvname(char *addr)
           55 {
           56         int i;
           57 
           58         for(i=0; i<strlen(addr); i++){
           59                 if(addr[i] == '!')
           60                         addr[i] = ':';
           61         }
           62         return addr;
           63 }
           64 
           65 void
           66 threadmain(int argc, char **argv)
           67 {
           68         char *mntpt, *srvpost, srvfile[64];
           69         int fd;
           70 
           71         quotefmtinstall();
           72         srvpost = nil;
           73         ARGBEGIN{
           74         case 'A':
           75                 doauth = 0;
           76                 break;
           77         case 'd':
           78                 debug++;
           79                 break;
           80         case 'E':
           81                 if ((encproto = lookup(EARGF(usage()), encprotos)) < 0)
           82                         usage();
           83                 break;
           84         case 'e':
           85                 ealgs = EARGF(usage());
           86                 if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
           87                         ealgs = nil;
           88                 break;
           89         case 'k':
           90                 keyspec = EARGF(usage());
           91                 break;
           92         case 'p':
           93                 filterp = unsharp("#9/bin/aan");
           94                 break;
           95         case 's':
           96                 srvpost = EARGF(usage());
           97                 break;
           98         default:
           99                 usage();
          100         }ARGEND;
          101 
          102         mntpt = 0;                /* to shut up compiler */
          103         switch(argc) {
          104         case 2:
          105                 mntpt = argv[1];
          106                 break;
          107         case 3:
          108                 mntpt = argv[2];
          109                 break;
          110         default:
          111                 usage();
          112         }
          113 
          114         if(encproto != Encnone)
          115                 sysfatal("%s: tls and ssl have not yet been implemented", argv[0]);
          116 
          117         threadnotify(catcher, 1);
          118         alarm(60*1000);
          119 
          120         fd = connectez(argv[0], argv[1]);
          121 
          122         fprint(fd, "impo %s %s\n", filterp? "aan": "nofilter",
          123                 encprotos[encproto]);
          124 
          125         if (filterp)
          126                 fd = filter(fd, filterp, argv[0]);
          127 
          128         if(srvpost == nil)
          129                  srvpost = srvname(argv[0]);
          130         sprint(srvfile, "%s", srvpost);
          131 
          132         if(post9pservice(fd, srvfile, mntpt) < 0)
          133                 sysfatal("can't post %s: %r", argv[1]);
          134         alarm(0);
          135 
          136         threadexitsall(0);
          137 }
          138 
          139 /* the name "connect" is special */
          140 int
          141 connectez(char *system, char *tree)
          142 {
          143         char buf[ERRMAX], *na;
          144         int fd, n;
          145         char *authp;
          146 
          147         na = netmkaddr(system, "tcp", "exportfs");
          148         threadsetname("dial %s", na);
          149         if((fd = dial(na, nil, nil, nil)) < 0)
          150                 sysfatal("can't dial %s: %r", system);
          151 
          152         if(doauth){
          153                 authp = "p9any";
          154                 threadsetname("auth_proxy auth_getkey proto=%q role=client %s",
          155                         authp, keyspec);
          156                 ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s",
          157                         authp, keyspec);
          158                 if(ai == nil)
          159                         sysfatal("%r: %s", system);
          160         }
          161 
          162         threadsetname("writing tree name %s", tree);
          163         n = write(fd, tree, strlen(tree));
          164         if(n < 0)
          165                 sysfatal("can't write tree: %r");
          166 
          167         strcpy(buf, "can't read tree");
          168 
          169         threadsetname("awaiting OK for %s", tree);
          170         n = read(fd, buf, sizeof buf - 1);
          171         if(n!=2 || buf[0]!='O' || buf[1]!='K'){
          172                 if (timedout)
          173                         sysfatal("timed out connecting to %s", na);
          174                 buf[sizeof buf - 1] = '\0';
          175                 sysfatal("bad remote tree: %s", buf);
          176         }
          177 
          178         return fd;
          179 }
          180 
          181 void
          182 usage(void)
          183 {
          184         fprint(2, "usage: 9import [-A] [-E clear|ssl|tls] "
          185 "[-e 'crypt auth'|clear] [-k keypattern] [-p] [-s srv] host remotefs [mountpoint]\n");
          186         threadexitsall("usage");
          187 }
          188 
          189 /* Network on fd1, mount driver on fd0 */
          190 int
          191 filter(int fd, char *cmd, char *host)
          192 {
          193         int p[2], len, argc;
          194         char newport[256], buf[256], *s;
          195         char *argv[16], *file, *pbuf;
          196 
          197         if ((len = read(fd, newport, sizeof newport - 1)) < 0)
          198                 sysfatal("filter: cannot write port; %r");
          199         newport[len] = '\0';
          200 
          201         if ((s = strchr(newport, '!')) == nil)
          202                 sysfatal("filter: illegally formatted port %s", newport);
          203 
          204         strecpy(buf, buf+sizeof buf, netmkaddr(host, "tcp", "0"));
          205         pbuf = strrchr(buf, '!');
          206         strecpy(pbuf, buf+sizeof buf, s);
          207 
          208         if(debug)
          209                 fprint(2, "filter: remote port %s\n", newport);
          210 
          211         argc = tokenize(cmd, argv, nelem(argv)-2);
          212         if (argc == 0)
          213                 sysfatal("filter: empty command");
          214         argv[argc++] = "-c";
          215         argv[argc++] = buf;
          216         argv[argc] = nil;
          217         file = argv[0];
          218         if (s = strrchr(argv[0], '/'))
          219                 argv[0] = s+1;
          220 
          221         if(pipe(p) < 0)
          222                 sysfatal("pipe: %r");
          223 
          224         switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {
          225         case -1:
          226                 sysfatal("rfork record module: %r");
          227         case 0:
          228                 dup(p[0], 1);
          229                 dup(p[0], 0);
          230                 close(p[0]);
          231                 close(p[1]);
          232                 exec(file, argv);
          233                 sysfatal("exec record module: %r");
          234         default:
          235                 close(fd);
          236                 close(p[0]);
          237         }
          238         return p[1];
          239 }