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

Defined functions

brkany defined in line 302; used 4 times
brkstring defined in line 272; used 3 times
client defined in line 58; never used
copyip defined in line 316; used 3 times
getcpy defined in line 328; used 4 times
getport defined in line 199; used 1 times
inet defined in line 252; used 2 times
rcaux defined in line 140; used 2 times

Defined variables

broken defined in line 269; used 5 times
he defined in line 50; used 6 times
hosts defined in line 51; used 4 times
hz defined in line 50; used 2 times
ne defined in line 47; used 6 times
nets defined in line 48; used 4 times
nz defined in line 47; used 2 times

Defined struct's

addrent defined in line 36; used 10 times

Defined macros

DONE defined in line 17; never used
FALSE defined in line 20; never used
MAXARGS defined in line 25; used 4 times
MAXHOSTS defined in line 27; used 1 times
  • in line 51
MAXNETS defined in line 26; used 1 times
  • in line 48
NOTOK defined in line 15; used 15 times
OK defined in line 16; never used
OOPS1 defined in line 22; used 1 times
OOPS2 defined in line 23; used 1 times
TRUE defined in line 19; never used
a_addr defined in line 44; used 2 times
a_net defined in line 43; used 2 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1778
Valid CSS Valid XHTML 1.0 Strict