Annotation of 43BSD/etc/htable/htable.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)htable.c   5.5 (Berkeley) 4/15/86";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * htable - convert NIC host table into a UNIX format.
        !            19:  * NIC format is described in RFC 810, 1 March 1982.
        !            20:  */
        !            21: #include <stdio.h>
        !            22: #include <ctype.h>
        !            23: #include <errno.h>
        !            24: #include <netdb.h>
        !            25: 
        !            26: #include "htable.h"            /* includes <sys/types.h> */
        !            27: 
        !            28: #include <sys/socket.h>
        !            29: #include <netinet/in.h>
        !            30: 
        !            31: #define        DATELINES       3       /* these lines usually contain the date */
        !            32: #define        MAXNETS         30      /* array size for local, connected nets */
        !            33: 
        !            34: FILE   *hf;                    /* hosts file */
        !            35: FILE   *gf;                    /* gateways file */
        !            36: FILE   *nf;                    /* networks file */
        !            37: struct gateway *savegateway(), *gatewayto();
        !            38: 
        !            39: int connected_nets[MAXNETS];
        !            40: int nconnected;
        !            41: int local_nets[MAXNETS];
        !            42: int nlocal;
        !            43: char *myname;
        !            44: 
        !            45: main(argc, argv)
        !            46:        int argc;
        !            47:        char *argv[];
        !            48: {
        !            49:        int errs;
        !            50: 
        !            51:        infile = "(stdin)";
        !            52:        myname = argv[0];
        !            53:        argc--;
        !            54:        argv++;
        !            55:        while (argc--) {
        !            56:                if (*argv[0] == '-') {
        !            57:                        switch (argv[0][1]) {
        !            58:                        case 'c':
        !            59:                                nconnected = addlocal(argv[1], connected_nets);
        !            60:                                argv++;
        !            61:                                argc--;
        !            62:                                break;
        !            63:                        case 'l':
        !            64:                                nlocal = addlocal(argv[1], local_nets);
        !            65:                                argv++;
        !            66:                                argc--;
        !            67:                                break;
        !            68:                        default:
        !            69:                                usage();
        !            70:                                /*NOTREACHED*/
        !            71:                        }
        !            72:                } else {
        !            73:                        infile = argv[0];
        !            74:                        if (freopen(infile, "r", stdin) == NULL) {
        !            75:                                perror(infile);
        !            76:                                exit(1);
        !            77:                        }
        !            78:                }
        !            79:                argv++;
        !            80:        }
        !            81:        hf = fopen("hosts", "w");
        !            82:        if (hf == NULL) {
        !            83:                perror("hosts");
        !            84:                exit(1);
        !            85:        }
        !            86:        copylocal(hf, "localhosts");
        !            87:        gf = fopen("gateways", "w");
        !            88:        if (gf == NULL) {
        !            89:                perror("gateways");
        !            90:                exit(1);
        !            91:        }
        !            92:        copygateways(gf, "localgateways");
        !            93:        nf = fopen("networks", "w");
        !            94:        if (nf == NULL) {
        !            95:                perror("networks");
        !            96:                exit(1);
        !            97:        }
        !            98:        copylocal(nf, "localnetworks");
        !            99:        copycomments(stdin, hf, DATELINES);
        !           100:        errs = yyparse();
        !           101:        dogateways();
        !           102:        exit(errs);
        !           103: }
        !           104: 
        !           105: usage()
        !           106: {
        !           107:        fprintf(stderr,
        !           108:        "usage: %s [ -c connected-nets ] [-l local-nets ] [ input-file ]\n",
        !           109:                myname);
        !           110:        exit(1);
        !           111: }
        !           112: 
        !           113: /*
        !           114:  *  Turn a comma-separated list of network names or numbers in dot notation
        !           115:  *  (e.g.  "arpanet, 128.32") into an array of net numbers.
        !           116:  */
        !           117: addlocal(arg, nets)
        !           118:        char *arg;
        !           119:        int *nets;
        !           120: {
        !           121:        register char *p, c;
        !           122:        register int nfound = 0;
        !           123: 
        !           124:        do {
        !           125:                p = arg;
        !           126:                while (*p && *p != ',' && !isspace(*p))
        !           127:                        p++;
        !           128:                c = *p;
        !           129:                *p = 0;
        !           130:                while (*arg && isspace(*arg))
        !           131:                        arg++;
        !           132:                if (*arg == 0)
        !           133:                        continue;
        !           134:                if (nfound == MAXNETS) {
        !           135:                        fprintf(stderr, "%s: Too many networks in list\n",
        !           136:                                myname);
        !           137:                        return (nfound);
        !           138:                }
        !           139:                if (getnetaddr(arg, &nets[nfound]))
        !           140:                        nfound++;
        !           141:                else {
        !           142:                        fprintf(stderr, "%s: %s: unknown network\n",
        !           143:                                myname, arg);
        !           144:                        exit(1);
        !           145:                }
        !           146:                arg = p + 1;
        !           147:        } while (c);
        !           148:        return (nfound);
        !           149: }
        !           150: 
        !           151: struct name *
        !           152: newname(str)
        !           153:        char *str;
        !           154: {
        !           155:        char *p;
        !           156:        struct name *nm;
        !           157: 
        !           158:        p = malloc(strlen(str) + 1);
        !           159:        strcpy(p, str);
        !           160:        nm = (struct name *)malloc(sizeof (struct name));
        !           161:        nm->name_val = p;
        !           162:        nm->name_link = NONAME;
        !           163:        return (nm);
        !           164: }
        !           165: 
        !           166: char *
        !           167: lower(str)
        !           168:        char *str;
        !           169: {
        !           170:        register char *cp = str;
        !           171: 
        !           172:        while (*cp) {
        !           173:                if (isupper(*cp))
        !           174:                        *cp = tolower(*cp);
        !           175:                cp++;
        !           176:        }
        !           177:        return (str);
        !           178: }
        !           179: 
        !           180: do_entry(keyword, addrlist, namelist, cputype, opsys, protos)
        !           181:        int keyword;
        !           182:        struct addr *addrlist;
        !           183:        struct name *namelist, *cputype, *opsys, *protos;
        !           184: {
        !           185:        register struct addr *al, *al2;
        !           186:        register struct name *nl;
        !           187:        struct addr *connect_addr;
        !           188:        char *cp;
        !           189: 
        !           190:        switch (keyword) {
        !           191: 
        !           192:        case KW_NET:
        !           193:                nl = namelist;
        !           194:                if (nl == NONAME) {
        !           195:                        fprintf(stderr, "htable: net");
        !           196:                        putnet(stderr, inet_netof(addrlist->addr_val));
        !           197:                        fprintf(stderr, " missing names.\n");
        !           198:                        break;
        !           199:                }
        !           200:                fprintf(nf, "%-16.16s", lower(nl->name_val));
        !           201:                al2 = addrlist;
        !           202:                while (al = al2) {
        !           203:                        char *cp;
        !           204: 
        !           205:                        putnet(nf, inet_netof(al->addr_val));
        !           206:                        cp = "\t%s";
        !           207:                        while (nl = nl->name_link) {
        !           208:                                fprintf(nf, cp, lower(nl->name_val));
        !           209:                                cp = " %s";
        !           210:                        }
        !           211:                        putc('\n', nf);
        !           212:                        al2 = al->addr_link;
        !           213:                        free((char *)al);
        !           214:                }
        !           215:                break;
        !           216: 
        !           217:        case KW_GATEWAY:
        !           218:                /* locate locally connected address, if one */
        !           219:                for (al = addrlist; al; al = al->addr_link)
        !           220:                        if (connectedto(inet_netof(al->addr_val)))
        !           221:                                break;
        !           222:                if (al == NULL) {
        !           223:                        /*
        !           224:                         * Not connected to known networks.  Save for later.
        !           225:                         */
        !           226:                        struct gateway *gw, *firstgw = (struct gateway *) NULL;
        !           227: 
        !           228:                        for (al = addrlist; al; al = al->addr_link) {
        !           229:                                register int net;
        !           230: 
        !           231:                                net = inet_netof(al->addr_val);
        !           232:                                gw = savegateway(namelist, net,
        !           233:                                    al->addr_val, 0);
        !           234:                                if (firstgw == (struct gateway *) NULL)
        !           235:                                        firstgw = gw;
        !           236:                                gw->g_firstent = firstgw;
        !           237:                        }
        !           238:                        freeaddrs(addrlist);
        !           239:                        goto dontfree;
        !           240:                }
        !           241:                /*
        !           242:                 * Connected to a known network.
        !           243:                 * Mark this as the gateway to all other networks
        !           244:                 * that are on the addrlist (unless we already have
        !           245:                 * gateways to them).
        !           246:                 */
        !           247:                connect_addr = al;
        !           248:                for (al = addrlist; al; al = al->addr_link) {
        !           249:                        register int net;
        !           250: 
        !           251:                        /* suppress duplicates -- not optimal */
        !           252:                        net = inet_netof(al->addr_val);
        !           253:                        if (connectedto(net) || gatewayto(net))
        !           254:                                continue;
        !           255:                        printgateway(net, namelist->name_val, 1);
        !           256:                        (void) savegateway(namelist, net, al->addr_val, 1);
        !           257:                }
        !           258:                /*
        !           259:                 * Put the gateway in the hosts file.
        !           260:                 */
        !           261:                putaddr(hf, connect_addr->addr_val);
        !           262:                cp = "%s";
        !           263:                for (nl = namelist; nl; nl = nl->name_link) {
        !           264:                        fprintf(hf, cp, lower(nl->name_val));
        !           265:                        cp = " %s";
        !           266:                }
        !           267:                fprintf(hf, "\t# gateway\n");
        !           268:                freeaddrs(addrlist);
        !           269:                goto dontfree;
        !           270: 
        !           271:        case KW_HOST:
        !           272:                al2 = addrlist;
        !           273:                while (al = al2) {
        !           274:                        if (!local(inet_netof(al->addr_val))) {
        !           275:                                char *cp;
        !           276: 
        !           277:                                putaddr(hf, al->addr_val);
        !           278:                                cp = "%s";
        !           279:                                for (nl = namelist; nl; nl = nl->name_link) {
        !           280:                                        fprintf(hf, cp, lower(nl->name_val));
        !           281:                                        cp = " %s";
        !           282:                                }
        !           283:                                putc('\n', hf);
        !           284:                        }
        !           285:                        al2 = al->addr_link;
        !           286:                        free((char *)al);
        !           287:                }
        !           288:                break;
        !           289: 
        !           290:        default:
        !           291:                fprintf(stderr, "Unknown keyword: %d.\n", keyword);
        !           292:        }
        !           293:        freenames(namelist);
        !           294: dontfree:
        !           295:        freenames(protos);
        !           296: }
        !           297: 
        !           298: printgateway(net, name, metric)
        !           299:        int net;
        !           300:        char *name;
        !           301:        int metric;
        !           302: {
        !           303:        struct netent *np;
        !           304: 
        !           305:        fprintf(gf, "net ");
        !           306:        np = getnetbyaddr(net, AF_INET);
        !           307:        if (np)
        !           308:                fprintf(gf, "%s", np->n_name);
        !           309:        else
        !           310:                putnet(gf, net);
        !           311:        fprintf(gf, " gateway %s metric %d passive\n",
        !           312:                lower(name), metric);
        !           313: }
        !           314: 
        !           315: copylocal(f, filename)
        !           316:        FILE *f;
        !           317:        char *filename;
        !           318: {
        !           319:        register FILE *lhf;
        !           320:        register cc;
        !           321:        char buf[BUFSIZ];
        !           322:        extern int errno;
        !           323: 
        !           324:        lhf = fopen(filename, "r");
        !           325:        if (lhf == NULL) {
        !           326:                if (errno != ENOENT) {
        !           327:                        perror(filename);
        !           328:                        exit(1);
        !           329:                }
        !           330:                fprintf(stderr, "Warning, no %s file.\n", filename);
        !           331:                return;
        !           332:        }
        !           333:        while (cc = fread(buf, 1, sizeof(buf), lhf))
        !           334:                fwrite(buf, 1, cc, f);
        !           335:        fclose(lhf);
        !           336: }
        !           337: 
        !           338: copygateways(f, filename)
        !           339:        FILE *f;
        !           340:        char *filename;
        !           341: {
        !           342:        register FILE *lhf;
        !           343:        struct name *nl;
        !           344:        char type[80];
        !           345:        char dname[80];
        !           346:        char gname[80];
        !           347:        char junk[80];
        !           348:        char buf[500];
        !           349:        u_long addr;
        !           350:        int net, metric;
        !           351:        extern int errno;
        !           352: 
        !           353:        lhf = fopen(filename, "r");
        !           354:        if (lhf == NULL) {
        !           355:                if (errno != ENOENT) {
        !           356:                        perror(filename);
        !           357:                        exit(1);
        !           358:                }
        !           359:                fprintf(stderr, "Warning, no %s file.\n", filename);
        !           360:                return;
        !           361:        }
        !           362:        /* format: {net | host} XX gateway XX metric DD [passive]\n */
        !           363:        for (;;) {
        !           364:                junk[0] = 0;
        !           365:                if (fgets(buf, sizeof(buf), lhf) == (char *)NULL)
        !           366:                        break;
        !           367:                fputs(buf, gf);
        !           368:                if (buf[0] == '#' ||
        !           369:                    sscanf(buf, "%s %s gateway %s metric %d %s",
        !           370:                    type, dname, gname, &metric, junk) < 5)
        !           371:                        continue;
        !           372:                if (strcmp(type, "net"))
        !           373:                        continue;
        !           374:                if (!getnetaddr(dname, &net))
        !           375:                        continue;
        !           376:                if (!gethostaddr(gname, &addr))
        !           377:                        continue;
        !           378:                nl = newname(gname);
        !           379:                (void) savegateway(nl, net, addr, metric);
        !           380:        }
        !           381:        fclose(lhf);
        !           382: }
        !           383: 
        !           384: getnetaddr(name, addr)
        !           385:        char *name;
        !           386:        int *addr;
        !           387: {
        !           388:        struct netent *np = getnetbyname(name);
        !           389:        int n;
        !           390: 
        !           391:        if (np == 0) {
        !           392:                *addr = inet_network(name);
        !           393:                return (*addr != -1);
        !           394:        } else {
        !           395:                if (np->n_addrtype != AF_INET)
        !           396:                        return (0);
        !           397:                *addr = np->n_net;
        !           398:                return (1);
        !           399:        }
        !           400: }
        !           401: 
        !           402: gethostaddr(name, addr)
        !           403:        char *name;
        !           404:        u_long *addr;
        !           405: {
        !           406:        struct hostent *hp;
        !           407: 
        !           408:        hp = gethostbyname(name);
        !           409:        if (hp) {
        !           410:                *addr = *(u_long *)(hp->h_addr);
        !           411:                return (1);
        !           412:        }
        !           413:        *addr = inet_addr(name);
        !           414:        return (*addr != -1);
        !           415: }
        !           416: 
        !           417: copycomments(in, out, ccount)
        !           418:        FILE *in, *out;
        !           419:        int ccount;
        !           420: {
        !           421:        char buf[BUFSIZ];
        !           422:        int length;
        !           423:        int count;
        !           424:        char *fgets();
        !           425: 
        !           426:        for (count=0; count < ccount; count++) {
        !           427:                if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';'))
        !           428:                        return;
        !           429:                buf[0] = '#';
        !           430:                fputs(buf, out);
        !           431:        }
        !           432:        return;
        !           433: }
        !           434: #define        UC(b)   (((int)(b))&0xff)
        !           435: 
        !           436: /*
        !           437:  * Print network number in internet-standard dot notation;
        !           438:  * v is in host byte order.
        !           439:  */
        !           440: putnet(f, v)
        !           441:        FILE *f;
        !           442:        register int v;
        !           443: {
        !           444:        if (v < 128)
        !           445:                fprintf(f, "%d", v);
        !           446:        else if (v < 65536)
        !           447:                fprintf(f, "%d.%d", UC(v >> 8), UC(v));
        !           448:        else
        !           449:                fprintf(f, "%d.%d.%d", UC(v >> 16), UC(v >> 8), UC(v));
        !           450: }
        !           451: 
        !           452: putaddr(f, v)
        !           453:        FILE *f;
        !           454:        u_long v;
        !           455: {
        !           456:        register char *a = (char *)&v;
        !           457:        char buf[32];
        !           458: 
        !           459:        sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]));
        !           460:        fprintf(f, "%-16.16s", buf);
        !           461: }
        !           462: 
        !           463: freenames(list)
        !           464:        struct name *list;
        !           465: {
        !           466:        register struct name *nl, *nl2;
        !           467: 
        !           468:        nl2 = list;
        !           469:        while (nl = nl2) {
        !           470:                nl2 = nl->name_link;
        !           471:                free(nl->name_val);
        !           472:                free((char *)nl);
        !           473:        }
        !           474: }
        !           475: 
        !           476: freeaddrs(list)
        !           477:        struct addr *list;
        !           478: {
        !           479:        register struct addr *al, *al2;
        !           480: 
        !           481:        al2 = list;
        !           482:        while (al = al2)
        !           483:                al2 = al->addr_link, free((char *)al);
        !           484: }
        !           485: 
        !           486: struct gateway *gateways = 0;
        !           487: struct gateway *lastgateway = 0;
        !           488: 
        !           489: struct gateway *
        !           490: gatewayto(net)
        !           491:        register int net;
        !           492: {
        !           493:        register struct gateway *gp;
        !           494: 
        !           495:        for (gp = gateways; gp; gp = gp->g_link)
        !           496:                if ((gp->g_net == net) && (gp->g_metric > 0))
        !           497:                        return (gp);
        !           498:        return ((struct gateway *) NULL);
        !           499: }
        !           500: 
        !           501: struct gateway *
        !           502: savegateway(namelist, net, addr, metric)
        !           503:        struct name *namelist;
        !           504:        u_long addr;
        !           505:        int net, metric;
        !           506: {
        !           507:        register struct gateway *gp;
        !           508: 
        !           509:        gp = (struct gateway *)malloc(sizeof (struct gateway));
        !           510:        if (gp == 0) {
        !           511:                fprintf(stderr, "htable: out of memory\n");
        !           512:                exit(1);
        !           513:        }
        !           514:        gp->g_link = (struct gateway *) NULL;
        !           515:        if (lastgateway)
        !           516:                lastgateway->g_link = gp;
        !           517:        else
        !           518:                gateways = gp;
        !           519:        lastgateway = gp;
        !           520:        gp->g_name = namelist;
        !           521:        gp->g_net = net;
        !           522:        gp->g_addr = addr;
        !           523:        gp->g_metric = metric;
        !           524:        if (metric == 1)
        !           525:                gp->g_dst = gp;
        !           526:        return (gp);
        !           527: }
        !           528: 
        !           529: connectedto(net)
        !           530:        u_long net;
        !           531: {
        !           532:        register i;
        !           533: 
        !           534:        for (i = 0; i < nconnected; i++)
        !           535:                if (connected_nets[i] == net)
        !           536:                        return(1);
        !           537:        return(0);
        !           538: }
        !           539: 
        !           540: local(net)
        !           541:        u_long net;
        !           542: {
        !           543:        register i;
        !           544: 
        !           545:        for (i = 0; i < nlocal; i++)
        !           546:                if (local_nets[i] == net)
        !           547:                        return(1);
        !           548:        return(0);
        !           549: }
        !           550: 
        !           551: #define        MAXHOPS 10
        !           552: 
        !           553: /*
        !           554:  * Go through list of gateways, finding connections for gateways
        !           555:  * that are not yet connected.
        !           556:  */
        !           557: dogateways()
        !           558: {
        !           559:        register struct gateway *gp, *gw, *ggp;
        !           560:        register int hops, changed = 1;
        !           561:        struct name *nl;
        !           562:        char *cp;
        !           563: 
        !           564:        for (hops = 0; hops < MAXHOPS && changed; hops++, changed = 0) {
        !           565:            for (gp = gateways; gp; gp = gp->g_link)
        !           566:                if ((gp->g_metric == 0) && (gw = gatewayto(gp->g_net))) {
        !           567:                    /*
        !           568:                     * Found a new connection.
        !           569:                     * For each other network that this gateway is on,
        !           570:                     * add a new gateway to that network.
        !           571:                     */
        !           572:                    changed = 1;
        !           573:                    gp->g_dst = gw->g_dst;
        !           574:                    gp->g_metric = gw->g_metric + 1;
        !           575:                    for (ggp = gp->g_firstent; ggp->g_name == gp->g_name;
        !           576:                        ggp = ggp->g_link) {
        !           577:                            if (ggp == gp)
        !           578:                                continue;
        !           579:                            if (gatewayto(ggp->g_net))
        !           580:                                continue;
        !           581:                            ggp->g_dst = gp->g_dst;
        !           582:                            ggp->g_metric = gp->g_metric;
        !           583:                            printgateway(ggp->g_net,
        !           584:                                    gw->g_dst->g_name->name_val, gp->g_metric);
        !           585:                    }
        !           586:                    /*
        !           587:                     * Put the gateway in the hosts file,
        !           588:                     * using the address for the connected net.
        !           589:                     */
        !           590:                    putaddr(hf, gp->g_addr);
        !           591:                    cp = "%s";
        !           592:                    for (nl = gp->g_name; nl; nl = nl->name_link) {
        !           593:                            fprintf(hf, cp, lower(nl->name_val));
        !           594:                            cp = " %s";
        !           595:                    }
        !           596:                    fprintf(hf, "\t# gateway\n");
        !           597:                }
        !           598:        }
        !           599: }

unix.superglobalmegacorp.com

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