Annotation of 43BSD/contrib/mh/zotnet/mts/client.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.