Annotation of 43BSD/contrib/pathalias/mapaux.c, revision 1.1

1.1     ! root        1: /* pathalias -- by steve bellovin, as told to peter honeyman */
        !             2: #ifndef lint
        !             3: static char    *sccsid = "@(#)mapaux.c 8.2 (down!honey) 86/01/26";
        !             4: #endif lint
        !             5: 
        !             6: #include "def.h"
        !             7: 
        !             8: void   pack();
        !             9: 
        !            10: void
        !            11: pack()
        !            12: {
        !            13:        long    hole, next;
        !            14: 
        !            15:        /* find first "hole " */
        !            16:        for (hole = Tabsize - 1; hole >= 0 && Table[hole] != 0; --hole)
        !            17:                ;
        !            18: 
        !            19:        /* repeatedly move next filled entry into last hole */
        !            20:        for (next = hole - 1; next >= 0; --next) {
        !            21:                if (Table[next] != 0) {
        !            22:                        Table[hole] = Table[next];
        !            23:                        Table[hole]->n_tloc = hole;
        !            24:                        Table[next] = 0;
        !            25:                        while (Table[--hole] != 0)      /* find next hole */
        !            26:                                ;
        !            27:                }
        !            28:        }
        !            29:        Hashpart = hole + 1;
        !            30: }
        !            31: 
        !            32: FILE   *Gstream;
        !            33: 
        !            34: dumpgraph()
        !            35: {
        !            36:        long    i;
        !            37:        node    *n;
        !            38: 
        !            39:        if ((Gstream = fopen(Graphout, "w")) == NULL) {
        !            40:                fprintf(stderr, "%s: ", ProgName);
        !            41:                perror(Graphout);
        !            42:        }
        !            43: 
        !            44:        untangle();     /* untangle net cycles for proper output */
        !            45: 
        !            46:        for (i = Hashpart; i < Tabsize; i++) {
        !            47:                n = Table[i];
        !            48:                if (n == 0)
        !            49:                        continue;       /* impossible, but ... */
        !            50:                /* a minor optimization ... */
        !            51:                if (n->n_link == 0)
        !            52:                        continue;
        !            53:                /* pathparse doesn't need these */
        !            54:                if (n->n_flag & NNET)
        !            55:                        continue;
        !            56:                dumpnode(n);
        !            57:        }
        !            58: }
        !            59: 
        !            60: dumpnode(from)
        !            61: node   *from;
        !            62: {
        !            63:        node    *to;
        !            64:        link    *l;
        !            65:        char    netbuf[BUFSIZ], *nptr = netbuf;
        !            66: 
        !            67:        for (l = from->n_link ; l; l = l->l_next) {
        !            68:                to = l->l_to;
        !            69:                if (from == to)
        !            70:                        continue;       /* oops -- it's me! */
        !            71: 
        !            72:                if ((to->n_flag & NNET) == 0) {
        !            73:                        /* host -> host -- print host>host */
        !            74:                        if (l->l_cost == INF)
        !            75:                                continue;       /* phoney link */
        !            76:                        fputs(from->n_name, Gstream);
        !            77:                        putc('>', Gstream);
        !            78:                        fputs(to->n_name, Gstream);
        !            79:                        putc('\n', Gstream);
        !            80:                } else {
        !            81:                        /* host -> net -- just cache it for now */
        !            82:                        while (to->n_root && to != to->n_root)
        !            83:                                to = to->n_root;
        !            84:                        *nptr++ = ',';
        !            85:                        strcpy(nptr, to->n_name);
        !            86:                        nptr += strlen(nptr);
        !            87:                }
        !            88:        }
        !            89: 
        !            90:        /* dump nets */
        !            91:        if (nptr != netbuf) {
        !            92:                /* nets -- print host@\tnet,net, ... */
        !            93:                *nptr = 0;
        !            94:                fputs(from->n_name, Gstream);
        !            95:                putc('@', Gstream);
        !            96:                *netbuf = '\t'; /* insert tab by killing initial ',' */
        !            97:                fputs(netbuf, Gstream); /* skip initial ',' */
        !            98:                putc('\n', Gstream);
        !            99:        }
        !           100: }
        !           101: 
        !           102: /*
        !           103:  * remove cycles in net definitions. 
        !           104:  *
        !           105:  * depth-first search
        !           106:  *
        !           107:  * for each net, run dfs on its neighbors (nets only).  if we return to
        !           108:  * a visited node, that's a net cycle.  mark the cycle with a pointer
        !           109:  * in the n_root field (which gets us closer to the root of this
        !           110:  * portion of the dfs tree).
        !           111:  */
        !           112: untangle()
        !           113: {
        !           114:        long    i;
        !           115:        node    *n;
        !           116: 
        !           117:        for (i = Hashpart; i < Tabsize; i++) {
        !           118:                n = Table[i];
        !           119:                if (n == 0 || (n->n_flag & NNET) == 0 || n->n_root)
        !           120:                        continue;
        !           121:                dfs(n);
        !           122:        }
        !           123: }
        !           124: 
        !           125: dfs(n)
        !           126: node   *n;
        !           127: {
        !           128:        link    *l;
        !           129:        node    *next;
        !           130: 
        !           131:        n->n_flag |= INDFS;
        !           132:        n->n_root = n;
        !           133:        for (l = n->n_link; l; l = l->l_next) {
        !           134:                next = l->l_to;
        !           135:                if ((next->n_flag & NNET) == 0)
        !           136:                        continue;
        !           137:                if ((next->n_flag & INDFS) == 0) {
        !           138:                        dfs(next);
        !           139:                        if (next->n_root != next)
        !           140:                                n->n_root = next->n_root;
        !           141:                } else
        !           142:                        n->n_root = next->n_root;
        !           143:        }
        !           144:        n->n_flag &= ~INDFS;
        !           145: }
        !           146: 
        !           147: showlinks() 
        !           148: {
        !           149:        link    *l;
        !           150:        node    *n;
        !           151:        long    i;
        !           152:        FILE    *estream;
        !           153: 
        !           154:        if ((estream = fopen(Linkout, "w")) == 0)
        !           155:                return;
        !           156: 
        !           157:        for (i = Hashpart; i < Tabsize; i++) {
        !           158:                n = Table[i];
        !           159:                if (n == 0)     /* impossible, but ... */
        !           160:                        continue;
        !           161:                if (l = n->n_link) {
        !           162:                        fprintf(estream, "%s\t%s(%d)", n->n_name,
        !           163:                                l->l_to->n_name,
        !           164:                                l->l_cost ? l->l_cost : DEFCOST);
        !           165:                        for (l = l->l_next; l; l = l->l_next)
        !           166:                                fprintf(estream, ",\n\t%s(%d)", l->l_to->n_name,
        !           167:                                        l->l_cost ? l->l_cost : DEFCOST);
        !           168:                        fputc('\n', estream);
        !           169:                }
        !           170:        }
        !           171:        (void) fclose(estream);
        !           172: }
        !           173: 
        !           174: /*
        !           175:  * n is node in heap, newp is candidate for new parent.
        !           176:  * choose between newp and n->n_parent for parent.
        !           177:  * return 0 to use newp, non-zero o.w.
        !           178:  */
        !           179: #define NEWP 0
        !           180: #define OLDP 1
        !           181: tiebreaker(n, newp)
        !           182: node   *n, *newp;
        !           183: {
        !           184:        register char   *opname, *npname, *name;
        !           185:        node    *oldp;
        !           186:        int     metric;
        !           187: 
        !           188:        oldp = n->n_parent;
        !           189: 
        !           190:        /*
        !           191:         * given the choice, avoid gatewayed nets,
        !           192:         * thereby placating the FCC or some such.
        !           193:         */
        !           194:        if (GATEWAYED(newp) && !GATEWAYED(oldp))
        !           195:                return(OLDP);
        !           196:        if (!GATEWAYED(newp) && GATEWAYED(oldp))
        !           197:                return(NEWP);
        !           198: 
        !           199:        /* look at real parents, not nets */
        !           200:        while (oldp->n_flag & NNET)
        !           201:                oldp = oldp->n_parent;
        !           202:        while (newp->n_flag & NNET)
        !           203:                newp = newp->n_parent;
        !           204: 
        !           205:        /* use fewer hops, if possible */
        !           206:        metric = height(oldp) - height(newp);
        !           207:        if (metric < 0)
        !           208:                return(OLDP);
        !           209:        if (metric > 0)
        !           210:                return(NEWP);
        !           211: 
        !           212:        /* compare names */
        !           213:        opname = oldp->n_name;
        !           214:        npname = newp->n_name;
        !           215:        name = n->n_name;
        !           216: 
        !           217:        /* find point of departure */
        !           218:        while (*opname == *npname && *npname == *name) {
        !           219:                if (*name == 0) {
        !           220:                        fprintf(stderr, "%s: error in tie breaker\n", ProgName);
        !           221:                        badmagic(1);
        !           222:                }
        !           223:                opname++;
        !           224:                npname++;
        !           225:                name++;
        !           226:        }
        !           227: 
        !           228:        /* use longest match, if appl. */
        !           229:        if (*opname == *name || *opname == 0)
        !           230:                return(OLDP);
        !           231:        if (*npname == *name || *npname == 0)
        !           232:                return(NEWP);
        !           233: 
        !           234:        /* use shorter host name, if appl. */
        !           235:        metric = strlen(opname) - strlen(npname);
        !           236:        if (metric < 0)
        !           237:                return(OLDP);
        !           238:        if (metric > 0)
        !           239:                return(NEWP);
        !           240: 
        !           241:        /* use larger lexicographically (no reason) */
        !           242:        metric = strcmp(opname, npname);
        !           243:        if (metric < 0)
        !           244:                return(NEWP);
        !           245:        return(OLDP);
        !           246: }
        !           247: 
        !           248: height(n)
        !           249: register node  *n;
        !           250: {
        !           251:        register int i = 0;
        !           252: 
        !           253:        while ((n = n->n_parent) != 0)
        !           254:                if ((n->n_flag & NNET) == 0)
        !           255:                        i++;    /* should count domains too ... */
        !           256:        return(i);
        !           257: }

unix.superglobalmegacorp.com

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