|
|
1.1 ! root 1: /* client.c - connect to a server */ ! 2: ! 3: #ifdef BSD42 ! 4: #include "../h/strings.h" ! 5: #include <stdio.h> ! 6: #include "mts.h" ! 7: #include <errno.h> ! 8: #include <sys/types.h> ! 9: #include <sys/socket.h> ! 10: #include <netinet/in.h> ! 11: #include <netdb.h> ! 12: #include <arpa/inet.h> ! 13: ! 14: ! 15: #define NOTOK (-1) ! 16: #define OK 0 ! 17: #define DONE 1 ! 18: ! 19: #define TRUE 1 ! 20: #define FALSE 0 ! 21: ! 22: #define OOPS1 (-2) ! 23: #define OOPS2 (-3) ! 24: ! 25: #define MAXARGS 1000 ! 26: #define MAXNETS 5 ! 27: #define MAXHOSTS 25 ! 28: ! 29: /* */ ! 30: ! 31: extern int errno; ! 32: extern int sys_nerr; ! 33: extern char *sys_errlist[]; ! 34: ! 35: ! 36: struct addrent { ! 37: int a_addrtype; /* assumes AF_INET for inet_netof () */ ! 38: ! 39: union { ! 40: int un_net; ! 41: char un_addr[14]; ! 42: } un; ! 43: #define a_net un.un_net ! 44: #define a_addr un.un_addr ! 45: }; ! 46: ! 47: static struct addrent *ne, *nz; ! 48: static struct addrent nets[MAXNETS]; ! 49: ! 50: static struct addrent *he, *hz; ! 51: static struct addrent hosts[MAXHOSTS]; ! 52: ! 53: static int rcaux(), getport(), inet(), brkany(); ! 54: static char **brkstring(), **copyip(), *getcpy(); ! 55: ! 56: /* */ ! 57: ! 58: client(args, protocol, service, rproto, response) ! 59: char *args, *protocol, *service, *response; ! 60: int rproto; ! 61: { ! 62: int sd; ! 63: register char **ap; ! 64: char *arguments[MAXARGS]; ! 65: register struct hostent *hp; ! 66: #ifndef BIND ! 67: register struct netent *np; ! 68: #endif BIND ! 69: register struct servent *sp; ! 70: ! 71: if ((sp = getservbyname (service, protocol)) == NULL) { ! 72: (void) sprintf (response, "%s/%s: unknown service", protocol, service); ! 73: return NOTOK; ! 74: } ! 75: ! 76: ap = arguments; ! 77: if (args != NULL && *args != NULL) ! 78: ap = copyip (brkstring (getcpy (args), " ", "\n"), ap); ! 79: else ! 80: if (servers != NULL && *servers != NULL) ! 81: ap = copyip (brkstring (getcpy (servers), " ", "\n"), ap); ! 82: if (ap == arguments) { ! 83: *ap++ = getcpy ("localhost"); ! 84: *ap = NULL; ! 85: } ! 86: ! 87: nz = (ne = nets) + sizeof nets / sizeof nets[0]; ! 88: hz = (he = hosts) + sizeof hosts / sizeof hosts[0]; ! 89: ! 90: for (ap = arguments; *ap; ap++) { ! 91: if (**ap == '\01') { ! 92: #ifndef BIND ! 93: if (np = getnetbyname (*ap + 1)) { ! 94: sethostent (1); ! 95: while (hp = gethostent ()) ! 96: if (np -> n_addrtype == hp -> h_addrtype ! 97: && inet (hp, np -> n_net)) { ! 98: switch (sd = rcaux (sp, hp, rproto, response)) { ! 99: case NOTOK: ! 100: continue; ! 101: case OOPS1: ! 102: break; ! 103: case OOPS2: ! 104: return NOTOK; ! 105: ! 106: default: ! 107: return sd; ! 108: } ! 109: break; ! 110: } ! 111: } ! 112: #endif not BIND ! 113: continue; ! 114: } ! 115: ! 116: if (hp = gethostbyname (*ap)) { ! 117: switch (sd = rcaux (sp, hp, rproto, response)) { ! 118: case NOTOK: ! 119: case OOPS1: ! 120: break; ! 121: case OOPS2: ! 122: return NOTOK; ! 123: ! 124: default: ! 125: return sd; ! 126: } ! 127: continue; ! 128: } ! 129: } ! 130: ! 131: (void) strcpy (response, "no servers available"); ! 132: return NOTOK; ! 133: } ! 134: ! 135: /* */ ! 136: ! 137: static int ! 138: rcaux(sp, hp, rproto, response) ! 139: register struct servent *sp; ! 140: register struct hostent *hp; ! 141: int rproto; ! 142: register char *response; ! 143: { ! 144: int sd; ! 145: struct in_addr in; ! 146: register struct addrent *ap; ! 147: struct sockaddr_in in_socket; ! 148: register struct sockaddr_in *isock = &in_socket; ! 149: ! 150: for (ap = nets; ap < ne; ap++) ! 151: if (ap -> a_addrtype == hp -> h_addrtype && inet (hp, ap -> a_net)) ! 152: return NOTOK; ! 153: ! 154: for (ap = hosts; ap < he; ap++) ! 155: if (ap -> a_addrtype == hp -> h_addrtype ! 156: && bcmp (ap -> a_addr, hp -> h_addr, hp -> h_length) == 0) ! 157: return NOTOK; ! 158: ! 159: if ((sd = getport (rproto, hp -> h_addrtype, response)) == NOTOK) ! 160: return OOPS2; ! 161: ! 162: bzero ((char *) isock, sizeof *isock); ! 163: isock -> sin_family = hp -> h_addrtype; ! 164: isock -> sin_port = sp -> s_port; ! 165: bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length); ! 166: ! 167: if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) ! 168: switch (errno) { ! 169: case ENETDOWN: ! 170: case ENETUNREACH: ! 171: (void) close (sd); ! 172: if (ne < nz) { ! 173: ne -> a_addrtype = hp -> h_addrtype; ! 174: bcopy (hp -> h_addr, (char *) &in, sizeof in); ! 175: ne -> a_net = inet_netof (in); ! 176: ne++; ! 177: } ! 178: return OOPS1; ! 179: ! 180: case ETIMEDOUT: ! 181: case ECONNREFUSED: ! 182: default: ! 183: (void) close (sd); ! 184: if (he < hz) { ! 185: he -> a_addrtype = hp -> h_addrtype; ! 186: bcopy (hp -> h_addr, he -> a_addr, hp -> h_length); ! 187: he++; ! 188: } ! 189: return NOTOK; ! 190: } ! 191: ! 192: return sd; ! 193: } ! 194: ! 195: /* */ ! 196: ! 197: static int ! 198: getport(rproto, addrtype, response) ! 199: int rproto, addrtype; ! 200: register char *response; ! 201: { ! 202: int sd, ! 203: port; ! 204: struct sockaddr_in in_socket, ! 205: *isock = &in_socket; ! 206: ! 207: if (rproto && addrtype != AF_INET) { ! 208: (void) sprintf (response, "reserved ports not supported for af=%d", ! 209: addrtype); ! 210: errno = ENOPROTOOPT; ! 211: return NOTOK; ! 212: } ! 213: ! 214: if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) { ! 215: (void) sprintf (response, "unable to create socket: %s", ! 216: errno > 0 && errno < sys_nerr ? sys_errlist[errno] ! 217: : "unknown error"); ! 218: return NOTOK; ! 219: } ! 220: if (!rproto) ! 221: return sd; ! 222: ! 223: bzero ((char *) isock, sizeof *isock); ! 224: isock -> sin_family = addrtype; ! 225: for (port = IPPORT_RESERVED - 1;;) { ! 226: isock -> sin_port = htons ((u_short) port); ! 227: if (bind (sd, (struct sockaddr *) isock, sizeof *isock) != NOTOK) ! 228: return sd; ! 229: ! 230: switch (errno) { ! 231: case EADDRINUSE: ! 232: case EADDRNOTAVAIL: ! 233: if (--port <= IPPORT_RESERVED / 2) { ! 234: (void) strcpy (response, "ports available"); ! 235: return NOTOK; ! 236: } ! 237: break; ! 238: ! 239: default: ! 240: (void) sprintf (response, "unable to bind socket: %s", ! 241: errno > 0 && errno < sys_nerr ? sys_errlist[errno] ! 242: : "unknown error"); ! 243: return NOTOK; ! 244: } ! 245: } ! 246: } ! 247: ! 248: /* */ ! 249: ! 250: static int ! 251: inet(hp, net) ! 252: register struct hostent *hp; ! 253: int net; ! 254: { ! 255: struct in_addr in; ! 256: ! 257: bcopy (hp -> h_addr, (char *) &in, sizeof in); ! 258: return (inet_netof (in) == net); ! 259: } ! 260: ! 261: /* */ ! 262: ! 263: /* static copies of three MH subroutines... (sigh) */ ! 264: ! 265: char *malloc (); ! 266: ! 267: ! 268: static char *broken[MAXARGS + 1]; ! 269: ! 270: ! 271: static char ** ! 272: brkstring(strg, brksep, brkterm) ! 273: register char *strg, *brksep, *brkterm; ! 274: { ! 275: register int bi; ! 276: register char c, ! 277: *sp; ! 278: ! 279: sp = strg; ! 280: ! 281: for (bi = 0; bi < MAXARGS; bi++) { ! 282: while (brkany (c = *sp, brksep)) ! 283: *sp++ = 0; ! 284: if (!c || brkany (c, brkterm)) { ! 285: *sp = 0; ! 286: broken[bi] = 0; ! 287: return broken; ! 288: } ! 289: ! 290: broken[bi] = sp; ! 291: while ((c = *++sp) && !brkany (c, brksep) && !brkany (c, brkterm)) ! 292: continue; ! 293: } ! 294: broken[MAXARGS] = 0; ! 295: ! 296: return broken; ! 297: } ! 298: ! 299: ! 300: static int ! 301: brkany(chr, strg) ! 302: register char chr, *strg; ! 303: { ! 304: register char *sp; ! 305: ! 306: if (strg) ! 307: for (sp = strg; *sp; sp++) ! 308: if (chr == *sp) ! 309: return 1; ! 310: return 0; ! 311: } ! 312: ! 313: ! 314: static char ** ! 315: copyip(p, q) ! 316: register char **p, **q; ! 317: { ! 318: while (*p) ! 319: *q++ = *p++; ! 320: *q = 0; ! 321: ! 322: return q; ! 323: } ! 324: ! 325: ! 326: static char * ! 327: getcpy (str) ! 328: register char *str; ! 329: { ! 330: register char *cp; ! 331: ! 332: if ((cp = malloc ((unsigned) (strlen (str) + 1))) == NULL) ! 333: return NULL; ! 334: ! 335: (void) strcpy (cp, str); ! 336: return cp; ! 337: } ! 338: #endif BSD42
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.