1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/types.h>
13 #include <sys/socket.h>
14
15 #include <netinet/in.h>
16
17 #include <stdio.h>
18 #include <netdb.h>
19 #include <errno.h>
20
21 extern errno;
22 char *index();
23 int rexecoptions;
24 char *getpass(), *getlogin();
25
rexec(ahost,rport,name,pass,cmd,fd2p)26 rexec(ahost, rport, name, pass, cmd, fd2p)
27 char **ahost;
28 int rport;
29 char *name, *pass, *cmd;
30 int *fd2p;
31 {
32 struct sockaddr_in sin, sin2, from;
33 struct hostent *hp;
34 u_short port;
35 int s, timo = 1, s3;
36 char c;
37
38 hp = gethostbyname(*ahost);
39 if (hp == 0) {
40 herror(*ahost);
41 return (-1);
42 }
43 *ahost = hp->h_name;
44 ruserpass(hp->h_name, &name, &pass);
45 retry:
46 s = socket(AF_INET, SOCK_STREAM, 0);
47 if (s < 0) {
48 perror("rexec: socket");
49 return (-1);
50 }
51 sin.sin_family = hp->h_addrtype;
52 sin.sin_port = rport;
53 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
54 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
55 if (errno == ECONNREFUSED && timo <= 16) {
56 (void) close(s);
57 sleep(timo);
58 timo *= 2;
59 goto retry;
60 }
61 perror(hp->h_name);
62 return (-1);
63 }
64 if (fd2p == 0) {
65 (void) write(s, "", 1);
66 port = 0;
67 } else {
68 char num[8];
69 int s2, sin2len;
70
71 s2 = socket(AF_INET, SOCK_STREAM, 0);
72 if (s2 < 0) {
73 (void) close(s);
74 return (-1);
75 }
76 listen(s2, 1);
77 sin2len = sizeof (sin2);
78 if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
79 sin2len != sizeof (sin2)) {
80 perror("getsockname");
81 (void) close(s2);
82 goto bad;
83 }
84 port = ntohs((u_short)sin2.sin_port);
85 (void) sprintf(num, "%u", port);
86 (void) write(s, num, strlen(num)+1);
87 { int len = sizeof (from);
88 s3 = accept(s2, (struct sockaddr *)&from, &len);
89 close(s2);
90 if (s3 < 0) {
91 perror("accept");
92 port = 0;
93 goto bad;
94 }
95 }
96 *fd2p = s3;
97 }
98 (void) write(s, name, strlen(name) + 1);
99 /* should public key encypt the password here */
100 (void) write(s, pass, strlen(pass) + 1);
101 (void) write(s, cmd, strlen(cmd) + 1);
102 if (read(s, &c, 1) != 1) {
103 perror(*ahost);
104 goto bad;
105 }
106 if (c != 0) {
107 while (read(s, &c, 1) == 1) {
108 (void) write(2, &c, 1);
109 if (c == '\n')
110 break;
111 }
112 goto bad;
113 }
114 return (s);
115 bad:
116 if (port)
117 (void) close(*fd2p);
118 (void) close(s);
119 return (-1);
120 }
121