1 #ifndef lint 2 static char sccsid[] = "@(#)rcmd.c 4.7 02/23/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 if (write(s, num, strlen(num)+1) != strlen(num)+1) { 72 perror("write: setting up stderr"); 73 (void) close(s2); 74 goto bad; 75 } 76 { int len = sizeof (from); 77 s3 = accept(s2, &from, &len, 0); 78 close(s2); 79 if (s3 < 0) { 80 perror("accept"); 81 lport = 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 (lport) 112 (void) close(*fd2p); 113 bad: 114 (void) close(s); 115 return (-1); 116 } 117 118 rresvport(alport) 119 int *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, superuser, ruser, luser) 146 char *rhost; 147 int superuser; 148 char *ruser, *luser; 149 { 150 FILE *hostf; 151 char ahost[32]; 152 int first = 1; 153 154 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); 155 again: 156 if (hostf) { 157 while (fgets(ahost, sizeof (ahost), hostf)) { 158 char *user; 159 if (index(ahost, '\n')) 160 *index(ahost, '\n') = 0; 161 user = index(ahost, ' '); 162 if (user) 163 *user++ = 0; 164 if (!strcmp(rhost, ahost) && 165 !strcmp(ruser, user ? user : luser)) { 166 (void) fclose(hostf); 167 return (0); 168 } 169 } 170 (void) fclose(hostf); 171 } 172 if (first == 1) { 173 first = 0; 174 hostf = fopen(".rhosts", "r"); 175 goto again; 176 } 177 return (-1); 178 } 179 180 socketaddr(x, y) 181 { 182 183 syscall(103,x,y); 184 } 185