xref: /titanic_53/usr/src/cmd/rexd/on.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"
23*7c478bd9Sstevel@tonic-gate 
24*7c478bd9Sstevel@tonic-gate /*
25*7c478bd9Sstevel@tonic-gate  * on - user interface program for remote execution service
26*7c478bd9Sstevel@tonic-gate  *
27*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1985 Sun Microsystems, Inc.
28*7c478bd9Sstevel@tonic-gate  */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #define	BSD_COMP
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include <ctype.h>
33*7c478bd9Sstevel@tonic-gate #include <errno.h>
34*7c478bd9Sstevel@tonic-gate #include <netdb.h>
35*7c478bd9Sstevel@tonic-gate #include <signal.h>
36*7c478bd9Sstevel@tonic-gate #include <stdio.h>
37*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
38*7c478bd9Sstevel@tonic-gate #include <string.h>
39*7c478bd9Sstevel@tonic-gate #include <unistd.h>
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
42*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
43*7c478bd9Sstevel@tonic-gate #include <rpc/clnt_soc.h>
44*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h>
45*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
50*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
51*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #include <sys/ttold.h>
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate #include "rex.h"
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate #include <stropts.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/stream.h>
61*7c478bd9Sstevel@tonic-gate #include <sys/ttcompat.h>
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate #define	bcmp(b1, b2, len)	memcmp(b1, b2, len)
65*7c478bd9Sstevel@tonic-gate #define	bzero(b, len)		memset(b, '\0', len)
66*7c478bd9Sstevel@tonic-gate #define	bcopy(b1, b2, len)	memcpy(b2, b1, len)
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate #define	CommandName "on"	/* given as argv[0] */
69*7c478bd9Sstevel@tonic-gate #define	AltCommandName "dbon"
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate extern int errno;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /*
74*7c478bd9Sstevel@tonic-gate  * Note - the following must be long enough for at least two portmap
75*7c478bd9Sstevel@tonic-gate  * timeouts on the other side.
76*7c478bd9Sstevel@tonic-gate  */
77*7c478bd9Sstevel@tonic-gate struct timeval LongTimeout = { 123, 0 };
78*7c478bd9Sstevel@tonic-gate struct timeval testtimeout = { 5, 0 };
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate int Debug = 0;			/* print extra debugging information */
81*7c478bd9Sstevel@tonic-gate int Only2 = 0;			/* stdout and stderr are the same */
82*7c478bd9Sstevel@tonic-gate int Interactive = 0;		/* use a pty on server */
83*7c478bd9Sstevel@tonic-gate int NoInput = 0;		/* don't read standard input */
84*7c478bd9Sstevel@tonic-gate int child = 0;			/* pid of the executed process */
85*7c478bd9Sstevel@tonic-gate int ChildDied = 0;		/* true when above is valid */
86*7c478bd9Sstevel@tonic-gate int HasHelper = 0;		/* must kill helpers (interactive mode) */
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate int InOut;			/* socket for stdin/stdout */
89*7c478bd9Sstevel@tonic-gate int Err;			/* socket for stderr */
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate struct sgttyb OldFlags;		/* saved tty flags */
92*7c478bd9Sstevel@tonic-gate struct sgttyb NewFlags;		/* for stop/continue job control */
93*7c478bd9Sstevel@tonic-gate CLIENT *Client;			/* RPC client handle */
94*7c478bd9Sstevel@tonic-gate struct rex_ttysize WindowSize;	/* saved window size */
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate static int Argc;
97*7c478bd9Sstevel@tonic-gate static char **Argv;		/* saved argument vector (for ps) */
98*7c478bd9Sstevel@tonic-gate static char *LastArgv;		/* saved end-of-argument vector */
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate void	usage(void);
101*7c478bd9Sstevel@tonic-gate void	Die(int stat);
102*7c478bd9Sstevel@tonic-gate void	doaccept(int *fdp);
103*7c478bd9Sstevel@tonic-gate u_short makeport(int *fdp);
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * window change handler - propagate to remote server
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate void
110*7c478bd9Sstevel@tonic-gate sigwinch(int junk)
111*7c478bd9Sstevel@tonic-gate {
112*7c478bd9Sstevel@tonic-gate 	struct	winsize	newsize; /* the modern way to get row and col	*/
113*7c478bd9Sstevel@tonic-gate 	struct	rex_ttysize	size;	/* the old way no body */
114*7c478bd9Sstevel@tonic-gate 					/* bothered to change */
115*7c478bd9Sstevel@tonic-gate 	enum	clnt_stat	clstat;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 	ioctl(0, TIOCGWINSZ, &newsize);
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 	/*
120*7c478bd9Sstevel@tonic-gate 	 * compensate for the struct change
121*7c478bd9Sstevel@tonic-gate 	 */
122*7c478bd9Sstevel@tonic-gate 	size.ts_lines = (int)newsize.ws_row; /* typecast important! */
123*7c478bd9Sstevel@tonic-gate 	size.ts_cols = (int)newsize.ws_col;
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	if (bcmp(&size, &WindowSize, sizeof (size)) == 0)
126*7c478bd9Sstevel@tonic-gate 		return;
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	WindowSize = size;
129*7c478bd9Sstevel@tonic-gate 	if (clstat = clnt_call(Client, REXPROC_WINCH,
130*7c478bd9Sstevel@tonic-gate 				xdr_rex_ttysize, (caddr_t)&size, xdr_void,
131*7c478bd9Sstevel@tonic-gate 				NULL, LongTimeout)) {
132*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on (size): ");
133*7c478bd9Sstevel@tonic-gate 		clnt_perrno(clstat);
134*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "\r\n");
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate }
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate /*
139*7c478bd9Sstevel@tonic-gate  * signal handler - propagate to remote server
140*7c478bd9Sstevel@tonic-gate  */
141*7c478bd9Sstevel@tonic-gate void
142*7c478bd9Sstevel@tonic-gate sendsig(int sig)
143*7c478bd9Sstevel@tonic-gate {
144*7c478bd9Sstevel@tonic-gate 	enum clnt_stat clstat;
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 	if (clstat = clnt_call(Client, REXPROC_SIGNAL,
147*7c478bd9Sstevel@tonic-gate 				xdr_int, (caddr_t) &sig, xdr_void,
148*7c478bd9Sstevel@tonic-gate 				NULL, LongTimeout)) {
149*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on (signal): ");
150*7c478bd9Sstevel@tonic-gate 		clnt_perrno(clstat);
151*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "\r\n");
152*7c478bd9Sstevel@tonic-gate 	}
153*7c478bd9Sstevel@tonic-gate }
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate void
157*7c478bd9Sstevel@tonic-gate cont(int junk)
158*7c478bd9Sstevel@tonic-gate {
159*7c478bd9Sstevel@tonic-gate 	/*
160*7c478bd9Sstevel@tonic-gate 	 * Put tty modes back the way they were and tell the rexd server
161*7c478bd9Sstevel@tonic-gate 	 * to send the command a SIGCONT signal.
162*7c478bd9Sstevel@tonic-gate 	 */
163*7c478bd9Sstevel@tonic-gate 	if (Interactive) {
164*7c478bd9Sstevel@tonic-gate 		ioctl(0, TIOCSETN, &NewFlags);
165*7c478bd9Sstevel@tonic-gate 		(void) send(InOut, "", 1, MSG_OOB);
166*7c478bd9Sstevel@tonic-gate 	}
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate /*
170*7c478bd9Sstevel@tonic-gate  * oob -- called when the command invoked by the rexd server is stopped
171*7c478bd9Sstevel@tonic-gate  *	  with a SIGTSTP or SIGSTOP signal.
172*7c478bd9Sstevel@tonic-gate  */
173*7c478bd9Sstevel@tonic-gate void
174*7c478bd9Sstevel@tonic-gate oob(int junk)
175*7c478bd9Sstevel@tonic-gate {
176*7c478bd9Sstevel@tonic-gate 	int atmark;
177*7c478bd9Sstevel@tonic-gate 	char waste[BUFSIZ], mark;
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 	for (;;) {
180*7c478bd9Sstevel@tonic-gate 		if (ioctl(InOut, SIOCATMARK, &atmark) < 0) {
181*7c478bd9Sstevel@tonic-gate 			perror("ioctl");
182*7c478bd9Sstevel@tonic-gate 			break;
183*7c478bd9Sstevel@tonic-gate 		}
184*7c478bd9Sstevel@tonic-gate 		if (atmark)
185*7c478bd9Sstevel@tonic-gate 			break;
186*7c478bd9Sstevel@tonic-gate 		(void) read(InOut, waste, sizeof (waste));
187*7c478bd9Sstevel@tonic-gate 	}
188*7c478bd9Sstevel@tonic-gate 	(void) recv(InOut, &mark, 1, MSG_OOB);
189*7c478bd9Sstevel@tonic-gate 	/*
190*7c478bd9Sstevel@tonic-gate 	 * Reset tty modes to something sane and stop myself
191*7c478bd9Sstevel@tonic-gate 	 */
192*7c478bd9Sstevel@tonic-gate 	if (Interactive) {
193*7c478bd9Sstevel@tonic-gate 		ioctl(0, TIOCSETN, &OldFlags);
194*7c478bd9Sstevel@tonic-gate 		printf("\r\n");
195*7c478bd9Sstevel@tonic-gate 	}
196*7c478bd9Sstevel@tonic-gate 	kill(getpid(), SIGSTOP);
197*7c478bd9Sstevel@tonic-gate }
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate void
202*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
203*7c478bd9Sstevel@tonic-gate {
204*7c478bd9Sstevel@tonic-gate 	struct	winsize	newsize; /* the modern way to get row and col	*/
205*7c478bd9Sstevel@tonic-gate 	char *rhost, **cmdp;
206*7c478bd9Sstevel@tonic-gate 	char curdir[MAXPATHLEN];
207*7c478bd9Sstevel@tonic-gate 	char wdhost[MAXHOSTNAMELEN];
208*7c478bd9Sstevel@tonic-gate 	char fsname[MAXPATHLEN];
209*7c478bd9Sstevel@tonic-gate 	char dirwithin[MAXPATHLEN];
210*7c478bd9Sstevel@tonic-gate 	struct rex_start rst;
211*7c478bd9Sstevel@tonic-gate 	struct rex_result result;
212*7c478bd9Sstevel@tonic-gate 	extern char **environ;
213*7c478bd9Sstevel@tonic-gate 	enum clnt_stat clstat;
214*7c478bd9Sstevel@tonic-gate 	struct hostent *hp;
215*7c478bd9Sstevel@tonic-gate 	struct sockaddr_in server_addr;
216*7c478bd9Sstevel@tonic-gate 	int sock = RPC_ANYSOCK;
217*7c478bd9Sstevel@tonic-gate 	fd_set selmask, zmask, remmask;
218*7c478bd9Sstevel@tonic-gate 	int nfds, cc;
219*7c478bd9Sstevel@tonic-gate 	char *chi, *cho;
220*7c478bd9Sstevel@tonic-gate 	int trying_authdes;
221*7c478bd9Sstevel@tonic-gate 	char netname[MAXNETNAMELEN+1];
222*7c478bd9Sstevel@tonic-gate 	char hostname[MAXHOSTNAMELEN+1];
223*7c478bd9Sstevel@tonic-gate 	char publickey[HEXKEYBYTES+1];
224*7c478bd9Sstevel@tonic-gate 	int i;
225*7c478bd9Sstevel@tonic-gate 	char *domain;
226*7c478bd9Sstevel@tonic-gate 	static char buf[4096];
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	/*
229*7c478bd9Sstevel@tonic-gate 	 * we check the invoked command name to see if it should
230*7c478bd9Sstevel@tonic-gate 	 * really be a host name.
231*7c478bd9Sstevel@tonic-gate 	 */
232*7c478bd9Sstevel@tonic-gate 	if ((rhost = strrchr(argv[0], '/')) == NULL) {
233*7c478bd9Sstevel@tonic-gate 		rhost = argv[0];
234*7c478bd9Sstevel@tonic-gate 	} else {
235*7c478bd9Sstevel@tonic-gate 		rhost++;
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	/*
239*7c478bd9Sstevel@tonic-gate 	 * argv start and extent for setproctitle()
240*7c478bd9Sstevel@tonic-gate 	 */
241*7c478bd9Sstevel@tonic-gate 	Argc = argc;
242*7c478bd9Sstevel@tonic-gate 	Argv = argv;
243*7c478bd9Sstevel@tonic-gate 	if (argc > 0)
244*7c478bd9Sstevel@tonic-gate 		LastArgv = argv[argc-1] + strlen(argv[argc-1]);
245*7c478bd9Sstevel@tonic-gate 	else
246*7c478bd9Sstevel@tonic-gate 		LastArgv = NULL;
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	while (argc > 1 && argv[1][0] == '-') {
249*7c478bd9Sstevel@tonic-gate 		switch (argv[1][1]) {
250*7c478bd9Sstevel@tonic-gate 		case 'd': Debug = 1;
251*7c478bd9Sstevel@tonic-gate 			break;
252*7c478bd9Sstevel@tonic-gate 		case 'i': Interactive = 1;
253*7c478bd9Sstevel@tonic-gate 			break;
254*7c478bd9Sstevel@tonic-gate 		case 'n': NoInput = 1;
255*7c478bd9Sstevel@tonic-gate 			break;
256*7c478bd9Sstevel@tonic-gate 		default:
257*7c478bd9Sstevel@tonic-gate 			printf("Unknown option %s\n", argv[1]);
258*7c478bd9Sstevel@tonic-gate 		}
259*7c478bd9Sstevel@tonic-gate 		argv++;
260*7c478bd9Sstevel@tonic-gate 		argc--;
261*7c478bd9Sstevel@tonic-gate 	}
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 	if (strcmp(rhost, CommandName) && strcmp(rhost, AltCommandName)) {
264*7c478bd9Sstevel@tonic-gate 		cmdp = &argv[1];
265*7c478bd9Sstevel@tonic-gate 		Interactive = 1;
266*7c478bd9Sstevel@tonic-gate 	} else {
267*7c478bd9Sstevel@tonic-gate 		if (argc < 2)
268*7c478bd9Sstevel@tonic-gate 			usage();
269*7c478bd9Sstevel@tonic-gate 		rhost = argv[1];
270*7c478bd9Sstevel@tonic-gate 		cmdp = &argv[2];
271*7c478bd9Sstevel@tonic-gate 	}
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	/*
274*7c478bd9Sstevel@tonic-gate 	 * Can only have one of these
275*7c478bd9Sstevel@tonic-gate 	 */
276*7c478bd9Sstevel@tonic-gate 	if (Interactive && NoInput)
277*7c478bd9Sstevel@tonic-gate 		usage();
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate 	if ((hp = gethostbyname(rhost)) == NULL) {
280*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on: unknown host %s\n", rhost);
281*7c478bd9Sstevel@tonic-gate 		exit(1);
282*7c478bd9Sstevel@tonic-gate 	}
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate 	bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
285*7c478bd9Sstevel@tonic-gate 	server_addr.sin_family = AF_INET;
286*7c478bd9Sstevel@tonic-gate 	server_addr.sin_port = 0; /* use pmapper */
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	if (Debug)
289*7c478bd9Sstevel@tonic-gate 		printf("Got the host named %s (%s)\n",
290*7c478bd9Sstevel@tonic-gate 			rhost, inet_ntoa(server_addr.sin_addr));
291*7c478bd9Sstevel@tonic-gate 	trying_authdes = 1;
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate try_auth_unix:
294*7c478bd9Sstevel@tonic-gate 	sock = RPC_ANYSOCK;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	if (Debug)
297*7c478bd9Sstevel@tonic-gate 		printf("clnt_create: Server_Addr %u Prog %d Vers %d Sock %d\n",
298*7c478bd9Sstevel@tonic-gate 			&server_addr, REXPROG, REXVERS, sock);
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 	if ((Client = clnttcp_create(&server_addr, REXPROG, REXVERS, &sock,
301*7c478bd9Sstevel@tonic-gate 					0, 0)) == NULL) {
302*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on: cannot connect to server on %s\n",
303*7c478bd9Sstevel@tonic-gate 			rhost);
304*7c478bd9Sstevel@tonic-gate 		clnt_pcreateerror("on:");
305*7c478bd9Sstevel@tonic-gate 		exit(1);
306*7c478bd9Sstevel@tonic-gate 	}
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 	if (Debug)
309*7c478bd9Sstevel@tonic-gate 		printf("TCP RPC connection created\n");
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 	if (trying_authdes) {
312*7c478bd9Sstevel@tonic-gate 		yp_get_default_domain(&domain);
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate 		cho =  hostname;
315*7c478bd9Sstevel@tonic-gate 		*cho = 0;
316*7c478bd9Sstevel@tonic-gate 		chi =  hp->h_name;
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 		for (i = 0; (*chi && (i < MAXHOSTNAMELEN)); i++)
319*7c478bd9Sstevel@tonic-gate 			{
320*7c478bd9Sstevel@tonic-gate 				if (isupper(*chi))
321*7c478bd9Sstevel@tonic-gate 					*cho = tolower(*chi);
322*7c478bd9Sstevel@tonic-gate 				else
323*7c478bd9Sstevel@tonic-gate 					*cho = *chi;
324*7c478bd9Sstevel@tonic-gate 				cho++;
325*7c478bd9Sstevel@tonic-gate 				chi++;
326*7c478bd9Sstevel@tonic-gate 			}
327*7c478bd9Sstevel@tonic-gate 		*cho = 0;
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 		if (domain != NULL)	{
330*7c478bd9Sstevel@tonic-gate 			if (host2netname(netname, hostname, domain) == 0) {
331*7c478bd9Sstevel@tonic-gate 				trying_authdes = 0;
332*7c478bd9Sstevel@tonic-gate 				if (Debug)
333*7c478bd9Sstevel@tonic-gate 					printf("host2netname failed %s\n",
334*7c478bd9Sstevel@tonic-gate 						hp->h_name);
335*7c478bd9Sstevel@tonic-gate 			}
336*7c478bd9Sstevel@tonic-gate 			/* #ifdef	NOWAY */
337*7c478bd9Sstevel@tonic-gate 			else {
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 				if (getpublickey(netname, publickey) == 0) {
340*7c478bd9Sstevel@tonic-gate 					trying_authdes = 0;
341*7c478bd9Sstevel@tonic-gate 					cho = strchr(hostname, '.');
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 					if (cho) {
344*7c478bd9Sstevel@tonic-gate 						*cho = 0;
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 						if (!host2netname(netname,
347*7c478bd9Sstevel@tonic-gate 						    hostname,
348*7c478bd9Sstevel@tonic-gate 						    domain)) {
349*7c478bd9Sstevel@tonic-gate 							if (Debug)
350*7c478bd9Sstevel@tonic-gate 				printf("host2netname failed %s\n", hp->h_name);
351*7c478bd9Sstevel@tonic-gate 						} else {
352*7c478bd9Sstevel@tonic-gate 							if (getpublickey(
353*7c478bd9Sstevel@tonic-gate 							    netname,
354*7c478bd9Sstevel@tonic-gate 							    publickey) != 0)
355*7c478bd9Sstevel@tonic-gate 							trying_authdes = 1;
356*7c478bd9Sstevel@tonic-gate 						}
357*7c478bd9Sstevel@tonic-gate 					}
358*7c478bd9Sstevel@tonic-gate 				}
359*7c478bd9Sstevel@tonic-gate 			}
360*7c478bd9Sstevel@tonic-gate 		} else {
361*7c478bd9Sstevel@tonic-gate 			trying_authdes = 0;
362*7c478bd9Sstevel@tonic-gate 			if (Debug)
363*7c478bd9Sstevel@tonic-gate 				printf("yp_get_default_domain failed \n");
364*7c478bd9Sstevel@tonic-gate 		}
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 	if (trying_authdes) {
368*7c478bd9Sstevel@tonic-gate 		Client->cl_auth = (AUTH *)authdes_create(netname, 60*60,
369*7c478bd9Sstevel@tonic-gate 						&server_addr, NULL);
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 		if (Client->cl_auth == NULL) {
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 			if (Debug)
374*7c478bd9Sstevel@tonic-gate 				printf("authdes_create failed %s\n", netname);
375*7c478bd9Sstevel@tonic-gate 			trying_authdes = 0;
376*7c478bd9Sstevel@tonic-gate 		}
377*7c478bd9Sstevel@tonic-gate 	}
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 	if (trying_authdes == 0)
381*7c478bd9Sstevel@tonic-gate 		if ((Client->cl_auth = authsys_create_default()) == NULL) {
382*7c478bd9Sstevel@tonic-gate 			clnt_destroy(Client);
383*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,"on: can't create authunix structure.\n");
384*7c478bd9Sstevel@tonic-gate 			exit(1);
385*7c478bd9Sstevel@tonic-gate 		}
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate 	/*
389*7c478bd9Sstevel@tonic-gate 	 * Now that we have created the TCP connection, we do some
390*7c478bd9Sstevel@tonic-gate 	 * work while the server daemon is being swapped in.
391*7c478bd9Sstevel@tonic-gate 	 */
392*7c478bd9Sstevel@tonic-gate 	if (getcwd(curdir, MAXPATHLEN) == (char *)NULL) {
393*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on: can't find . (%s)\n", curdir);
394*7c478bd9Sstevel@tonic-gate 		exit(1);
395*7c478bd9Sstevel@tonic-gate 	}
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 	if (findmount(curdir, wdhost, fsname, dirwithin) == 0) {
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 		if (Debug) {
400*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
401*7c478bd9Sstevel@tonic-gate 				"findmount failed: curdir %s\twdhost %s\t",
402*7c478bd9Sstevel@tonic-gate 				curdir, wdhost);
403*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "fsname %s\tdirwithin %s\n",
404*7c478bd9Sstevel@tonic-gate 				fsname, dirwithin);
405*7c478bd9Sstevel@tonic-gate 		}
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on: can't locate mount point for %s (%s)\n",
408*7c478bd9Sstevel@tonic-gate 			curdir, dirwithin);
409*7c478bd9Sstevel@tonic-gate 		exit(1);
410*7c478bd9Sstevel@tonic-gate 	}
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate 	if (Debug) {
413*7c478bd9Sstevel@tonic-gate 		printf("findmount suceeds: cwd= %s, wd host %s, fs %s,",
414*7c478bd9Sstevel@tonic-gate 			curdir, wdhost, fsname);
415*7c478bd9Sstevel@tonic-gate 		printf("dir within %s\n", dirwithin);
416*7c478bd9Sstevel@tonic-gate 	}
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 	Only2 = samefd(1, 2);
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate 	rst.rst_cmd = (void *)(cmdp);
421*7c478bd9Sstevel@tonic-gate 	rst.rst_host = (void *)wdhost;
422*7c478bd9Sstevel@tonic-gate 	rst.rst_fsname = (void *)fsname;
423*7c478bd9Sstevel@tonic-gate 	rst.rst_dirwithin = (void *)dirwithin;
424*7c478bd9Sstevel@tonic-gate 	rst.rst_env = (void *)environ;
425*7c478bd9Sstevel@tonic-gate 	rst.rst_port0 = makeport(&InOut);
426*7c478bd9Sstevel@tonic-gate 	rst.rst_port1 =  rst.rst_port0;	/* same port for stdin */
427*7c478bd9Sstevel@tonic-gate 	rst.rst_flags = 0;
428*7c478bd9Sstevel@tonic-gate 
429*7c478bd9Sstevel@tonic-gate 	if (Debug)
430*7c478bd9Sstevel@tonic-gate 		printf("before Interactive flags\n");
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate 	if (Interactive) {
433*7c478bd9Sstevel@tonic-gate 		rst.rst_flags |= REX_INTERACTIVE;
434*7c478bd9Sstevel@tonic-gate 		ioctl(0, TIOCGETP, &OldFlags);
435*7c478bd9Sstevel@tonic-gate 		NewFlags = OldFlags;
436*7c478bd9Sstevel@tonic-gate 		NewFlags.sg_flags |= (u_int)RAW;
437*7c478bd9Sstevel@tonic-gate 		NewFlags.sg_flags &= (u_int)~ECHO;
438*7c478bd9Sstevel@tonic-gate 		ioctl(0, TIOCSETN, &NewFlags);
439*7c478bd9Sstevel@tonic-gate 	}
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 	if (Only2) {
442*7c478bd9Sstevel@tonic-gate 		rst.rst_port2 = rst.rst_port1;
443*7c478bd9Sstevel@tonic-gate 	} else {
444*7c478bd9Sstevel@tonic-gate 		rst.rst_port2 = makeport(&Err);
445*7c478bd9Sstevel@tonic-gate 	}
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate 	if (Debug)
448*7c478bd9Sstevel@tonic-gate 		printf("before client call REXPROC_START\n");
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate 	(void) memset(&result, '\0', sizeof(result));
451*7c478bd9Sstevel@tonic-gate 
452*7c478bd9Sstevel@tonic-gate 	if (clstat = clnt_call(Client, REXPROC_START,
453*7c478bd9Sstevel@tonic-gate 			       xdr_rex_start, (caddr_t)&rst,
454*7c478bd9Sstevel@tonic-gate 			       xdr_rex_result, (caddr_t)&result, LongTimeout)) {
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate 		if (Debug)
457*7c478bd9Sstevel@tonic-gate 			printf("Client call failed for REXPROC_START\r\n");
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate 		if (trying_authdes) {
460*7c478bd9Sstevel@tonic-gate 			auth_destroy(Client->cl_auth);
461*7c478bd9Sstevel@tonic-gate 			clnt_destroy(Client);
462*7c478bd9Sstevel@tonic-gate 			trying_authdes = 0;
463*7c478bd9Sstevel@tonic-gate 			if (Interactive)
464*7c478bd9Sstevel@tonic-gate 				ioctl(0, TIOCSETN, &OldFlags);
465*7c478bd9Sstevel@tonic-gate 			goto try_auth_unix;
466*7c478bd9Sstevel@tonic-gate 		} else {
467*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "on %s: ", rhost);
468*7c478bd9Sstevel@tonic-gate 			clnt_perrno(clstat);
469*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "\n");
470*7c478bd9Sstevel@tonic-gate 			Die(1);
471*7c478bd9Sstevel@tonic-gate 		}
472*7c478bd9Sstevel@tonic-gate 	}
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate 	if (result.rlt_stat != 0) {
475*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on %s: %s\n\r", rhost, result.rlt_message);
476*7c478bd9Sstevel@tonic-gate 		Die(1);
477*7c478bd9Sstevel@tonic-gate 	}
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate 	clnt_freeres(Client, xdr_rex_result, (caddr_t)&result);
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	if (Debug)
482*7c478bd9Sstevel@tonic-gate 		printf("Client call suceeded for REXPROC_START\r\n");
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 	if (Interactive) {
485*7c478bd9Sstevel@tonic-gate 		/*
486*7c478bd9Sstevel@tonic-gate 		 * Pass the tty modes along to the server
487*7c478bd9Sstevel@tonic-gate 		 */
488*7c478bd9Sstevel@tonic-gate 		struct rex_ttymode mode;
489*7c478bd9Sstevel@tonic-gate 		int err;
490*7c478bd9Sstevel@tonic-gate 
491*7c478bd9Sstevel@tonic-gate 		mode.basic.sg_ispeed = OldFlags.sg_ispeed;
492*7c478bd9Sstevel@tonic-gate 		mode.basic.sg_ospeed = OldFlags.sg_ospeed;
493*7c478bd9Sstevel@tonic-gate 		mode.basic.sg_erase = OldFlags.sg_erase;
494*7c478bd9Sstevel@tonic-gate 		mode.basic.sg_kill = OldFlags.sg_kill;
495*7c478bd9Sstevel@tonic-gate 		mode.basic.sg_flags = (short) (OldFlags.sg_flags & 0xFFFF);
496*7c478bd9Sstevel@tonic-gate 		err =  (ioctl(0, TIOCGETC, &mode.more) < 0 ||
497*7c478bd9Sstevel@tonic-gate 			ioctl(0, TIOCGLTC, &mode.yetmore) < 0 ||
498*7c478bd9Sstevel@tonic-gate 			ioctl(0, TIOCLGET, &mode.andmore) < 0);
499*7c478bd9Sstevel@tonic-gate 		if (Debug)
500*7c478bd9Sstevel@tonic-gate 			printf("Before clnt_call(REXPROC_MODES) err=%d\n", err);
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate 		if (!err && (clstat = clnt_call(Client, REXPROC_MODES,
503*7c478bd9Sstevel@tonic-gate 					xdr_rex_ttymode, (caddr_t)&mode,
504*7c478bd9Sstevel@tonic-gate 					xdr_void, NULL, LongTimeout))) {
505*7c478bd9Sstevel@tonic-gate 
506*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "on (modes) %s: ", rhost);
507*7c478bd9Sstevel@tonic-gate 			clnt_perrno(clstat);
508*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "\r\n");
509*7c478bd9Sstevel@tonic-gate 		}
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 		err = ioctl(0, TIOCGWINSZ, &newsize) < 0;
512*7c478bd9Sstevel@tonic-gate 		/* typecast important in following lines */
513*7c478bd9Sstevel@tonic-gate 		WindowSize.ts_lines = (int)newsize.ws_row;
514*7c478bd9Sstevel@tonic-gate 		WindowSize.ts_cols = (int)newsize.ws_col;
515*7c478bd9Sstevel@tonic-gate 
516*7c478bd9Sstevel@tonic-gate 		if (Debug)
517*7c478bd9Sstevel@tonic-gate 			printf("Before client call REXPROC_WINCH\n");
518*7c478bd9Sstevel@tonic-gate 
519*7c478bd9Sstevel@tonic-gate 		if (!err && (clstat = clnt_call(Client, REXPROC_WINCH,
520*7c478bd9Sstevel@tonic-gate 					xdr_rex_ttysize, (caddr_t)&WindowSize,
521*7c478bd9Sstevel@tonic-gate 					xdr_void, NULL, LongTimeout))) {
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "on (size) %s: ", rhost);
524*7c478bd9Sstevel@tonic-gate 			clnt_perrno(clstat);
525*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "\r\n");
526*7c478bd9Sstevel@tonic-gate 		}
527*7c478bd9Sstevel@tonic-gate 
528*7c478bd9Sstevel@tonic-gate 		sigset(SIGWINCH, sigwinch);
529*7c478bd9Sstevel@tonic-gate 		sigset(SIGINT, sendsig);
530*7c478bd9Sstevel@tonic-gate 		sigset(SIGQUIT, sendsig);
531*7c478bd9Sstevel@tonic-gate 		sigset(SIGTERM, sendsig);
532*7c478bd9Sstevel@tonic-gate 	}
533*7c478bd9Sstevel@tonic-gate 	sigset(SIGCONT, cont);
534*7c478bd9Sstevel@tonic-gate 	sigset(SIGURG, oob);
535*7c478bd9Sstevel@tonic-gate 	doaccept(&InOut);
536*7c478bd9Sstevel@tonic-gate 	(void) fcntl(InOut, F_SETOWN, getpid());
537*7c478bd9Sstevel@tonic-gate 	FD_ZERO(&remmask);
538*7c478bd9Sstevel@tonic-gate 	FD_SET(InOut, &remmask);
539*7c478bd9Sstevel@tonic-gate 	if (Debug)
540*7c478bd9Sstevel@tonic-gate 		printf("accept on stdout\r\n");
541*7c478bd9Sstevel@tonic-gate 
542*7c478bd9Sstevel@tonic-gate 	if (!Only2) {
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate 		doaccept(&Err);
545*7c478bd9Sstevel@tonic-gate 		shutdown(Err, 1); /* 1=> further sends disallowed */
546*7c478bd9Sstevel@tonic-gate 		if (Debug)
547*7c478bd9Sstevel@tonic-gate 			printf("accept on stderr\r\n");
548*7c478bd9Sstevel@tonic-gate 		FD_SET(Err, &remmask);
549*7c478bd9Sstevel@tonic-gate 	}
550*7c478bd9Sstevel@tonic-gate 
551*7c478bd9Sstevel@tonic-gate 	FD_ZERO(&zmask);
552*7c478bd9Sstevel@tonic-gate 	if (NoInput) {
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 		/*
555*7c478bd9Sstevel@tonic-gate 		 * no input - simulate end-of-file instead
556*7c478bd9Sstevel@tonic-gate 		 */
557*7c478bd9Sstevel@tonic-gate 		shutdown(InOut, 1); /* 1=> further sends disallowed */
558*7c478bd9Sstevel@tonic-gate 	} else {
559*7c478bd9Sstevel@tonic-gate 		/*
560*7c478bd9Sstevel@tonic-gate 		 * set up to read standard input, send to remote
561*7c478bd9Sstevel@tonic-gate 		 */
562*7c478bd9Sstevel@tonic-gate 		FD_SET(0, &zmask);
563*7c478bd9Sstevel@tonic-gate 	}
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 	FD_ZERO(&selmask);
566*7c478bd9Sstevel@tonic-gate 	while (FD_ISSET(InOut, &remmask) || FD_ISSET(Err, &remmask)) {
567*7c478bd9Sstevel@tonic-gate 		if (FD_ISSET(InOut, &remmask))
568*7c478bd9Sstevel@tonic-gate 			FD_SET(InOut, &selmask);
569*7c478bd9Sstevel@tonic-gate 		else
570*7c478bd9Sstevel@tonic-gate 			FD_CLR(InOut, &selmask);
571*7c478bd9Sstevel@tonic-gate 		if (FD_ISSET(Err, &remmask))
572*7c478bd9Sstevel@tonic-gate 			FD_SET(Err, &selmask);
573*7c478bd9Sstevel@tonic-gate 		else
574*7c478bd9Sstevel@tonic-gate 			FD_CLR(Err, &selmask);
575*7c478bd9Sstevel@tonic-gate 		if (FD_ISSET(0, &zmask))
576*7c478bd9Sstevel@tonic-gate 			FD_SET(0, &selmask);
577*7c478bd9Sstevel@tonic-gate 		else
578*7c478bd9Sstevel@tonic-gate 			FD_CLR(0, &selmask);
579*7c478bd9Sstevel@tonic-gate 		nfds = select(FD_SETSIZE, &selmask, (fd_set *) 0, (fd_set *) 0,
580*7c478bd9Sstevel@tonic-gate 			      (struct timeval *) 0);
581*7c478bd9Sstevel@tonic-gate 
582*7c478bd9Sstevel@tonic-gate 
583*7c478bd9Sstevel@tonic-gate  		if (nfds <= 0) {
584*7c478bd9Sstevel@tonic-gate 			if (errno == EINTR) continue;
585*7c478bd9Sstevel@tonic-gate 			perror("on: select");
586*7c478bd9Sstevel@tonic-gate 			Die(1);
587*7c478bd9Sstevel@tonic-gate 		}
588*7c478bd9Sstevel@tonic-gate 		if (FD_ISSET(InOut, &selmask)) {
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate 			cc = read(InOut, buf, sizeof buf);
591*7c478bd9Sstevel@tonic-gate 			if (cc > 0)
592*7c478bd9Sstevel@tonic-gate 				write(1, buf, cc);
593*7c478bd9Sstevel@tonic-gate 			else
594*7c478bd9Sstevel@tonic-gate 				FD_CLR(InOut, &remmask);
595*7c478bd9Sstevel@tonic-gate 		}
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 		if (!Only2 && FD_ISSET(Err, &selmask)) {
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate 			cc = read(Err, buf, sizeof buf);
600*7c478bd9Sstevel@tonic-gate 			if (cc > 0)
601*7c478bd9Sstevel@tonic-gate 				write(2, buf, cc);
602*7c478bd9Sstevel@tonic-gate 			else
603*7c478bd9Sstevel@tonic-gate 				FD_CLR(Err, &remmask);
604*7c478bd9Sstevel@tonic-gate 		}
605*7c478bd9Sstevel@tonic-gate 
606*7c478bd9Sstevel@tonic-gate 		if (!NoInput && FD_ISSET(0, &selmask)) {
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate 			cc = read(0, buf, sizeof buf);
609*7c478bd9Sstevel@tonic-gate 			if (cc > 0)
610*7c478bd9Sstevel@tonic-gate 				write(InOut, buf, cc);
611*7c478bd9Sstevel@tonic-gate 			else {
612*7c478bd9Sstevel@tonic-gate 				/*
613*7c478bd9Sstevel@tonic-gate 				 * End of standard input - shutdown outgoing
614*7c478bd9Sstevel@tonic-gate 				 * direction of the TCP connection.
615*7c478bd9Sstevel@tonic-gate 				 */
616*7c478bd9Sstevel@tonic-gate 				if (Debug)
617*7c478bd9Sstevel@tonic-gate 					printf("Got EOF - shutting down connection\n");
618*7c478bd9Sstevel@tonic-gate 				FD_CLR(0, &zmask);
619*7c478bd9Sstevel@tonic-gate 				shutdown(InOut, 1); /* further sends disallowed */
620*7c478bd9Sstevel@tonic-gate 			}
621*7c478bd9Sstevel@tonic-gate 		}
622*7c478bd9Sstevel@tonic-gate 	}
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 	close(InOut);
625*7c478bd9Sstevel@tonic-gate 	if (!Only2)
626*7c478bd9Sstevel@tonic-gate 		close(Err);
627*7c478bd9Sstevel@tonic-gate 
628*7c478bd9Sstevel@tonic-gate 	(void) memset(&result, '\0', sizeof(result));
629*7c478bd9Sstevel@tonic-gate 
630*7c478bd9Sstevel@tonic-gate 	if (clstat = clnt_call(Client, REXPROC_WAIT,
631*7c478bd9Sstevel@tonic-gate 			       xdr_void, 0, xdr_rex_result, (caddr_t)&result,
632*7c478bd9Sstevel@tonic-gate 			       LongTimeout)) {
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "on: ");
635*7c478bd9Sstevel@tonic-gate 		clnt_perrno(clstat);
636*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "\r\n");
637*7c478bd9Sstevel@tonic-gate 		Die(1);
638*7c478bd9Sstevel@tonic-gate 	}
639*7c478bd9Sstevel@tonic-gate 	Die(result.rlt_stat);
640*7c478bd9Sstevel@tonic-gate }
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate /*
643*7c478bd9Sstevel@tonic-gate  * like exit, but resets the terminal state first
644*7c478bd9Sstevel@tonic-gate  */
645*7c478bd9Sstevel@tonic-gate void
646*7c478bd9Sstevel@tonic-gate Die(int stat)
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate {
649*7c478bd9Sstevel@tonic-gate 	if (Interactive) {
650*7c478bd9Sstevel@tonic-gate 		ioctl(0, TIOCSETN, &OldFlags);
651*7c478bd9Sstevel@tonic-gate 		printf("\r\n");
652*7c478bd9Sstevel@tonic-gate 	}
653*7c478bd9Sstevel@tonic-gate 	exit(stat);
654*7c478bd9Sstevel@tonic-gate }
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate 
657*7c478bd9Sstevel@tonic-gate void
658*7c478bd9Sstevel@tonic-gate remstop()
659*7c478bd9Sstevel@tonic-gate 
660*7c478bd9Sstevel@tonic-gate {
661*7c478bd9Sstevel@tonic-gate 	Die(23);
662*7c478bd9Sstevel@tonic-gate }
663*7c478bd9Sstevel@tonic-gate 
664*7c478bd9Sstevel@tonic-gate /*
665*7c478bd9Sstevel@tonic-gate  * returns true if we can safely say that the two file descriptors
666*7c478bd9Sstevel@tonic-gate  * are the "same" (both are same file).
667*7c478bd9Sstevel@tonic-gate  */
668*7c478bd9Sstevel@tonic-gate int
669*7c478bd9Sstevel@tonic-gate samefd(a, b)
670*7c478bd9Sstevel@tonic-gate {
671*7c478bd9Sstevel@tonic-gate 	struct stat astat, bstat;
672*7c478bd9Sstevel@tonic-gate 
673*7c478bd9Sstevel@tonic-gate 	if (fstat(a, &astat) || fstat(b, &bstat))
674*7c478bd9Sstevel@tonic-gate 		return (0);
675*7c478bd9Sstevel@tonic-gate 	if (astat.st_ino == 0 || bstat.st_ino == 0)
676*7c478bd9Sstevel@tonic-gate 		return (0);
677*7c478bd9Sstevel@tonic-gate 	return (!bcmp(&astat, &bstat, sizeof (astat)));
678*7c478bd9Sstevel@tonic-gate }
679*7c478bd9Sstevel@tonic-gate 
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate /*
682*7c478bd9Sstevel@tonic-gate  * accept the incoming connection on the given
683*7c478bd9Sstevel@tonic-gate  * file descriptor, and return the new file descritpor
684*7c478bd9Sstevel@tonic-gate  */
685*7c478bd9Sstevel@tonic-gate void
686*7c478bd9Sstevel@tonic-gate doaccept(fdp)
687*7c478bd9Sstevel@tonic-gate 	int *fdp;
688*7c478bd9Sstevel@tonic-gate {
689*7c478bd9Sstevel@tonic-gate 	int fd;
690*7c478bd9Sstevel@tonic-gate 
691*7c478bd9Sstevel@tonic-gate 	fd = accept(*fdp, 0, 0);
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate 	if (fd < 0) {
694*7c478bd9Sstevel@tonic-gate 		perror("accept");
695*7c478bd9Sstevel@tonic-gate 		remstop();
696*7c478bd9Sstevel@tonic-gate 	}
697*7c478bd9Sstevel@tonic-gate 	close(*fdp);
698*7c478bd9Sstevel@tonic-gate 	*fdp = fd;
699*7c478bd9Sstevel@tonic-gate }
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate /*
702*7c478bd9Sstevel@tonic-gate  * create a socket, and return its the port number.
703*7c478bd9Sstevel@tonic-gate  */
704*7c478bd9Sstevel@tonic-gate u_short
705*7c478bd9Sstevel@tonic-gate makeport(fdp)
706*7c478bd9Sstevel@tonic-gate 	int *fdp;
707*7c478bd9Sstevel@tonic-gate {
708*7c478bd9Sstevel@tonic-gate 	struct sockaddr_in sin;
709*7c478bd9Sstevel@tonic-gate 	socklen_t len = (socklen_t)sizeof (sin);
710*7c478bd9Sstevel@tonic-gate 	int fd;
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 	fd = socket(AF_INET, SOCK_STREAM, 0);
713*7c478bd9Sstevel@tonic-gate 
714*7c478bd9Sstevel@tonic-gate 	if (fd < 0) {
715*7c478bd9Sstevel@tonic-gate 		perror("socket");
716*7c478bd9Sstevel@tonic-gate 		exit(1);
717*7c478bd9Sstevel@tonic-gate 	}
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate 	bzero((char *)&sin, sizeof (sin));
720*7c478bd9Sstevel@tonic-gate 	sin.sin_family = AF_INET;
721*7c478bd9Sstevel@tonic-gate 	bind(fd, (struct sockaddr *)&sin, sizeof (sin));
722*7c478bd9Sstevel@tonic-gate 	getsockname(fd, (struct sockaddr *)&sin, &len);
723*7c478bd9Sstevel@tonic-gate 	listen(fd, 1);
724*7c478bd9Sstevel@tonic-gate 	*fdp = fd;
725*7c478bd9Sstevel@tonic-gate 	return (htons(sin.sin_port));
726*7c478bd9Sstevel@tonic-gate }
727*7c478bd9Sstevel@tonic-gate 
728*7c478bd9Sstevel@tonic-gate void
729*7c478bd9Sstevel@tonic-gate usage(void)
730*7c478bd9Sstevel@tonic-gate {
731*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "Usage: on [-i|-n] [-d] machine cmd [args]...\n");
732*7c478bd9Sstevel@tonic-gate 	exit(1);
733*7c478bd9Sstevel@tonic-gate }
734*7c478bd9Sstevel@tonic-gate 
735*7c478bd9Sstevel@tonic-gate /*
736*7c478bd9Sstevel@tonic-gate  *  SETPROCTITLE -- set the title of this process for "ps"
737*7c478bd9Sstevel@tonic-gate  *
738*7c478bd9Sstevel@tonic-gate  *	Does nothing if there were not enough arguments on the command
739*7c478bd9Sstevel@tonic-gate  * 	line for the information.
740*7c478bd9Sstevel@tonic-gate  *
741*7c478bd9Sstevel@tonic-gate  *	Side Effects:
742*7c478bd9Sstevel@tonic-gate  *		Clobbers argv[] of our main procedure.
743*7c478bd9Sstevel@tonic-gate  */
744*7c478bd9Sstevel@tonic-gate void
745*7c478bd9Sstevel@tonic-gate setproctitle(user, host)
746*7c478bd9Sstevel@tonic-gate 	char *user, *host;
747*7c478bd9Sstevel@tonic-gate {
748*7c478bd9Sstevel@tonic-gate 	register char *tohere;
749*7c478bd9Sstevel@tonic-gate 
750*7c478bd9Sstevel@tonic-gate 	tohere = Argv[0];
751*7c478bd9Sstevel@tonic-gate 	if ((int)LastArgv == (int)((char *)NULL) ||
752*7c478bd9Sstevel@tonic-gate 	    (int)(strlen(user) + strlen(host)+3) > (int)(LastArgv - tohere))
753*7c478bd9Sstevel@tonic-gate 		return;
754*7c478bd9Sstevel@tonic-gate 	*tohere++ = '-';		/* So ps prints (rpc.rexd) */
755*7c478bd9Sstevel@tonic-gate 	sprintf(tohere, "%s@%s", user, host);
756*7c478bd9Sstevel@tonic-gate 	while (*tohere++)		/* Skip to end of printf output	*/
757*7c478bd9Sstevel@tonic-gate 		;
758*7c478bd9Sstevel@tonic-gate 	while (tohere < LastArgv)	/* Avoid confusing ps		*/
759*7c478bd9Sstevel@tonic-gate 		*tohere++ = ' ';
760*7c478bd9Sstevel@tonic-gate }
761