1 #ifndef lint 2 static char sccsid[] = "@(#)rcmd.c 4.10 05/30/85"; 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 (void) close(s); 44 if (errno == EADDRINUSE) { 45 lport--; 46 goto retry; 47 } 48 if (errno == ECONNREFUSED && timo <= 16) { 49 sleep(timo); 50 timo *= 2; 51 goto retry; 52 } 53 perror(hp->h_name); 54 return (-1); 55 } 56 lport--; 57 if (fd2p == 0) { 58 write(s, "", 1); 59 lport = 0; 60 } else { 61 char num[8]; 62 int s2 = rresvport(&lport), s3; 63 int len = sizeof (from); 64 65 if (s2 < 0) 66 goto bad; 67 listen(s2, 1); 68 (void) sprintf(num, "%d", lport); 69 if (write(s, num, strlen(num)+1) != strlen(num)+1) { 70 perror("write: setting up stderr"); 71 (void) close(s2); 72 goto bad; 73 } 74 s3 = accept(s2, &from, &len, 0); 75 (void) close(s2); 76 if (s3 < 0) { 77 perror("accept"); 78 lport = 0; 79 goto bad; 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 (void) close(s); 132 return (-1); 133 } 134 (*alport)--; 135 if (*alport == IPPORT_RESERVED/2) { 136 fprintf(stderr, "socket: All ports in use\n"); 137 (void) close(s); 138 return (-1); 139 } 140 } 141 } 142 143 ruserok(rhost, superuser, ruser, luser) 144 char *rhost; 145 int superuser; 146 char *ruser, *luser; 147 { 148 FILE *hostf; 149 char ahost[32]; 150 int first = 1; 151 152 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); 153 again: 154 if (hostf) { 155 while (fgets(ahost, sizeof (ahost), hostf)) { 156 register char *p; 157 char *user; 158 159 p = ahost; 160 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 161 p++; 162 if (*p == ' ' || *p == '\t') { 163 *p++ = '\0'; 164 while (*p == ' ' || *p == '\t') 165 p++; 166 user = p; 167 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 168 p++; 169 } else 170 user = p; 171 *p = '\0'; 172 if (!strcmp(rhost, ahost) && 173 !strcmp(ruser, *user ? user : luser)) { 174 (void) fclose(hostf); 175 return (0); 176 } 177 } 178 (void) fclose(hostf); 179 } 180 if (first == 1) { 181 first = 0; 182 hostf = fopen(".rhosts", "r"); 183 goto again; 184 } 185 return (-1); 186 } 187