xref: /plan9/sys/src/cmd/rx.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <auth.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier int	eof;		/* send an eof if true */
63e12c5d1SDavid du Colombier char	*note = "die: yankee dog";
73e12c5d1SDavid du Colombier 
8*219b2ee8SDavid du Colombier void	rex(int, char*);
93e12c5d1SDavid du Colombier void	dkexec(int, char*, char*);
103e12c5d1SDavid du Colombier void	tcpexec(int, char*, char*);
113e12c5d1SDavid du Colombier int	call(char *, char*, char*, char**);
123e12c5d1SDavid du Colombier char	*buildargs(char*[]);
133e12c5d1SDavid du Colombier int	send(int);
143e12c5d1SDavid du Colombier void	error(char*, char*);
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier void
173e12c5d1SDavid du Colombier usage(void)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	fprint(2, "usage: %s [-e] net!host command...\n", argv0);
203e12c5d1SDavid du Colombier 	exits("usage");
213e12c5d1SDavid du Colombier }
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier void
243e12c5d1SDavid du Colombier main(int argc, char *argv[])
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	char *host, *addr, *args;
273e12c5d1SDavid du Colombier 	int fd;
283e12c5d1SDavid du Colombier 
293e12c5d1SDavid du Colombier 	eof = 1;
303e12c5d1SDavid du Colombier 	ARGBEGIN{
313e12c5d1SDavid du Colombier 	case 'e':
323e12c5d1SDavid du Colombier 		eof = 0;
333e12c5d1SDavid du Colombier 		break;
343e12c5d1SDavid du Colombier 	default:
353e12c5d1SDavid du Colombier 		usage();
363e12c5d1SDavid du Colombier 	}ARGEND
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier 	if(argc < 2)
393e12c5d1SDavid du Colombier 		usage();
403e12c5d1SDavid du Colombier 	host = argv[0];
413e12c5d1SDavid du Colombier 	args = buildargs(&argv[1]);
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 	/* generic attempts */
443e12c5d1SDavid du Colombier 	fd = call(0, host, "rexexec", &addr);
453e12c5d1SDavid du Colombier 	if(fd >= 0)
46*219b2ee8SDavid du Colombier 		rex(fd, args);
473e12c5d1SDavid du Colombier 	fd = call(0, host, "exec", &addr);
483e12c5d1SDavid du Colombier 	if(fd >= 0)
493e12c5d1SDavid du Colombier 		dkexec(fd, addr, args);
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	/* specific attempts */
523e12c5d1SDavid du Colombier 	fd = call("tcp", host, "shell", &addr);
533e12c5d1SDavid du Colombier 		tcpexec(fd, addr, args);
543e12c5d1SDavid du Colombier 	fd = call("dk", host, "exec", &addr);
553e12c5d1SDavid du Colombier 	if(fd >= 0)
563e12c5d1SDavid du Colombier 		dkexec(fd, addr, args);
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier 	error("can't dial", host);
593e12c5d1SDavid du Colombier 	exits(0);
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier int
633e12c5d1SDavid du Colombier call(char *net, char *host, char *service, char **na)
643e12c5d1SDavid du Colombier {
653e12c5d1SDavid du Colombier 	*na = netmkaddr(host, net, service);
663e12c5d1SDavid du Colombier 	return dial(*na, 0, 0, 0);
673e12c5d1SDavid du Colombier }
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier void
70*219b2ee8SDavid du Colombier rex(int fd, char *cmd)
713e12c5d1SDavid du Colombier {
72*219b2ee8SDavid du Colombier 	char buf[4096];
733e12c5d1SDavid du Colombier 	int kid, n;
743e12c5d1SDavid du Colombier 
75*219b2ee8SDavid du Colombier 	if(auth(fd) < 0){
763e12c5d1SDavid du Colombier 		close(fd);
77*219b2ee8SDavid du Colombier 		error("authenticate fails", 0);
783e12c5d1SDavid du Colombier 	}
793e12c5d1SDavid du Colombier 	write(fd, cmd, strlen(cmd)+1);
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier 	kid = send(fd);
823e12c5d1SDavid du Colombier 	while((n=read(fd, buf, sizeof buf))>0)
833e12c5d1SDavid du Colombier 		if(write(1, buf, n)!=n)
843e12c5d1SDavid du Colombier 			error("write error", 0);
853e12c5d1SDavid du Colombier 	sleep(250);
86*219b2ee8SDavid du Colombier 	postnote(PNPROC, kid, note);/**/
873e12c5d1SDavid du Colombier 	exits(0);
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier void
913e12c5d1SDavid du Colombier dkexec(int fd, char *addr, char *cmd)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 	char buf[4096];
943e12c5d1SDavid du Colombier 	int kid, n;
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	if(read(fd, buf, 1)!=1 || *buf!='O'
973e12c5d1SDavid du Colombier 	|| read(fd, buf, 1)!=1 || *buf!='K'){
983e12c5d1SDavid du Colombier 		close(fd);
993e12c5d1SDavid du Colombier 		error("can't authenticate to", addr);
1003e12c5d1SDavid du Colombier 	}
1013e12c5d1SDavid du Colombier 
1023e12c5d1SDavid du Colombier 	write(fd, cmd, strlen(cmd)+1);
1033e12c5d1SDavid du Colombier 	kid = send(fd);
1043e12c5d1SDavid du Colombier 	while((n=read(fd, buf, sizeof buf))>0)
1053e12c5d1SDavid du Colombier 		if(write(1, buf, n)!=n)
1063e12c5d1SDavid du Colombier 			error("write error", 0);
1073e12c5d1SDavid du Colombier 	sleep(250);
108*219b2ee8SDavid du Colombier 	postnote(PNPROC, kid, note);/**/
1093e12c5d1SDavid du Colombier 	exits(0);
1103e12c5d1SDavid du Colombier }
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier void
1133e12c5d1SDavid du Colombier tcpexec(int fd, char *addr, char *cmd)
1143e12c5d1SDavid du Colombier {
1153e12c5d1SDavid du Colombier 	char *u, buf[4096];
1163e12c5d1SDavid du Colombier 	int kid, n;
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier 	/*
1193e12c5d1SDavid du Colombier 	 *  do the ucb authentication and send command
1203e12c5d1SDavid du Colombier 	 */
1213e12c5d1SDavid du Colombier 	u = getuser();
1223e12c5d1SDavid du Colombier 	if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0
1233e12c5d1SDavid du Colombier 	|| write(fd, u, strlen(u)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){
1243e12c5d1SDavid du Colombier 		close(fd);
1253e12c5d1SDavid du Colombier 		error("can't authenticate to", addr);
1263e12c5d1SDavid du Colombier 	}
1273e12c5d1SDavid du Colombier 
1283e12c5d1SDavid du Colombier 	/*
1293e12c5d1SDavid du Colombier 	 *  get authentication reply
1303e12c5d1SDavid du Colombier 	 */
1313e12c5d1SDavid du Colombier 	if(read(fd, buf, 1) != 1){
1323e12c5d1SDavid du Colombier 		close(fd);
1333e12c5d1SDavid du Colombier 		error("can't authenticate to", addr);
1343e12c5d1SDavid du Colombier 	}
1353e12c5d1SDavid du Colombier 	if(buf[0] != 0){
1363e12c5d1SDavid du Colombier 		while(read(fd, buf, 1) == 1){
1373e12c5d1SDavid du Colombier 			write(2, buf, 1);
1383e12c5d1SDavid du Colombier 			if(buf[0] == '\n')
1393e12c5d1SDavid du Colombier 				break;
1403e12c5d1SDavid du Colombier 		}
1413e12c5d1SDavid du Colombier 		close(fd);
1423e12c5d1SDavid du Colombier 		error("rejected by", addr);
1433e12c5d1SDavid du Colombier 	}
1443e12c5d1SDavid du Colombier 
1453e12c5d1SDavid du Colombier 	kid = send(fd);
1463e12c5d1SDavid du Colombier 	while((n=read(fd, buf, sizeof buf))>0)
1473e12c5d1SDavid du Colombier 		if(write(1, buf, n)!=n)
1483e12c5d1SDavid du Colombier 			error("write error", 0);
1493e12c5d1SDavid du Colombier 	sleep(250);
150*219b2ee8SDavid du Colombier 	postnote(PNPROC, kid, note);/**/
1513e12c5d1SDavid du Colombier 	exits(0);
1523e12c5d1SDavid du Colombier }
1533e12c5d1SDavid du Colombier 
1543e12c5d1SDavid du Colombier int
1553e12c5d1SDavid du Colombier send(int fd)
1563e12c5d1SDavid du Colombier {
1573e12c5d1SDavid du Colombier 	char buf[4096];
1583e12c5d1SDavid du Colombier 	int n;
1593e12c5d1SDavid du Colombier 	int kid;
1603e12c5d1SDavid du Colombier 	switch(kid = fork()){
1613e12c5d1SDavid du Colombier 	case -1:
1623e12c5d1SDavid du Colombier 		error("fork error", 0);
1633e12c5d1SDavid du Colombier 	case 0:
1643e12c5d1SDavid du Colombier 		break;
1653e12c5d1SDavid du Colombier 	default:
1663e12c5d1SDavid du Colombier 		return kid;
1673e12c5d1SDavid du Colombier 	}
1683e12c5d1SDavid du Colombier 	while((n=read(0, buf, sizeof buf))>0)
1693e12c5d1SDavid du Colombier 		if(write(fd, buf, n)!=n)
1703e12c5d1SDavid du Colombier 			exits("write error");
1713e12c5d1SDavid du Colombier 	if(eof)
1723e12c5d1SDavid du Colombier 		write(fd, buf, 0);
1733e12c5d1SDavid du Colombier 
1743e12c5d1SDavid du Colombier 	exits(0);
1753e12c5d1SDavid du Colombier 	return 0;			/* to keep compiler happy */
1763e12c5d1SDavid du Colombier }
1773e12c5d1SDavid du Colombier 
1783e12c5d1SDavid du Colombier void
1793e12c5d1SDavid du Colombier error(char *s, char *z)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier 	if(z == 0)
182*219b2ee8SDavid du Colombier 		fprint(2, "%s: %s: %r\n", argv0, s);
1833e12c5d1SDavid du Colombier 	else
184*219b2ee8SDavid du Colombier 		fprint(2, "%s: %s %s: %r\n", argv0, s, z);
1853e12c5d1SDavid du Colombier 	exits(s);
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier 
1883e12c5d1SDavid du Colombier char *
1893e12c5d1SDavid du Colombier buildargs(char *argv[])
1903e12c5d1SDavid du Colombier {
1913e12c5d1SDavid du Colombier 	char *args;
1923e12c5d1SDavid du Colombier 	int m, n;
1933e12c5d1SDavid du Colombier 
1943e12c5d1SDavid du Colombier 	args = malloc(1);
1953e12c5d1SDavid du Colombier 	args[0] = '\0';
1963e12c5d1SDavid du Colombier 	n = 0;
1973e12c5d1SDavid du Colombier 	while(*argv){
1983e12c5d1SDavid du Colombier 		m = strlen(*argv) + 1;
1993e12c5d1SDavid du Colombier 		args = realloc(args, n+m +1);
2003e12c5d1SDavid du Colombier 		if(args == 0)
2013e12c5d1SDavid du Colombier 			error("malloc fail", 0);
2023e12c5d1SDavid du Colombier 		args[n] = ' ';	/* smashes old null */
2033e12c5d1SDavid du Colombier 		strcpy(args+n+1, *argv);
2043e12c5d1SDavid du Colombier 		n += m;
2053e12c5d1SDavid du Colombier 		argv++;
2063e12c5d1SDavid du Colombier 	}
2073e12c5d1SDavid du Colombier 	return args;
2083e12c5d1SDavid du Colombier }
209