1 #ifndef lint 2 static char sccsid[] = "@(#)rcmd.c 4.1 82/04/02"; 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 11 extern errno; 12 char *index(), *sprintf(); 13 int rcmdoptions; 14 15 rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 16 char **ahost; 17 int rport; 18 char *locuser, *remuser, *cmd; 19 int *fd2p; 20 { 21 int s, addr, timo = 1; 22 struct sockaddr_in sin, sin2, from; 23 char c; 24 short port; 25 26 addr = rhost(ahost); 27 if (addr == -1) { 28 fprintf(stderr, "%s: unknown host\n", *ahost); 29 return (-1); 30 } 31 retry: 32 s = rresvport(rcmdoptions|SO_KEEPALIVE); 33 if (s < 0) 34 return (-1); 35 sin.sin_family = AF_INET; 36 sin.sin_addr.s_addr = addr; 37 sin.sin_port = rport; 38 #ifdef vax 39 sin.sin_port = htons(sin.sin_port); 40 #endif 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 = sin2.sin_port; 64 #if vax 65 port = htons((u_short)port); 66 #endif 67 (void) sprintf(num, "%d", port); 68 (void) write(s, num, strlen(num)+1); 69 if (accept(s2, &from) < 0) { 70 perror("accept"); 71 goto bad; 72 } 73 #if vax 74 from.sin_port = ntohs(from.sin_port); 75 #endif 76 if (from.sin_family != AF_INET || 77 from.sin_port >= IPPORT_RESERVED) { 78 fprintf(stderr, 79 "socket: protocol failure in circuit setup.\n"); 80 goto bad; 81 } 82 *fd2p = s2; 83 } 84 (void) write(s, locuser, strlen(locuser)+1); 85 (void) write(s, remuser, strlen(remuser)+1); 86 (void) write(s, cmd, strlen(cmd)+1); 87 if (read(s, &c, 1) != 1) { 88 perror(*ahost); 89 goto bad; 90 } 91 if (c != 0) { 92 while (read(s, &c, 1) == 1) { 93 (void) write(2, &c, 1); 94 if (c == '\n') 95 break; 96 } 97 goto bad; 98 } 99 return (s); 100 bad: 101 if (port) 102 (void) close(*fd2p); 103 (void) close(s); 104 return (-1); 105 } 106 107 rresvport(options) 108 int options; 109 { 110 struct sockaddr_in sin; 111 short lport = IPPORT_RESERVED - 1; 112 int s; 113 114 for (;;) { 115 sin.sin_family = AF_INET; 116 sin.sin_port = lport; 117 sin.sin_addr.s_addr = 0; 118 #ifdef vax 119 sin.sin_port = htons(sin.sin_port); 120 #endif 121 s = socket(SOCK_STREAM, 0, &sin, options); 122 if (s >= 0) 123 return (s); 124 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { 125 perror("socket"); 126 return (-1); 127 } 128 lport--; 129 if (lport == IPPORT_RESERVED/2) { 130 fprintf(stderr, "socket: All ports in use\n"); 131 return (-1); 132 } 133 } 134 } 135 136 ruserok(rhost, ruser, luser) 137 char *rhost, *ruser, *luser; 138 { 139 FILE *hostf; 140 char ahost[32]; 141 int first = 1; 142 143 hostf = fopen("/etc/hosts.equiv", "r"); 144 again: 145 if (hostf) { 146 while (fgets(ahost, sizeof (ahost), hostf)) { 147 char *user; 148 if (index(ahost, '\n')) 149 *index(ahost, '\n') = 0; 150 user = index(ahost, ' '); 151 if (user) 152 *user++ = 0; 153 if (!strcmp(rhost, ahost) && 154 !strcmp(ruser, user ? user : luser)) 155 goto ok; 156 } 157 (void) fclose(hostf); 158 } 159 if (first == 1) { 160 first = 0; 161 hostf = fopen(".rhosts", "r"); 162 goto again; 163 } 164 return (-1); 165 ok: 166 (void) fclose(hostf); 167 return (0); 168 } 169