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