xref: /plan9-contrib/sys/src/cmd/rx.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 
5 int	eof;		/* send an eof if true */
6 char	*note = "die: yankee dog";
7 
8 void	rex(int, char*);
9 void	dkexec(int, char*, char*);
10 void	tcpexec(int, char*, char*);
11 int	call(char *, char*, char*, char**);
12 char	*buildargs(char*[]);
13 int	send(int);
14 void	error(char*, char*);
15 
16 void
17 usage(void)
18 {
19 	fprint(2, "usage: %s [-e] net!host command...\n", argv0);
20 	exits("usage");
21 }
22 
23 void
24 main(int argc, char *argv[])
25 {
26 	char *host, *addr, *args;
27 	int fd;
28 
29 	eof = 1;
30 	ARGBEGIN{
31 	case 'e':
32 		eof = 0;
33 		break;
34 	default:
35 		usage();
36 	}ARGEND
37 
38 	if(argc < 2)
39 		usage();
40 	host = argv[0];
41 	args = buildargs(&argv[1]);
42 
43 	/* generic attempts */
44 	fd = call(0, host, "rexexec", &addr);
45 	if(fd >= 0)
46 		rex(fd, args);
47 	fd = call(0, host, "exec", &addr);
48 	if(fd >= 0)
49 		dkexec(fd, addr, args);
50 
51 	/* specific attempts */
52 	fd = call("tcp", host, "shell", &addr);
53 		tcpexec(fd, addr, args);
54 	fd = call("dk", host, "exec", &addr);
55 	if(fd >= 0)
56 		dkexec(fd, addr, args);
57 
58 	error("can't dial", host);
59 	exits(0);
60 }
61 
62 int
63 call(char *net, char *host, char *service, char **na)
64 {
65 	*na = netmkaddr(host, net, service);
66 	return dial(*na, 0, 0, 0);
67 }
68 
69 void
70 rex(int fd, char *cmd)
71 {
72 	char buf[4096];
73 	int kid, n;
74 
75 	if(auth(fd) < 0){
76 		close(fd);
77 		error("authenticate fails", 0);
78 	}
79 	write(fd, cmd, strlen(cmd)+1);
80 
81 	kid = send(fd);
82 	while((n=read(fd, buf, sizeof buf))>0)
83 		if(write(1, buf, n)!=n)
84 			error("write error", 0);
85 	sleep(250);
86 	postnote(PNPROC, kid, note);/**/
87 	exits(0);
88 }
89 
90 void
91 dkexec(int fd, char *addr, char *cmd)
92 {
93 	char buf[4096];
94 	int kid, n;
95 
96 	if(read(fd, buf, 1)!=1 || *buf!='O'
97 	|| read(fd, buf, 1)!=1 || *buf!='K'){
98 		close(fd);
99 		error("can't authenticate to", addr);
100 	}
101 
102 	write(fd, cmd, strlen(cmd)+1);
103 	kid = send(fd);
104 	while((n=read(fd, buf, sizeof buf))>0)
105 		if(write(1, buf, n)!=n)
106 			error("write error", 0);
107 	sleep(250);
108 	postnote(PNPROC, kid, note);/**/
109 	exits(0);
110 }
111 
112 void
113 tcpexec(int fd, char *addr, char *cmd)
114 {
115 	char *u, buf[4096];
116 	int kid, n;
117 
118 	/*
119 	 *  do the ucb authentication and send command
120 	 */
121 	u = getuser();
122 	if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0
123 	|| write(fd, u, strlen(u)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){
124 		close(fd);
125 		error("can't authenticate to", addr);
126 	}
127 
128 	/*
129 	 *  get authentication reply
130 	 */
131 	if(read(fd, buf, 1) != 1){
132 		close(fd);
133 		error("can't authenticate to", addr);
134 	}
135 	if(buf[0] != 0){
136 		while(read(fd, buf, 1) == 1){
137 			write(2, buf, 1);
138 			if(buf[0] == '\n')
139 				break;
140 		}
141 		close(fd);
142 		error("rejected by", addr);
143 	}
144 
145 	kid = send(fd);
146 	while((n=read(fd, buf, sizeof buf))>0)
147 		if(write(1, buf, n)!=n)
148 			error("write error", 0);
149 	sleep(250);
150 	postnote(PNPROC, kid, note);/**/
151 	exits(0);
152 }
153 
154 int
155 send(int fd)
156 {
157 	char buf[4096];
158 	int n;
159 	int kid;
160 	switch(kid = fork()){
161 	case -1:
162 		error("fork error", 0);
163 	case 0:
164 		break;
165 	default:
166 		return kid;
167 	}
168 	while((n=read(0, buf, sizeof buf))>0)
169 		if(write(fd, buf, n)!=n)
170 			exits("write error");
171 	if(eof)
172 		write(fd, buf, 0);
173 
174 	exits(0);
175 	return 0;			/* to keep compiler happy */
176 }
177 
178 void
179 error(char *s, char *z)
180 {
181 	if(z == 0)
182 		fprint(2, "%s: %s: %r\n", argv0, s);
183 	else
184 		fprint(2, "%s: %s %s: %r\n", argv0, s, z);
185 	exits(s);
186 }
187 
188 char *
189 buildargs(char *argv[])
190 {
191 	char *args;
192 	int m, n;
193 
194 	args = malloc(1);
195 	args[0] = '\0';
196 	n = 0;
197 	while(*argv){
198 		m = strlen(*argv) + 1;
199 		args = realloc(args, n+m +1);
200 		if(args == 0)
201 			error("malloc fail", 0);
202 		args[n] = ' ';	/* smashes old null */
203 		strcpy(args+n+1, *argv);
204 		n += m;
205 		argv++;
206 	}
207 	return args;
208 }
209