1 #ifndef lint 2 static char sccsid[] = "@(#)rcmd.c 4.2 82/10/07"; 3 #endif 4 5 #include <stdio.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <net/in.h> 9 #include <errno.h> 10 #include <netdb.h> 11 12 extern errno; 13 char *index(), *sprintf(); 14 int rcmdoptions; 15 16 rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 17 char **ahost; 18 int rport; 19 char *locuser, *remuser, *cmd; 20 int *fd2p; 21 { 22 int s, addr, timo = 1; 23 struct sockaddr_in sin, sin2, from; 24 char c; 25 short port; 26 struct hostent *hp; 27 28 hp = gethostbyname(*ahost); 29 if (hp == 0) { 30 fprintf(stderr, "%s: unknown host\n", *ahost); 31 return (-1); 32 } 33 *ahost = hp->h_name; 34 retry: 35 s = rresvport(rcmdoptions|SO_KEEPALIVE); 36 if (s < 0) 37 return (-1); 38 sin.sin_family = hp->h_addrtype; 39 bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); 40 sin.sin_port = htons(rport); 41 if (connect(s, &sin) < 0) { 42 if (errno == ECONNREFUSED && timo <= 16) { 43 (void) close(s); 44 sleep(timo); 45 timo *= 2; 46 goto retry; 47 } 48 perror(*ahost); 49 return (-1); 50 } 51 if (fd2p == 0) { 52 write(s, "", 1); 53 port = 0; 54 } else { 55 char num[8]; 56 int s2 = rresvport(rcmdoptions|SO_ACCEPTCONN); 57 58 if (s2 < 0) { 59 (void) close(s); 60 return (-1); 61 } 62 socketaddr(s2, &sin2); 63 port = htons((u_short)sin2.sin_port); 64 (void) sprintf(num, "%d", port); 65 (void) write(s, num, strlen(num)+1); 66 if (accept(s2, &from) < 0) { 67 perror("accept"); 68 goto bad; 69 } 70 from.sin_port = ntohs(from.sin_port); 71 if (from.sin_family != AF_INET || 72 from.sin_port >= IPPORT_RESERVED) { 73 fprintf(stderr, 74 "socket: protocol failure in circuit setup.\n"); 75 goto bad; 76 } 77 *fd2p = s2; 78 } 79 (void) write(s, locuser, strlen(locuser)+1); 80 (void) write(s, remuser, strlen(remuser)+1); 81 (void) write(s, cmd, strlen(cmd)+1); 82 if (read(s, &c, 1) != 1) { 83 perror(*ahost); 84 goto bad; 85 } 86 if (c != 0) { 87 while (read(s, &c, 1) == 1) { 88 (void) write(2, &c, 1); 89 if (c == '\n') 90 break; 91 } 92 goto bad; 93 } 94 return (s); 95 bad: 96 if (port) 97 (void) close(*fd2p); 98 (void) close(s); 99 return (-1); 100 } 101 102 rresvport(options) 103 int options; 104 { 105 struct sockaddr_in sin; 106 short lport = IPPORT_RESERVED - 1; 107 int s; 108 109 for (;;) { 110 sin.sin_family = AF_INET; 111 sin.sin_port = htons(lport); 112 sin.sin_addr.s_addr = 0; 113 s = socket(SOCK_STREAM, 0, &sin, options); 114 if (s >= 0) 115 return (s); 116 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { 117 perror("socket"); 118 return (-1); 119 } 120 lport--; 121 if (lport == IPPORT_RESERVED/2) { 122 fprintf(stderr, "socket: All ports in use\n"); 123 return (-1); 124 } 125 } 126 } 127 128 ruserok(rhost, ruser, luser) 129 char *rhost, *ruser, *luser; 130 { 131 FILE *hostf; 132 char ahost[32]; 133 int first = 1; 134 135 hostf = fopen("/etc/hosts.equiv", "r"); 136 again: 137 if (hostf) { 138 while (fgets(ahost, sizeof (ahost), hostf)) { 139 char *user; 140 if (index(ahost, '\n')) 141 *index(ahost, '\n') = 0; 142 user = index(ahost, ' '); 143 if (user) 144 *user++ = 0; 145 if (!strcmp(rhost, ahost) && 146 !strcmp(ruser, user ? user : luser)) 147 goto ok; 148 } 149 (void) fclose(hostf); 150 } 151 if (first == 1) { 152 first = 0; 153 hostf = fopen(".rhosts", "r"); 154 goto again; 155 } 156 return (-1); 157 ok: 158 (void) fclose(hostf); 159 return (0); 160 } 161