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 this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #if defined(LIBC_SCCS) && !defined(lint) 14 static char sccsid[] = "@(#)rexec.c 5.4 (Berkeley) 03/07/88"; 15 #endif /* LIBC_SCCS and not lint */ 16 17 #include <sys/types.h> 18 #include <sys/socket.h> 19 20 #include <netinet/in.h> 21 22 #include <stdio.h> 23 #include <netdb.h> 24 #include <errno.h> 25 26 extern errno; 27 char *index(); 28 int rexecoptions; 29 char *getpass(), *getlogin(); 30 31 rexec(ahost, rport, name, pass, cmd, fd2p) 32 char **ahost; 33 int rport; 34 char *name, *pass, *cmd; 35 int *fd2p; 36 { 37 int s, timo = 1, s3; 38 struct sockaddr_in sin, sin2, from; 39 char c; 40 short port; 41 struct hostent *hp; 42 43 hp = gethostbyname(*ahost); 44 if (hp == 0) { 45 fprintf(stderr, "%s: unknown host\n", *ahost); 46 return (-1); 47 } 48 *ahost = hp->h_name; 49 ruserpass(hp->h_name, &name, &pass); 50 retry: 51 s = socket(AF_INET, SOCK_STREAM, 0); 52 if (s < 0) { 53 perror("rexec: socket"); 54 return (-1); 55 } 56 sin.sin_family = hp->h_addrtype; 57 sin.sin_port = rport; 58 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 59 if (connect(s, &sin, sizeof(sin)) < 0) { 60 if (errno == ECONNREFUSED && timo <= 16) { 61 (void) close(s); 62 sleep(timo); 63 timo *= 2; 64 goto retry; 65 } 66 perror(hp->h_name); 67 return (-1); 68 } 69 if (fd2p == 0) { 70 (void) write(s, "", 1); 71 port = 0; 72 } else { 73 char num[8]; 74 int s2, sin2len; 75 76 s2 = socket(AF_INET, SOCK_STREAM, 0); 77 if (s2 < 0) { 78 (void) close(s); 79 return (-1); 80 } 81 listen(s2, 1); 82 sin2len = sizeof (sin2); 83 if (getsockname(s2, (char *)&sin2, &sin2len) < 0 || 84 sin2len != sizeof (sin2)) { 85 perror("getsockname"); 86 (void) close(s2); 87 goto bad; 88 } 89 port = ntohs((u_short)sin2.sin_port); 90 (void) sprintf(num, "%d", port); 91 (void) write(s, num, strlen(num)+1); 92 { int len = sizeof (from); 93 s3 = accept(s2, &from, &len, 0); 94 close(s2); 95 if (s3 < 0) { 96 perror("accept"); 97 port = 0; 98 goto bad; 99 } 100 } 101 *fd2p = s3; 102 } 103 (void) write(s, name, strlen(name) + 1); 104 /* should public key encypt the password here */ 105 (void) write(s, pass, strlen(pass) + 1); 106 (void) write(s, cmd, strlen(cmd) + 1); 107 if (read(s, &c, 1) != 1) { 108 perror(*ahost); 109 goto bad; 110 } 111 if (c != 0) { 112 while (read(s, &c, 1) == 1) { 113 (void) write(2, &c, 1); 114 if (c == '\n') 115 break; 116 } 117 goto bad; 118 } 119 return (s); 120 bad: 121 if (port) 122 (void) close(*fd2p); 123 (void) close(s); 124 return (-1); 125 } 126