1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 	  /* from UCB 4.8 83/08/18 */
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #include <sys/types.h>
31*0Sstevel@tonic-gate #include <sys/socket.h>
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include <netinet/in.h>
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <netdb.h>
37*0Sstevel@tonic-gate #include <errno.h>
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate extern	errno;
40*0Sstevel@tonic-gate char	*index();
41*0Sstevel@tonic-gate char	*getpass(), *getlogin();
42*0Sstevel@tonic-gate #ifndef	S5EMUL
43*0Sstevel@tonic-gate char	*sprintf();
44*0Sstevel@tonic-gate #endif
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate int
47*0Sstevel@tonic-gate rexec(
48*0Sstevel@tonic-gate 	char **ahost,
49*0Sstevel@tonic-gate 	unsigned short rport,
50*0Sstevel@tonic-gate 	const char *name,
51*0Sstevel@tonic-gate 	const char *pass,
52*0Sstevel@tonic-gate 	const char *cmd,
53*0Sstevel@tonic-gate 	int *fd2p)
54*0Sstevel@tonic-gate {
55*0Sstevel@tonic-gate 	int s, timo = 1, s3;
56*0Sstevel@tonic-gate 	struct sockaddr_in sin, sin2, from;
57*0Sstevel@tonic-gate 	char c;
58*0Sstevel@tonic-gate 	u_short port;
59*0Sstevel@tonic-gate 	struct hostent *hp;
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate 	hp = gethostbyname(*ahost);
62*0Sstevel@tonic-gate 	if (hp == 0) {
63*0Sstevel@tonic-gate 		fprintf(stderr, "%s: unknown host\n", *ahost);
64*0Sstevel@tonic-gate 		return (-1);
65*0Sstevel@tonic-gate 	}
66*0Sstevel@tonic-gate 	*ahost = hp->h_name;
67*0Sstevel@tonic-gate 	_ruserpass(hp->h_name, &name, &pass);
68*0Sstevel@tonic-gate retry:
69*0Sstevel@tonic-gate 	s = socket(AF_INET, SOCK_STREAM, 0);
70*0Sstevel@tonic-gate 	if (s < 0) {
71*0Sstevel@tonic-gate 		perror("rexec: socket");
72*0Sstevel@tonic-gate 		return (-1);
73*0Sstevel@tonic-gate 	}
74*0Sstevel@tonic-gate 	sin.sin_family = hp->h_addrtype;
75*0Sstevel@tonic-gate 	sin.sin_port = rport;
76*0Sstevel@tonic-gate 	bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
77*0Sstevel@tonic-gate 	if (connect(s, &sin, sizeof(sin)) < 0) {
78*0Sstevel@tonic-gate 		if (errno == ECONNREFUSED && timo <= 16) {
79*0Sstevel@tonic-gate 			(void) close(s);
80*0Sstevel@tonic-gate 			sleep(timo);
81*0Sstevel@tonic-gate 			timo *= 2;
82*0Sstevel@tonic-gate 			goto retry;
83*0Sstevel@tonic-gate 		}
84*0Sstevel@tonic-gate 		perror(hp->h_name);
85*0Sstevel@tonic-gate 		(void) close(s);
86*0Sstevel@tonic-gate 		return (-1);
87*0Sstevel@tonic-gate 	}
88*0Sstevel@tonic-gate 	if (fd2p == 0) {
89*0Sstevel@tonic-gate 		(void) write(s, "", 1);
90*0Sstevel@tonic-gate 		port = 0;
91*0Sstevel@tonic-gate 	} else {
92*0Sstevel@tonic-gate 		char num[8];
93*0Sstevel@tonic-gate 		int s2, sin2len;
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 		s2 = socket(AF_INET, SOCK_STREAM, 0);
96*0Sstevel@tonic-gate 		if (s2 < 0) {
97*0Sstevel@tonic-gate 			(void) close(s);
98*0Sstevel@tonic-gate 			return (-1);
99*0Sstevel@tonic-gate 		}
100*0Sstevel@tonic-gate 		listen(s2, 1);
101*0Sstevel@tonic-gate 		sin2len = sizeof (sin2);
102*0Sstevel@tonic-gate 		if (getsockname(s2, (char *)&sin2, &sin2len) < 0 ||
103*0Sstevel@tonic-gate 		  sin2len != sizeof (sin2)) {
104*0Sstevel@tonic-gate 			perror("getsockname");
105*0Sstevel@tonic-gate 			(void) close(s2);
106*0Sstevel@tonic-gate 			goto bad;
107*0Sstevel@tonic-gate 		}
108*0Sstevel@tonic-gate 		port = ntohs((u_short)sin2.sin_port);
109*0Sstevel@tonic-gate 		(void) sprintf(num, "%u", port);
110*0Sstevel@tonic-gate 		(void) write(s, num, strlen(num)+1);
111*0Sstevel@tonic-gate 		{ int len = sizeof (from);
112*0Sstevel@tonic-gate 		  s3 = accept(s2, &from, &len);
113*0Sstevel@tonic-gate 		  close(s2);
114*0Sstevel@tonic-gate 		  if (s3 < 0) {
115*0Sstevel@tonic-gate 			perror("accept");
116*0Sstevel@tonic-gate 			port = 0;
117*0Sstevel@tonic-gate 			goto bad;
118*0Sstevel@tonic-gate 		  }
119*0Sstevel@tonic-gate 		}
120*0Sstevel@tonic-gate 		*fd2p = s3;
121*0Sstevel@tonic-gate 	}
122*0Sstevel@tonic-gate 	(void) write(s, name, strlen(name) + 1);
123*0Sstevel@tonic-gate 	/* should public key encypt the password here */
124*0Sstevel@tonic-gate 	(void) write(s, pass, strlen(pass) + 1);
125*0Sstevel@tonic-gate 	(void) write(s, cmd, strlen(cmd) + 1);
126*0Sstevel@tonic-gate 	if (read(s, &c, 1) != 1) {
127*0Sstevel@tonic-gate 		perror(*ahost);
128*0Sstevel@tonic-gate 		goto bad;
129*0Sstevel@tonic-gate 	}
130*0Sstevel@tonic-gate 	if (c != 0) {
131*0Sstevel@tonic-gate 		while (read(s, &c, 1) == 1) {
132*0Sstevel@tonic-gate 			(void) write(2, &c, 1);
133*0Sstevel@tonic-gate 			if (c == '\n')
134*0Sstevel@tonic-gate 				break;
135*0Sstevel@tonic-gate 		}
136*0Sstevel@tonic-gate 		goto bad;
137*0Sstevel@tonic-gate 	}
138*0Sstevel@tonic-gate 	return (s);
139*0Sstevel@tonic-gate bad:
140*0Sstevel@tonic-gate 	if (port)
141*0Sstevel@tonic-gate 		(void) close(*fd2p);
142*0Sstevel@tonic-gate 	(void) close(s);
143*0Sstevel@tonic-gate 	return (-1);
144*0Sstevel@tonic-gate }
145