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