plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

9import.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 }