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

unix.superglobalmegacorp.com

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