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

unix.superglobalmegacorp.com

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