Annotation of 43BSD/contrib/mh/zotnet/mts/client.c, revision 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.