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