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