xref: /original-bsd/lib/libcompat/4.3/rexec.c (revision 31205e5f)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static char sccsid[] = "@(#)rexec.c	5.5 (Berkeley) 06/27/88";
20 #endif /* LIBC_SCCS and not lint */
21 
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 
25 #include <netinet/in.h>
26 
27 #include <stdio.h>
28 #include <netdb.h>
29 #include <errno.h>
30 
31 extern	errno;
32 char	*index();
33 int	rexecoptions;
34 char	*getpass(), *getlogin();
35 
36 rexec(ahost, rport, name, pass, cmd, fd2p)
37 	char **ahost;
38 	int rport;
39 	char *name, *pass, *cmd;
40 	int *fd2p;
41 {
42 	int s, timo = 1, s3;
43 	struct sockaddr_in sin, sin2, from;
44 	char c;
45 	short port;
46 	struct hostent *hp;
47 
48 	hp = gethostbyname(*ahost);
49 	if (hp == 0) {
50 		fprintf(stderr, "%s: unknown host\n", *ahost);
51 		return (-1);
52 	}
53 	*ahost = hp->h_name;
54 	ruserpass(hp->h_name, &name, &pass);
55 retry:
56 	s = socket(AF_INET, SOCK_STREAM, 0);
57 	if (s < 0) {
58 		perror("rexec: socket");
59 		return (-1);
60 	}
61 	sin.sin_family = hp->h_addrtype;
62 	sin.sin_port = rport;
63 	bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
64 	if (connect(s, &sin, sizeof(sin)) < 0) {
65 		if (errno == ECONNREFUSED && timo <= 16) {
66 			(void) close(s);
67 			sleep(timo);
68 			timo *= 2;
69 			goto retry;
70 		}
71 		perror(hp->h_name);
72 		return (-1);
73 	}
74 	if (fd2p == 0) {
75 		(void) write(s, "", 1);
76 		port = 0;
77 	} else {
78 		char num[8];
79 		int s2, sin2len;
80 
81 		s2 = socket(AF_INET, SOCK_STREAM, 0);
82 		if (s2 < 0) {
83 			(void) close(s);
84 			return (-1);
85 		}
86 		listen(s2, 1);
87 		sin2len = sizeof (sin2);
88 		if (getsockname(s2, (char *)&sin2, &sin2len) < 0 ||
89 		  sin2len != sizeof (sin2)) {
90 			perror("getsockname");
91 			(void) close(s2);
92 			goto bad;
93 		}
94 		port = ntohs((u_short)sin2.sin_port);
95 		(void) sprintf(num, "%d", port);
96 		(void) write(s, num, strlen(num)+1);
97 		{ int len = sizeof (from);
98 		  s3 = accept(s2, &from, &len, 0);
99 		  close(s2);
100 		  if (s3 < 0) {
101 			perror("accept");
102 			port = 0;
103 			goto bad;
104 		  }
105 		}
106 		*fd2p = s3;
107 	}
108 	(void) write(s, name, strlen(name) + 1);
109 	/* should public key encypt the password here */
110 	(void) write(s, pass, strlen(pass) + 1);
111 	(void) write(s, cmd, strlen(cmd) + 1);
112 	if (read(s, &c, 1) != 1) {
113 		perror(*ahost);
114 		goto bad;
115 	}
116 	if (c != 0) {
117 		while (read(s, &c, 1) == 1) {
118 			(void) write(2, &c, 1);
119 			if (c == '\n')
120 				break;
121 		}
122 		goto bad;
123 	}
124 	return (s);
125 bad:
126 	if (port)
127 		(void) close(*fd2p);
128 	(void) close(s);
129 	return (-1);
130 }
131