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: }

Defined functions

dfs defined in line 125; used 2 times
dumpgraph defined in line 34; used 1 times
dumpnode defined in line 60; used 1 times
  • in line 56
height defined in line 248; used 2 times
  • in line 206(2)
pack defined in line 10; used 3 times
showlinks defined in line 147; used 1 times
tiebreaker defined in line 181; used 2 times
untangle defined in line 112; used 1 times
  • in line 44

Defined variables

FILE defined in line 32; never used
Gstream defined in line 32; used 9 times
sccsid defined in line 3; never used

Defined macros

NEWP defined in line 179; used 5 times
OLDP defined in line 180; used 5 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1516
Valid CSS Valid XHTML 1.0 Strict