|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 4086 (0xff6)
Types: TextFile
Names: »addlink.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec8/pathalias/addlink.c«
/* pathalias -- by steve bellovin, as told to peter honeyman */
#ifndef lint
static char *sccsid = "@(#)addlink.c 8.4 (down!honey) 86/09/19";
#endif lint
#include "def.h"
/* exports */
extern link *addlink();
extern void deadlink(), atrace(), addgateway();
extern int tracelink();
char *Netchars = "!:@%"; /* sparse, but sufficient */
long Lcount; /* how many edges? */
/* imports */
extern link *newlink();
extern node *addnode();
extern int Tflag;
extern char *Netchars;
extern void yyerror(), die();
/* privates */
STATIC void netbits(), ltrace(), ltrprint();
static link *Trace[NTRACE];
static int Tracecount;
link *
addlink(from, to, cost, netchar, netdir)
node *from;
register node *to;
Cost cost;
char netchar, netdir;
{ register link *l, *prev = 0;
if (Tflag)
ltrace(from, to, cost, netchar, netdir);
/* maintain uniqueness for dead links (only) */
for (l = from->n_link; l && l->l_flag & LDEAD; l = l->l_next) {
if (to == l->l_to) {
/* what the hell, use cheaper cost */
if (cost < l->l_cost) {
l->l_cost = cost;
netbits(l, netchar, netdir);
}
return(l);
}
prev = l;
}
/* allocate and link in the new link struct */
l = newlink();
if (cost != INF) /* ignore back links */
Lcount++;
if (prev) {
l->l_next = prev->l_next;
prev->l_next = l;
} else {
l->l_next = from->n_link;
from->n_link = l;
}
l->l_to = to;
l->l_cost = cost + from->n_cost; /* add penalty */
if (netchar == 0) {
netchar = DEFNET;
netdir = DEFDIR;
}
netbits(l, netchar, netdir);
return(l);
}
void
addgateway(from, to, cost, netchar, netdir)
node *from, *to;
Cost cost;
char netchar, netdir;
{
addlink(from, to, cost, netchar, netdir)->l_flag |= LGATEWAY;
}
void
deadlink(s)
register char *s;
{ register char *t;
char c;
link *l;
t = index(s, '!');
if (t) {
c = *t;
*t = 0;
l = addlink(addnode(s), addnode(t + 1), INF / 2, c, DEFDIR);
l->l_flag |= LDEAD;
} else
addnode(s)->n_flag |= NDEAD;
}
STATIC void
netbits(l, netchar, netdir)
register link *l;
char netchar, netdir;
{ char *nptr;
if ((nptr = index(Netchars, netchar)) == 0)
die("unknown network operator -- impossible!");
l->l_flag &= ~(LNETCHARS|LDIR);
l->l_flag |= (nptr - Netchars) | dirbits(netdir);
}
int
tracelink(arg)
char *arg;
{ char *bang;
link *l;
if (Tracecount >= NTRACE)
return(-1);
l = newlink();
bang = index(arg, '!');
if (bang) {
*bang = 0;
l->l_to = addnode(bang+1);
} else
l->l_to = 0;
l->l_from = (link *) addnode(arg);
Trace[Tracecount++] = l;
return(0);
}
STATIC void
ltrace(from, to, cost, netchar, netdir)
node *from, *to;
Cost cost;
char netchar, netdir;
{ link *l;
int i;
for (i = 0; i < Tracecount; i++) {
l = Trace[i];
/* overkill, but you asked for it! */
if ((l->l_to == 0
&& (from == (node *) l->l_from || to == (node *) l->l_from))
|| (from == (node *) l->l_from && to == l->l_to)
|| (to == (node *) l->l_from && from == l->l_to)) {
ltrprint(from, to, cost, netchar, netdir);
return;
}
}
}
/* print a trace item */
STATIC void
ltrprint(from, to, cost, netchar, netdir)
node *from, *to;
Cost cost;
char netchar;
char netdir;
{ char buf[256], *bptr = buf;
strcpy(bptr, from->n_name);
bptr += strlen(bptr);
*bptr++ = ' ';
if (netdir == LRIGHT) /* @% */
*bptr++ = netchar;
strcpy(bptr, to->n_name);
bptr += strlen(bptr);
if (netdir == LLEFT) /* !: */
*bptr++ = netchar;
sprintf(bptr, "(%ld)", cost);
yyerror(buf);
}
void
atrace(n1, n2)
node *n1, *n2;
{ link *l;
int i;
char buf[256];
for (i = 0; i < Tracecount; i++) {
l = Trace[i];
if (l->l_to == 0 && ((node *) l->l_from == n1 || (node *) l->l_from == n2)) {
sprintf(buf, "%s = %s", n1->n_name, n2->n_name);
yyerror(buf);
return;
}
}
}
maptrace(from, to)
register node *from, *to;
{ register link *l;
register int i;
for (i = 0; i < Tracecount; i++) {
l = Trace[i];
if (l->l_to == 0) {
if (from == (node *) l->l_from
|| to == (node *) l->l_from)
return(1);
} else if (from == (node *) l->l_from && to == l->l_to)
return(1);
}
return(0);
}