Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/rx.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <auth.h>
4
 
5
int	eof;		/* send an eof if true */
6
int	crtonl;		/* convert all received \r to \n */
7
int	returns;	/* strip \r on reception */
8
char	*note = "die: yankee dog";
9
char	*ruser;		/* for BSD authentication */
10
char *key;
11
 
12
void	rex(int, char*, char*);
13
void	tcpexec(int, char*, char*);
14
int	call(char *, char*, char*, char**);
15
char	*buildargs(char*[]);
16
int	send(int);
17
void	error(char*, char*);
18
void	sshexec(char*, char*);
19
 
20
void
21
usage(void)
22
{
23
	fprint(2, "usage: %s [-e] [-T] [-r] [-k keypattern] [-l user] net!host command...\n", argv0);
24
	exits("usage");
25
}
26
 
27
static int
28
catch(void *, char *s)
29
{
30
	return strstr(s, "alarm") != nil;
31
}
32
 
33
void
34
main(int argc, char *argv[])
35
{
36
	char *host, *addr, *args;
37
	int fd;
38
 
39
	key = "";
40
	eof = 1;
41
	crtonl = 0;
42
	returns = 1;
43
	ARGBEGIN{
44
	case 'T':
45
		crtonl = 1;
46
		break;
47
	case 'r':
48
		returns = 0;
49
		break;
50
	case 'e':
51
		eof = 0;
52
		break;
53
	case 'k':
54
		key = EARGF(usage());
55
		break;
56
	case 'l':
57
		ruser = EARGF(usage());
58
		break;
59
	default:
60
		usage();
61
	}ARGEND
62
 
63
	if(argc < 2)
64
		usage();
65
	host = argv[0];
66
	args = buildargs(&argv[1]);
67
	atnotify(catch, 1);
68
 
69
	/* try rexexec p9any then dial again with p9sk2 */
70
	fd = call(0, host, "rexexec", &addr);
71
	if(fd >= 0)
72
		rex(fd, args, "p9any");
73
	close(fd);
74
	fd = call(0, host, "rexexec", &addr);
75
	if(fd >= 0)
76
		rex(fd, args, "p9sk2");
77
	close(fd);
78
 
79
	/* if there's an ssh port, try that */
80
	fd = call("tcp", host, "ssh", &addr);
81
	if(fd >= 0){
82
		close(fd);
83
		sshexec(host, args);
84
		/* falls through if no ssh */
85
	}
86
 
87
	/* specific attempts */
88
	fd = call("tcp", host, "shell", &addr);
89
	if(fd >= 0)
90
		tcpexec(fd, addr, args);
91
 
92
	error("can't dial", host);
93
	exits(0);
94
}
95
 
96
int
97
call(char *net, char *host, char *service, char **na)
98
{
99
	*na = netmkaddr(host, net, service);
100
	return dial(*na, 0, 0, 0);
101
}
102
 
103
void
104
rex(int fd, char *cmd, char *proto)
105
{
106
	char buf[4096];
107
	int kid, n, oalarm;
108
	AuthInfo *ai;
109
 
110
	oalarm = alarm(2 * 60 * 1000);		/* don't hang forever */
111
	ai = auth_proxy(fd, auth_getkey, "proto=%s role=client %s", proto, key);
112
	alarm(oalarm);
113
	if(ai == nil){
114
		if(strcmp(proto, "p9any") == 0)
115
			return;
116
		error("auth_proxy", nil);
117
	}
118
	write(fd, cmd, strlen(cmd)+1);
119
 
120
	kid = send(fd);
121
	while((n=read(fd, buf, sizeof buf))>0)
122
		if(write(1, buf, n)!=n)
123
			error("write error", 0);
124
	sleep(250);
125
	postnote(PNPROC, kid, note);/**/
126
	exits(0);
127
}
128
 
129
void
130
tcpexec(int fd, char *addr, char *cmd)
131
{
132
	char *cp, *ep, *u, *ru, buf[4096];
133
	int kid, n;
134
 
135
	/*
136
	 *  do the ucb authentication and send command
137
	 */
138
	u = getuser();
139
	ru = ruser;
140
	if(ru == nil)
141
		ru = u;
142
	if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0
143
	|| write(fd, ru, strlen(ru)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){
144
		close(fd);
145
		error("can't authenticate to", addr);
146
	}
147
 
148
	/*
149
	 *  get authentication reply
150
	 */
151
	if(read(fd, buf, 1) != 1){
152
		close(fd);
153
		error("can't authenticate to", addr);
154
	}
155
	if(buf[0] != 0){
156
		while(read(fd, buf, 1) == 1){
157
			write(2, buf, 1);
158
			if(buf[0] == '\n')
159
				break;
160
		}
161
		close(fd);
162
		error("rejected by", addr);
163
	}
164
 
165
	kid = send(fd);
166
	while((n=read(fd, buf, sizeof buf))>0){
167
		if(crtonl) {
168
			/* convert cr's to nl's */
169
			for (cp = buf; cp < buf + n; cp++)
170
				if (*cp == '\r')
171
					*cp = '\n';
172
		}
173
		else if(!returns){
174
			/* convert cr's to null's */
175
			cp = buf;
176
			ep = buf + n;
177
			while(cp < ep && (cp = memchr(cp, '\r', ep-cp))){
178
				memmove(cp, cp+1, ep-cp-1);
179
				ep--;
180
				n--;
181
			}
182
		}
183
		if(write(1, buf, n)!=n)
184
			error("write error", 0);
185
	}
186
	sleep(250);
187
	postnote(PNPROC, kid, note);/**/
188
	exits(0);
189
}
190
 
191
void
192
sshexec(char *host, char *cmd)
193
{
194
	char *argv[10];
195
	int n;
196
 
197
	n = 0;
198
	argv[n++] = "ssh";
199
	argv[n++] = "-iCm";
200
	if(!returns)
201
		argv[n++] = "-r";
202
	if(ruser){
203
		argv[n++] = "-l";
204
		argv[n++] = ruser;
205
	}
206
	argv[n++] = host;
207
	argv[n++] = cmd;
208
	argv[n] = 0;
209
	exec("/bin/ssh", argv);
210
}
211
 
212
int
213
send(int fd)
214
{
215
	char buf[4096];
216
	int n;
217
	int kid;
218
	switch(kid = fork()){
219
	case -1:
220
		error("fork error", 0);
221
	case 0:
222
		break;
223
	default:
224
		return kid;
225
	}
226
	while((n=read(0, buf, sizeof buf))>0)
227
		if(write(fd, buf, n)!=n)
228
			exits("write error");
229
	if(eof)
230
		write(fd, buf, 0);
231
 
232
	exits(0);
233
	return 0;			/* to keep compiler happy */
234
}
235
 
236
void
237
error(char *s, char *z)
238
{
239
	if(z == 0)
240
		fprint(2, "%s: %s: %r\n", argv0, s);
241
	else
242
		fprint(2, "%s: %s %s: %r\n", argv0, s, z);
243
	exits(s);
244
}
245
 
246
char *
247
buildargs(char *argv[])
248
{
249
	char *args;
250
	int m, n;
251
 
252
	args = malloc(1);
253
	args[0] = '\0';
254
	n = 0;
255
	while(*argv){
256
		m = strlen(*argv) + 1;
257
		args = realloc(args, n+m +1);
258
		if(args == 0)
259
			error("malloc fail", 0);
260
		args[n] = ' ';	/* smashes old null */
261
		strcpy(args+n+1, *argv);
262
		n += m;
263
		argv++;
264
	}
265
	return args;
266
}