DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T a

⟦bf4c445b1⟧ TextFile

    Length: 4086 (0xff6)
    Types: TextFile
    Names: »addlink.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/pathalias/addlink.c« 

TextFile

/* 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);
}