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

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

unix.superglobalmegacorp.com

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