[net.sources] yet another path-finding program

oscar@utcsrgv.UUCP (Oscar M. Nierstrasz) (12/18/83)

:	path.c, abridged mail database, and support programs

#	Here is another mail(1) path-finding program.
#	It is not as sophisticated as Steve Bellovin's pathalias
#	program (it uses # of hops as the only cost data)
#	but it works tolerably well.
#	The complete mail connection database is monstrously huge
#	so I have included a subgraph of just main USENET sites
#	(only 500 vs 2000 sites).
#	To use the system you must generate a "pathfile" from
#	the enclosed graph.  (Just follow the instructions in
#	the various README files). Once this is done you can throw
#	away (or store offline) everything but "path" and "pathfile".

#	The only changes you must make are:

#	1. tell src/path.c where you will keep your "pathfile"
#	2. tell map/makefile what your site is called

#	If your site isn't in the database you must add it.

echo README
sed 's/^	//' > README << 'Rosebud'
	This directory contains the pathfile used by path(1).
	See the documentation in the doc directory and in 
	the file map/README.
	
	Installation requires modifications to src/path.c and map/makefile
	to suit your site.  Makefiles in both directories will do the rest
	of the work for you.
	------------------------- FILES -------------------------
	doc...............directory of manual pages
	map...............directory of site connections
	msg...............a mail message
	pathfile..........the pathname database
	src...............directory containing source code
Rosebud
echo doc/
mkdir doc
echo doc/makefile
sed 's/^	//' > doc/makefile << 'Rosebud'
	
	DOC = path span unpath
	
	MAN =	nroff -man $@.? | col > $@
	
	all :	$(DOC)
		cat $(DOC) > all
	
	clean :
		rm -f $(DOC)
	
	path :	path.1
		$(MAN)
	
	span :	span.1
		$(MAN)
	
	unpath : unpath.1
		$(MAN)
Rosebud
echo doc/path.1
sed 's/^	//' > doc/path.1 << 'Rosebud'
	.TH PATH 1
	.UC
	.SH NAME
	path \- pathname generation
	.SH SYNOPSIS
	.B path 
	<site> ...  [ -l | -f pathfile ]
	.br
	.B path 
	-a [ -f pathfile ]
	.br
	.B path 
	-p [ -f pathfile ]
	.SH DESCRIPTION
	.I Path
	produces a list of pathnames to a set of sites for sending mail(1)
	to users at distant locations.
	For example:
	.IP
	path ucbvax
	.PP
	yields:
	.IP
	allegra!ucbvax
	.br
	decvax!ucbvax
	.br
	decwrl!ucbvax
	.br
	floyd!ucbvax
	.br
	ihnp4!ucbvax
	.PP
	.I Path
	expects to find a pathfile
	containing a map of site-to-site connections in the form of a tree
	with the host machine as the root of the tree.
	A default pathfile is used if none is specified.
	A longer pathfile with more sites in it will be used if the "-l"
	flag is specified.
	The format of the pathfile is:
	.IP
	.I pathfile
	::=
	.I branch ...
	.IP
	.I branch
	::=
	.I site
	[ "{"
	.I branch ...
	"}" ]
	.PP
	For example:
	.IP
	utzoo {
	.in +4
	decvax
	.br
	}
	.in -4
	ihnp4 {
	.in +4
	eagle {
	.in +4
	mit-vax
	.br
	}
	.in -4
	tektronix
	.br
	}
	.in -4
	.PP
	might be a pathfile for the host
	.I utcsrgv.
	(The amount of white space separating site names is irrelevant.
	Tabbing is included here for readability only.)
	.IP
	path mit-vax
	.PP
	would yield:
	.IP
	ihnp4!eagle!mit-vax
	.IP
	path -a
	.PP
	yields a list of all pathnames to all sites.
	.IP
	path -p
	.PP
	"pretty-prints" the pathfile as in the example given above.
	.PP
	The pathfile needn't be a true tree and may contain 
	duplicated nodes for the purpose of yielding alternative pathnames.
	.PP
	.I Path 
	will complain if it couldn't find any of the sites asked for.
	If you do not know the precise name of the site you wish to
	mail to, you may use
	.IP
	path -a | grep <pattern>
	.PP
	to find the pathname.
	.PP
	A
	.I pathfile 
	for an arbitrary host may be generated automatically
	from a file describing the entire graph of site-to-site connections
	by using span(1).
	.SH AUTHOR
	Oscar Nierstrasz at the University of Toronto.
	.SH BUGS
	Pathnames are arbitrarily limited to 30 sites and 300 characters in length
	(more than adequate).
	The pathfile generated by span(1) includes "shortest" paths only.
	"Longer" paths that may be faster, cheaper or more reliable are not listed.
	.I Path
	does not tell you which of the alternatives it gives you is the "best".
	.SH FILES
	/usr/pub/pathfile
	/usr/pub/longpf
	.SH SEE ALSO
	span(1), unpath(1), mail(1).
Rosebud
echo doc/span.1
sed 's/^	//' > doc/span.1 << 'Rosebud'
	.TH SPAN 1
	.UC
	.SH NAME
	span \- pathfile generation
	.SH SYNOPSIS
	.B span 
	<host site> <graphfile> [ <pathfile> ] [-a] [-c] [-p] [-t]
	.SH DESCRIPTION
	.I Span
	is program for generating a spanning tree of a graph of
	site-to site connections, given the host site to use as
	the root of the tree.
	It uses a breadth-first search to generate a tree with a
	shortest path to all reachable sites.
	The output of
	.I span
	is suitable for use as the
	.I pathfile
	required by path(1) to generate mail(1) pathnames to sites.
	.I Span
	generates a single tree, though this tree is, of course,
	not necessarily unique.
	The "-c" option supresses leading tabs and blanks in the output,
	producing a more compact pathfile.
	.PP
	The
	.I graphfile
	is stored as a
	.I sorted
	sequence of adjacency lists:
	.IP
	.I graph
	::=
	.I adj-list ...
	.IP
	.I adj-list
	::=
	.I site
	[ '{'
	.I site ...
	'}' ]
	.PP
	For example, if
	.IP
	decvax { tektronix }
	.br
	eagle { mit-vax }
	.br
	ihnp4 { decvax eagle tektronix utcsrgv utzoo }
	.br
	mit-vax { eagle }
	.br
	tektronix { decvax }
	.br
	utcsrgv { utzoo ihnp4 }
	.br
	utzoo { utcsrgv decvax ihnp4 }
	.PP
	were the contents of
	.I graphfile,
	then
	.IP
	span utcsrgv graphfile
	.PP
	would generate the tree:
	.IP
	utzoo {
	.in +4
	decvax
	.br
	}
	.in -4
	ihnp4 {
	.in +4
	eagle {
	.in +4
	mit-vax
	.br
	}
	.in -4
	tektronix
	.br
	}
	.in -4
	.PP
	White space may appear anywhere in the
	.I graphfile,
	but since the file must be sorted according to host name,
	it makes sense to put each adjacency list on a single line 
	so that the file may be piped through sort(1).
	(The names within the braces may appear in any order.)
	.IP
	span host graphfile -p
	.PP
	will 'pretty-print' the graphfile with any bad entries deleted
	(see below).
	.IP
	span host graphfile -t
	.PP
	will turn the
	.I trace
	mode on.
	This causes
	.I span
	to generate diagnostic messages tracing its execution.
	(This is probably not too useful outside of debugging.)
	.PP
	Note that the graphfile describes a
	.I directed
	graph.
	.I Span
	uses only
	.I out
	edges from sites, and does
	.I not 
	assume that if
	.I decvax
	can talk to
	.I utzoo
	then
	.I utzoo
	can also talk to
	.I decvax.
	If it can, then this information must appear explicitly in the
	adjacency list for
	.I utzoo.
	Alternatively, if
	.I decvax
	calls
	.I utzoo
	on demand but not vice versa, then the reverse connection
	should be left out of the graph so that
	.I span
	will use only reliable connections.
	Similarly, the connections in the adjacency list should be
	listed in decreasing order of reliability, since
	.I span
	uses the first path it finds.
	The '-a' option overrides this, causing span to generate a 'tree'
	with duplicate branches whenever there are several paths of the
	same 'shortest' length.
	All equal length paths will be generated.
	The resultant pathfile is, of course, larger.
	.PP
	.I Span
	produces warning messages for the following situations:
	.PP
	1. extraneous braces
	.PP
	2. duplicate entries (more than one adjacency list for a
	single host site)
	.PP
	3. missing entries (site appearing in an adjacency list with no
	such list of its own -- such sites are ignored)
	.PP
	4. no entry for the root site (this is a fatal error)
	.PP
	5. sites that cannot be reached (the graph may be disconnected
	or contain sites with out-edges only)
	.PP
	The
	.I graphfile
	can be automatically generated from a sorted list of edge connections
	by using awk(1).
	.SH BUGS
	The "shortest" path generated is does not take into account
	cost, physical distance or reliability of the connections.
	"Longer" paths that are in fact cheaper, faster or more
	reliable are not generated.
	.SH FILES
	/usr/pub/edgefile
	.br
	/usr/pub/graphfile
	.br
	/usr/pub/pathfile
	.SH AUTHOR
	Oscar Nierstrasz at the University of Toronto.
	.SH SEE ALSO
	path(1), unpath(1), mail(1).
Rosebud
echo doc/unpath.1
sed 's/^	//' > doc/unpath.1 << 'Rosebud'
	.TH UNPATH 1
	.UC
	.SH NAME
	unpath \- convert pathnames to site connections
	.SH SYNOPSIS
	.B unpath 
	< pathnamefile
	.SH DESCRIPTION
	.I Unpath
	takes a file containing site pathnames and generates a list of edges.
	For example:
	.IP
	allegra!amd70!trsvax!sneaky
	.PP
	is converted to:
	.IP
	allegra amd70
	.br
	amd70 trsvax
	.br
	trsvax sneaky
	.PP
	This is useful for generating new edges to be used by 
	span(1) in maintaining a database of UUCP site connections.
	Pathnames can be scavenged from mail and news files.
	A shell script using grep(1) and sed(1) can extract the path information
	and delete extraneous information.
	Use sort(1) to sort to output and remove duplicate entries.
	.PP
	.I NOTE:
	Be sure to remove user logins from pathnames or they will be
	interpreted as site names.
	.SH DIAGNOSTICS
	Reports unexpected characters in the input.
	.SH AUTHOR
	Oscar Nierstrasz at the University of Toronto.
	.SH SEE ALSO
	path(1), span(1), mail(1), grep(1), sed(1).
Rosebud
echo src/
mkdir src
echo src/README
sed 's/^	//' > src/README << 'Rosebud'
	Change the #define string PATHFILE in path.c to refer to the location
	of the pathfile on your system.
	
	Install the programs span and path in some publically accessible
	directory.  Path must be available to all.  Span is used only
	to maintain the database and must be accessible to the makefile in
	../map/makefile.
Rosebud
echo src/makefile
sed 's/^	//' > src/makefile << 'Rosebud'
	
	PROGS = path span unpath 
	
	B = ../bin
	
	SRC = ../src
	
	CMP = cc $@.c -o $@
	
	all : $(PROGS)
	
	clean :
		rm -f $(PROGS)
	
	path  : path.c
		$(CMP)
	
	span  : span.c
		$(CMP)
	
	unpath  : unpath.c
		$(CMP)
Rosebud
echo src/path.c
sed 's/^	//' > src/path.c << 'Rosebud'
	/*	FILE: PATH.C				831004
	 *	AUTHOR:	OSCAR NIERSTRASZ
	 */
	
	#include	<stdio.h>
	
	/*	default pathfile should be:
	#define		PATHFILE	"/usr/pub/pathfile"
		but is in fact:							*/
	#define		PATHFILE	"/u3/oscar/net/pathfile"
	#define		LONGPF		"/u3/oscar/net/longpf"
	
	/*	modes	*/
	#define		PATH		1
	#define		ALL		2
	#define		PRETTY		3
	
	#define		TRUE		1
	#define		FALSE		0
	
	#define		TAB		'\t'
	#define		BLANK		' '
	#define		EOL		'\n'
	#define		BANG		'!'
	#define		DOWN		'{'
	#define		UP		'}'
	#define		EOS		'\0'
	#define		SPACEFOUR	"    "
	
	#define		BUFLEN		300
	#define		MAXLEVELS	30
	#define		MAXARGS		50
	
	#define		charok(x)	(('-' <= x) && (x <= 'z'))
	#define		checkeob()	testbuf(pathchar, eobuf)
	
	main(argc, argv)
		int	argc;
		char	**argv;
	{
		int	i, lastarg, level, mode, reading, getfile, searching;
		char	pathname[BUFLEN], *site[MAXLEVELS];
		char	*pathchar, *lastchar, *eobuf;
		char	c, *filename, *find[MAXARGS];
		int	found[MAXARGS], first;
		FILE	*pathfile;
	
		/*	ARGUMENT PROCESSING	*/
		filename = PATHFILE; /* default pathfile */
		mode = PATH; /* default -- find pathname */
		lastarg = -1; /* index into find[] */
		getfile = FALSE; /* use different pathfile */
		for(i=1; i<argc; i++){
			if(getfile){
				filename = argv[i];
				getfile = FALSE;
				}
			else	if(argv[i][0] == '-'){
				switch(argv[i][1]){
				case 'a':
					mode = ALL;
					break;
				case 'p':
					mode = PRETTY;
					break;
				case 'f':
					getfile = TRUE;
					break;
				case 'l':
					filename = LONGPF;
					break;
				default:
					usage();
					break;
					}
				}
			else	{
				lastarg++;
				if(lastarg == MAXARGS){
					fprintf(stderr, "Error: too many arguments\n");
					exit(1);
					}
				find[lastarg] = argv[i];
				found[lastarg] = FALSE;
				}
			}
		if((mode == PATH) && (lastarg == -1))
			usage();
		if((mode != PATH) && (lastarg != -1))
			usage();
		if(getfile){
			fprintf(stderr, "Error: missing argument\n");
			usage();
			}
	
		/*	INITIALIZATION		*/
		pathfile = fopen(filename, "r");
		if(pathfile == NULL){
			fprintf(stderr, "Error: cannot open %s\n", filename);
			exit(1);
			}
	
		level = 0;
		eobuf = pathname + BUFLEN; /* end of pathname buffer */
		pathchar = pathname;
		site[level] = pathchar; /* points to level'th site in pathname */
		reading = FALSE; /* TRUE if getting site name */
		if(mode == PRETTY)	first = TRUE;
	
		while((c = fgetc(pathfile)) != EOF){
			if(charok(c)){
			/* get a site name into the buffer */
				reading = TRUE;
				*pathchar = c;
				pathchar++;
				checkeob();
				}
			else	{
				if(reading){
				/* test site name */
					reading = FALSE;
					*pathchar = EOS;
					lastchar = pathchar;
					pathchar = site[level];
					switch(mode){
					case	PATH:
						searching = TRUE;
						i = 0;
						while(searching){
							if(strcmp(find[i],site[level]) == 0){
							/* found a site */
								searching = FALSE;
								found[i] = TRUE;
								printf("%s\n", pathname);
								}
							else	{
							/* keep looking */
								i++;
								if(i > lastarg)
									searching = FALSE;
								}
							}
						break;
					case	ALL:
						printf("%s\n", pathname);
						break;
					case	PRETTY:
						if(first)
							first = FALSE;
						else	putchar(EOL);
						puttabs(level);
						printf("%s", site[level]);
						break;
					default:
					/* this can't happen */
						fprintf(stderr, "Error: unknown mode\n");
						exit(1);
						break;
						}
					}
				switch(c){
				/* white space */
				case	TAB:
				case	BLANK:
				case	EOL:
					break;
				case	DOWN:
				/* go down the tree */
					*lastchar = BANG;
					pathchar = lastchar+1;
					checkeob();
					level++;
					if(level > MAXLEVELS){
						fprintf(stderr, "Error: path too long\n");
						exit(1);
						}
					site[level] = pathchar;
					if(mode == PRETTY){
						putchar(BLANK);
						putchar(DOWN);
						}
					break;
				case	UP:
				/* go up the tree */
					if(mode == PRETTY){
						putchar(EOL);
						puttabs(level);
						putchar(UP);
						}
					level--;
					if(level < 0){
						fprintf(stderr, "Error: unmatched '%c'\n", UP);
						exit(1);
						}
					pathchar = site[level];
					break;
				default:
					fprintf(stderr, "Warning: '%c' bad character\n", c);
					break;
					}
				}
			}
		if(mode == PRETTY)	putchar(EOL);
		fclose(pathfile);
		for(i=0; i<=lastarg; i++){
			if(!found[i])
				fprintf(stderr, "Site '%s' not found\n", find[i]);
			}
	}
	usage(){
		fprintf(stderr, "Usage: path [ <site> ... | -p[retty] | -a[ll] ] [-l[ong] | -f <pathfile>]\n");
		exit(1);
	}
	puttabs(numtabs)
		int	numtabs;
	{
		int i, half, plusfour;
		half = numtabs/2;
		plusfour = ((numtabs%2) == 1);
		for(i=1; i<=half; i++)
			putchar(TAB);
		if(plusfour)
			printf(SPACEFOUR);
	}
	testbuf(ptr, end)
		char	*ptr, *end;
	{
		if(ptr == end){
			fprintf(stderr, "Error: buffer overflow\n");
			exit(1);
			}
	}
Rosebud
echo src/span.c
sed 's/^	//' > src/span.c << 'Rosebud'
	/*	FILE: SPAN.C				831005
	 *	AUTHOR:	OSCAR NIERSTRASZ
	 */
	
	#include	<stdio.h>
	
	#define		MAXNODES	1500	/* max nodes in graph */
	#define		MAXCHARS	10000	/* max chars in site name buffer */
	#define		MAXCONNS	5000	/* max edges in graph */
	#define		MAXLEVELS	50	/* max path length */
	#define		SITELEN		30	/* max site name length */
	#define		LEVBUFSIZ	(MAXNODES + MAXLEVELS)
	
	#define		EOLIST		-1
	#define		NOTFOUND	-1
	#define		NOTCHECKED	-1
	
	#define		TRUE		1
	#define		FALSE		0
	
	#define		TAB		'\t'
	#define		BLANK		' '
	#define		EOL		'\n'
	#define		DOWN		'{'
	#define		UP		'}'
	#define		EOS		'\0'
	#define		SPACEFOUR	"    "
	
	#define		loop		for(;;)
	#define		charok(x)	(('-' <= x) && (x <= 'z'))
	#define		checkeob()	testbuf(namechar, eobuf)
	#define		checkeofind()	testbuf(findptr, eofind)
	
	#define		ROOT		1
	#define		GRAPH		2
	#define		TREE		3
	#define		DONE		4
	
	/*	GLOBAL VARIABLES	*/
	struct	node {
		char	*sitename;	/* pointer into namebuf[] */
		int	connlist;	/* index into connbuf */
		int	distance;	/* distance from root */
		int	done;		/* flag when printed */
		} nodelist[MAXNODES];
	
	char	namebuf[MAXCHARS];	/* buffer for site names */
	int	connbuf[MAXCONNS], connidx; /* buffer for adjacency lists */
	int	lastnode, rootnode, parent; /* indices into nodelist */
	int	all; /* TRUE with -a option -- for all equal length paths */
	int	trace;	/* TRUE with -t option -- for diagnostic messages */
	int	compact; /* TRUE with -c option -- inhibits leading white space */
	int	levelbuf[LEVBUFSIZ], levelptr; /* lists of nodes at a given level */
	int	stack[MAXLEVELS], level; /* indices into connbuf or levelbuf */
	FILE	*infile, *outfile;
	
	main(argc, argv)
		int	argc;
		char	**argv;
	{
		char	*root;
		int	i, pretty, argtype;
	
		/*	ARGUMENT PROCESSING	*/
		all = FALSE;
		trace = FALSE;
		pretty = FALSE;
		compact = FALSE;
		/* arguments are ROOT GRAPH and TREE */
		argtype = ROOT;
		outfile = stdout; /* by default */
		for(i=1; i<argc; i++){
			if(argv[i][0] == '-'){
				switch(argv[i][1]){
				case 'a':
					all = TRUE;
					break;
				case 't':
					trace = TRUE;
					break;
				case 'p':
					pretty = TRUE;
					break;
				case 'c':
					compact = TRUE;
					break;
				default:
					usage();
					break;
					}
				}
			else	{
				switch(argtype){
				case	ROOT:
					root = argv[i];
					argtype = GRAPH;
					break;
				case	GRAPH:
					infile = fopen(argv[i], "r");
					if(infile == NULL){
						fprintf(stderr, "Error: Can't open %s\n", argv[i]);
						exit(1);
						}
					argtype = TREE;
					break;
				case	TREE:
					outfile = fopen(argv[i], "w");
					if(outfile == NULL){
						fprintf(stderr, "Error: Can't open %s\n", argv[i]);
						exit(1);
						}
					argtype = DONE;
					break;
				case	DONE:
					usage();
					break;
				default:
				/*	This can't happen	*/
					fprintf(stderr, "Error: unknown argtype\n");
					exit(1);
					}
				}
			}
		if((argtype != TREE) && (argtype != DONE))
			usage();
	
		loadnames(); /* first pass -- load site names */
		rewind(infile);
		loadconns(); /* second pass -- load adjacency lists */
		if(pretty)
			prettyprint();
		else {
			if((rootnode = search(root)) == NOTFOUND){
				fprintf(stderr, "Error: no entry for root site '%s'\n", root);
				exit(1);
				}
			if(trace)
				fprintf(stderr, "\nmain: root site '%s' is node %d\n\n", root, rootnode);
			gentree();	/* generate the spanning tree */
			printtree();	/* traverse and print the tree */
			orphans();	/* warn of unreachable sites */
			}
	
		fclose(outfile);
	}
	usage(){
		fprintf(stderr, "Usage: span <root site> <graph file> [<tree file>] [-a[ll]] [-c[ompact]]\n");
		exit(1);
	}
	puttabs(numtabs) /* use tabs and blanks to tab (4 * numtabs) spaces */
		int	numtabs;
	{
		int i, half, plusfour;
	
		if(compact)
			return;
		half = numtabs/2;
		plusfour = ((numtabs%2) == 1);
		for(i=1; i<=half; i++)
			fputc(TAB, outfile);
		if(plusfour)
			fprintf(outfile, SPACEFOUR);
	}
	testbuf(ptr, end)
		char	*ptr, *end;
	{
		if(ptr == end){
			fprintf(stderr, "Error: buffer overflow\n");
			exit(1);
			}
	}
	orphans() /* find nodes not covered by the spanning tree */
	{
		int	currnode;
	
		for(currnode=0; currnode<=lastnode; currnode++)
			if(!nodelist[currnode].done)
				fprintf(stderr, "Warning: %s could not be reached\n", 
					nodelist[currnode].sitename);
	}
	loadnames(){
		char	c, *namechar, *eobuf;
		int	reading, freenode, test;
	
		/* reads sitenames into namebuf[] and sets */
		/* nodelist[].sitename to point to this name */
	
		namechar = namebuf;
		eobuf = namebuf+MAXCHARS;
		reading = FALSE;
		freenode = 0;
		nodelist[freenode].sitename = namechar;
	
		while((c = fgetc(infile)) != EOF){
			if(charok(c)){
				reading = TRUE;
				*namechar = c;
				namechar ++;
				checkeob();
				}
			else	{
				if(reading){
					reading = FALSE;
					*namechar = EOS;
					namechar++;
					checkeob();
					if(trace)
						fprintf(stderr, "loadnames: node %d = %s\n", freenode, nodelist[freenode].sitename);
					if(freenode != 0){
						if((test = strcmp(nodelist[freenode-1].sitename, nodelist[freenode].sitename)) == 0)
							fprintf(stderr, "Warning: duplicate entry for site '%s'\n", nodelist[freenode].sitename);
						if(test > 0){
							fprintf(stderr, "Error: input not sorted\n");
							exit(1);
							}
						}
					freenode++;
					if(freenode > MAXNODES){
						fprintf(stderr, "Error: too many sites (max = %d)\n", MAXNODES);
						exit(1);
						}
					nodelist[freenode].sitename = namechar;
					}
				switch(c){
				case	TAB:
				case	BLANK:
				case	EOL:
					break;
				case	DOWN:
				/* skip the adjacency lists on the first pass */
					while((c = fgetc(infile)) != UP)
						if(c == EOF){
							fprintf(stderr, "Error: EOF -- missing '%c'\n", UP);
							exit(1);
							}
					break;
				case	UP:
					fprintf(stderr, "Warning: mismatched '%c'\n", UP);
					break;
				default:
					fprintf(stderr, "Warning: '%c' bad character\n", c);
					break;
					}
				}
			}
		if(freenode == 0){
			fprintf(stderr, "Error: empty input file\n");
			exit(1);
			}
		lastnode = freenode - 1;
		if(trace){
			fprintf(stderr, "\nloadnames: # of sites = %d (max %d)\n", lastnode, MAXNODES);
			fprintf(stderr, "loadnames: %d characters used (max = %d)\n\n", (namechar - namebuf), MAXCHARS);
			}
	}
	loadconns()
	{
		int	i, currnode, connect, reading, getconn;
		char	c, findsite[SITELEN], *findptr, *eofind;
	
		/* reads the adjacency list for each node and stores		*/
		/* the nodelist indices of each adjacent node in connbuf[]	*/
		/* search() is used to convert site names to indices.		*/
		/* nodelist[].connlist points to the beginning of the		*/
		/* adjacency list in connbuf[].  The lists are terminated	*/
		/* with an EOLIST.						*/
	
		connidx = 0; /* index into connbuf */
		reading = FALSE;
		findptr = findsite; /* site names are read into this buffer */
		eofind = findsite + SITELEN;
		getconn = FALSE; /* TRUE within adjacency list */
		currnode = -1;
	
		while((c = fgetc(infile)) != EOF){
			if(charok(c)){
				reading = TRUE;
				*findptr = c;
				findptr++;
				checkeofind();
				}
			else{
				if(reading){
					reading = FALSE;
					*findptr = EOS;
					findptr = findsite;
					if(getconn){
						if((connect = search(findsite)) == NOTFOUND)
							fprintf(stderr, "Warning: no entry for site '%s'\n", findsite);
						else{
						/* store the adjacency */
							connbuf[connidx] = connect;
							connidx++;
							if(trace)
								fprintf(stderr, "loadconns: %s -> %s\n", nodelist[currnode].sitename, nodelist[connect].sitename);
							if(connidx == MAXCONNS){
								fprintf(stderr, "Error: too many connections\n");
								exit(1);
								}
							}
						}
					else{
						currnode++;
						/* check if the host is still the one */
						/* you read in loadnames() */
						if(strcmp(findsite, nodelist[currnode].sitename) != 0){
						/* This can't happen */
							fprintf(stderr, "Program error: '%s' ~= '%s'\n", findsite, nodelist[currnode].sitename);
							exit(1);
							}
						/* terminate previous list */
						connbuf[connidx] = EOLIST;
						connidx++;
						if(connidx == MAXCONNS){
							fprintf(stderr, "Error: too many connections\n");
							exit(1);
							}
						nodelist[currnode].connlist = connidx;
						/* initialize other variables */
						nodelist[currnode].distance = NOTCHECKED;
						nodelist[currnode].done = FALSE;
						}
					}
				switch(c){
				case	TAB:
				case	BLANK:
				case	EOL:
					break;
				case	DOWN:
					if(getconn)
						fprintf(stderr, "Warning: extra '%c' ignored\n", DOWN);
					/* the next site name is an adjacency */
					getconn = TRUE;
					break;
				case	UP:
					if(!getconn)
						fprintf(stderr, "Warning: extra '%c' ignored\n", UP);
					/* the next site name is a host */
					getconn = FALSE;
					break;
				default:
					fprintf(stderr, "Warning: '%c' bad character\n", c);
					break;
					}
				}
			}
		/* terminate the last adjacency list */
		connbuf[connidx] = EOLIST;
		if(trace){
			fprintf(stderr, "\nloadconns: connbuf = ");
			for(i=0; i<=connidx; i++)
				fprintf(stderr, "%d ", connbuf[i]);
			fprintf(stderr, "\nloadconns: graph contains %d connections (max %d)\n\n", (connidx - lastnode), MAXCONNS);
			}
	}
	search(findsite)
		char	*findsite;
	{
		int	top, bot, mid, test;
	
		/* binary search through nodelist[].sitename */
		top = 0;
		bot = lastnode;
		if((test = strcmp(nodelist[top].sitename, findsite)) == 0)
			return(top);
		if(test > 0)
			return(NOTFOUND);
		if((test = strcmp(nodelist[bot].sitename, findsite)) == 0)
			return(bot);
		if(test < 0)
			return(NOTFOUND);
		loop{
			if(top == bot)
				return(NOTFOUND);
			mid = (top + bot)/2;
			if(mid == top)
				return(NOTFOUND);
			if((test = strcmp(nodelist[mid].sitename, findsite)) == 0)
				return(mid);
			if(test < 0)
				top = mid;
			else	bot = mid;
		}
			
	}
	gentree()
	{
		int	i, notdone, nextsite, parentnode;
	
		/* generate spanning tree by recording the distance */
		/* of each site from the root. */
		level = 0; /* start at distance = level 0 */
		levelptr = 0;
		stack[level] = levelptr; /* points to a list of nodes at that level */
		levelbuf[levelptr] = rootnode; /* root is at level 0 */
		nodelist[rootnode].distance = level;
		levelptr++;
	
		notdone = TRUE;
		while(notdone){
			notdone = FALSE;
			checklev(); /* check for buffer overflow */
			levelbuf[levelptr] = EOLIST; /* terminate previous list */
			level++; /* next level */
			if(level == MAXLEVELS){
				fprintf(stderr, "Error: path too long (max %d)\n", MAXLEVELS);
				exit(1);
				}
			levelptr++;
			checklev();
			stack[level] = levelptr;
	
			/* find all the children of nodes at the previous level */
			parent = stack[level-1]; /* init for getnode() */
			parentnode = levelbuf[parent];
	
			/* connidx points to the first possible child */
			connidx = nodelist[parentnode].connlist;
	
			/* record all nodes found at this level */
			while((nextsite = getnode()) != EOLIST){
				notdone = TRUE;
				nodelist[nextsite].distance = level;
				levelbuf[levelptr] = nextsite;
				levelptr++;
				checklev();
				if(trace)
					fprintf(stderr, "gentree: level %d => %s\n", level, nodelist[nextsite].sitename);
				}
			/* if no nodes found at this level then */
			/* notdone is still FALSE */
			}
		if(trace){
			fprintf(stderr, "gentree: levelbuf = ");
			for(i=0; i<levelptr; i++)
				fprintf(stderr, "%d ", levelbuf[i]);
			fprintf(stderr, "\n");
			}
	}
	getnode()
	{
		int	next, parentnode;
	
		loop{
			if((next = connbuf[connidx]) != EOLIST){
				connidx++;
				/* return if this node has not been checked */
				/* if the distance has already been set */
				/* then keep looking */
				if(nodelist[next].distance == NOTCHECKED)
					return(next);
				}
			else {
				/* last child, so get next parent */
				parent++;
				parentnode = levelbuf[parent];
				/* no more parents? */
				if(parentnode == EOLIST)
					return(EOLIST);
				else	connidx = nodelist[parentnode].connlist;
				}
			}
	}
	checklev(){
		if(levelptr > LEVBUFSIZ){
		/*	This can't happen	*/
			fprintf(stderr, "Error: level buffer overflow\n");
			exit(1);
			}
	}
	printtree()
	{
		int	nextsite, previous, started;
	
		/* traverse the tree depth first, printing each node */
		level = 0;
		previous = 1; /* previous level */
		started = FALSE;
		while((nextsite = depthfirst()) != EOLIST){
			if(previous < level){
				fputc(BLANK, outfile);
				fputc(DOWN, outfile);
				}
			else while(previous > level){
				fputc(EOL, outfile);
				puttabs(previous-1);
				fputc(UP, outfile);
				previous--;
				}
			if(started)
				fputc(EOL, outfile);
			else	started = TRUE;
			puttabs(level-1);
			fprintf(outfile, "%s", nodelist[nextsite].sitename);
			previous = level;
			}
		while(previous > 1){
			fputc(EOL, outfile);
			puttabs(previous-1);
			fputc(UP, outfile);
			previous--;
			}
		if(started)
			fputc(EOL, outfile);
	}
	depthfirst()
	{
		int	next;
	
		if(level < 1){ /* initially */
			nodelist[rootnode].done = TRUE;
			level = 1;
			stack[level] = nodelist[rootnode].connlist;
			}
		else {
			/* try to go down a level (depth first) */
			next = connbuf[stack[level]];
			level++;
			stack[level] = nodelist[next].connlist;
			}
		loop{
			if((next = connbuf[stack[level]]) == EOLIST){
				/* leaf node, so go up and right */
				level--;
				if(level < 1)
					return(EOLIST);
				stack[level]++; /* step right */
				}
			else {
				if((nodelist[next].distance == level) &&
					(all || !nodelist[next].done)){
					nodelist[next].done = TRUE;
					return(next);
					}
				/* wrong level or previously handled, step right */
				stack[level]++;
				}
			}
	}
	prettyprint(){
		int	currnode, connect;
	
		/* print each adjacency list as read in by loadnames() */
		/* and loadconns() */
		for(currnode=0; currnode<=lastnode; currnode++){
			fprintf(outfile, "%s", nodelist[currnode].sitename);
			connidx = nodelist[currnode].connlist;
			if(connbuf[connidx] != EOLIST){
				fprintf(outfile, " { ");
				while((connect = connbuf[connidx]) != EOLIST){
					fprintf(outfile, "%s ", nodelist[connect].sitename);
					connidx++;
					}
				fprintf(outfile, "}\n");
				}
			else	fputc(EOL, outfile);
			}
	}
Rosebud
echo src/unpath.c
sed 's/^	//' > src/unpath.c << 'Rosebud'
	
	/*	FILE: UNPATH.C
	 *	AUTHOR:	OSCAR NIERSTRASZ
	 *
	 *	Converts paths into lists of edges.  eg:
	 *
	 *		allegra!amd70!trsvax!sneaky
	 *
	 *	becomes
	 *
	 *		allegra amd70
	 *		amd70 trsvax
	 *		trsvax sneaky
	 *
	 *	This is useful for finding new mail connections from
	 *	such sources as net.news.  See edge(1), span(1) and path(1).
	 */
	
	#include	<stdio.h>
	
	#define		MAX		20
	
	#define		BAD		1
	#define		OLD		2
	#define		NEW		3
	
	#define		EOL		'\n'
	#define		EOS		'\0'
	#define		BANG		'!'
	
	#define		charok(x)	(('-' <= x) && (x <= 'z'))
	
	main()
	{
		char	s1[MAX], s2[MAX], *s, *host, *guest;
		int	sep;
	
		host = s1;
		guest = s2;
		sep = getsite(host);
		while(sep != EOF){
			switch(sep){
			case	BAD:
			case	MAX:
			case	NEW:
				sep = getsite(host);
				break;
			case	OLD:
				sep = getsite(guest);
				printf("%s %s\n", host, guest);
				s = host;
				host = guest;
				guest = s;
				break;
			}
		}
	}
	getsite(s)
		char	*s;
	{
		int	i=0;
		char	c;
	
		c = fgetc(stdin);
		while((c != EOL) && (c != BANG)){
			if(c == EOF)
				return(EOF);
			if(!charok(c)){
				fprintf(stderr, "Bad character: '%c'\n", c);
				return(BAD);
				}
			s[i] = c;
			i++;
			if(i == MAX){
				fprintf(stderr, "Site name too long: '%s'\n", s);
				s[i-1] = '\0';
				return(MAX);
			}
			c = fgetc(stdin);
		}
		s[i] = EOS;
		if(c == EOL)
			return(NEW);
		else	return(OLD);
	}
Rosebud
echo map/
mkdir map
echo map/README
sed 's/^	//' > map/README << 'Rosebud'
	This is a work directory for creating the graphfile used by span(1).
	See documentation for span(1), path(1) and unpath(1).
	
	Change the line "host = utcsrgv" in the makefile to your sitename.
	If your site has an entry in "graphfile", simply run:
	
		make pathfile
	
	and install the pathfile in whatever location the path program
	expects to find it (see ../src/path.c).
	
	If your site is not mentioned in graphfile, you may add it
	by editing in the appropriate line (in SORT order), or
	you may do it automatically by adding the new edges (see the
	examples in "bad" and "oneway"):
	
	To add new edges, place them in "more" and run "make pathfile".
	Install the pathfile in the appropriate location.  (You may modify
	the makefile to do this automatically.)  "make clean" will get
	rid of the generated files.
	
	------------------------------- FILES -------------------------------
	
	makefile .............. makefile for generating pathfile
	edmap ................. a shell script for converting net maps to graph files
	
	graphfile ............. the mail connection database
	backup ................ a backup of the previous graphfile
	pathfile .............. generated from graphfile
	sites ................. generated from graphfile
	
	more .................. new edges to be added to graphfile
	
	bad ................... some connections that don't seem to work
	oneway ................ "one-way" connections (various reasons)
	
	ae.awk ................ convert adjacency lists to edge lists
	bot.awk ............... select bottom half of edge list
	ea.awk ................ convert edge lists to adjacency lists
	rev.awk ............... reverse edges
	sites.awk ............. print site names only
	top.awk ............... select top half of edge list
Rosebud
echo map/ae.awk
sed 's/^	//' > map/ae.awk << 'Rosebud'
	
	BEGIN {
		host = 1
		site = ""
		}
	{
		for (i=1; i <= NF; i++) {
			if ($i == "{") {
				if (host)
					host = 0
				else	{
					printf "Mismatched braces\n"
					exit
					}
				}
			else if ($i == "}") {
				if (host) {
					printf "Mismatched braces\n"
					exit
					}
				else	host = 1
				}
			else {
				if (host)
					site = $i
				else	print site, $i
				}
			}
	}
	END	{
		if (!host) {
			printf "Mismatched braces\n"
			exit
			}
	}
Rosebud
echo map/bad
sed 's/^	//' > map/bad << 'Rosebud'
	cornell lbl-csam
	ctvax uiucdcs
	ihnp4 mh3bs
	lbl-csam cornell
	mh3bs ihnp4
	trsvax uiucdcs
	uiucdcs uiucsrl
	uiucdcs uok
	uiucdcs uokvax
Rosebud
echo map/bot.awk
sed 's/^	//' > map/bot.awk << 'Rosebud'
	$2 > $1
Rosebud
echo map/dist.awk
sed 's/^	//' > map/dist.awk << 'Rosebud'
	BEGIN { FS = "!" }
	{ if (NF >= 6) print NF, $0 }
Rosebud
echo map/ea.awk
sed 's/^	//' > map/ea.awk << 'Rosebud'
	BEGIN {
		host = "" 
		prev = 0
		}
	{
		if ($1 != host) {
			if (prev)
				printf " }\n"
			else	prev = 1
			host = $1
			linelen = length + 2
			printf "%s { %s", $1, $2
			}
		else	{
			linelen = linelen + 1 + length($2)
			if (linelen > 70) {
				printf "\n\t%s", $2
				linelen = 8 + length($2)
				}
			else	printf " %s", $2
			}
	}
	END {
		if (prev)
			printf " }\n"
	}
Rosebud
echo map/edmap
sed 's/^	//' > map/edmap << 'Rosebud'
	ed - $1 <<!
	1,/^Lines/d
	g/^echo/d
	g/^cat/d
	g/^Comments/d
	g/^\!Funky/d
	g/^Organization/d
	g/^Contact/d
	g/^Phone/d
	g/^Postal/d
	g/^Electronic/d
	g/^Name/s/$/ {/
	g/^Name/i }
	g/^Name:/s///
	g/^News:/s///
	g/^Mail:/s///
	g/^ */s///
	g/^$/d
	w
	q
	!
	echo map $1 finished
Rosebud
echo map/graphfile
sed 's/^	//' > map/graphfile << 'Rosebud'
	5941ux { allegra houxf houxm ihnp4 machaids }
	abnjh { allegra ihnp4 pyuxll u1100a }
	adec23 { hssg40 }
	adiron { allegra duke rlgvax }
	alberta { allegra auvax ihnp4 sask ubc-vision }
	alfalfa { allegra ihnp4 spanky }
	alice { allegra cbosg circe cornell floyd ihnp4 ima mhtsa npois npoiv
		rabbit research ulysses }
	allegra { 5941ux abnjh adiron alberta alfalfa alice aluxz amd70 ariel
		arizona astrovax beesvax brunix burl cbosg cbosgd cbrmc cbscc
		cbscd5 circe cmcl2 cornell decvax decwrl denelcor druxs duke
		eagle eisx esquire floyd fluke fortune garfield gatech genrad
		gummo harpo hfhrv hlexa hlhop hocda hocsf hogpc hogpd hou5a
		hou5b hou5c hou5d hou5e hou5f houca houem hound houti houxa
		houxf houxk houxm houxw houxz hp-dcd hplabs ih1ap iheds ihldt
		ihlts ihn5i ihn5l ihnet ihnp1 ihnp3 ihnp4 ihnss ihpad ihtnt
		ihtpa ihu1e ihu1f ikonas ima inuxa inuxb inuxc inuxd inuxe
		ism780 isrnix ittvax iuvax ixhte ixn5c kcwin kpno laidbak
		linus ll1 llkp03 machaids masscomp mb2c mcnc mh3bs mhtsa mhuxa
		mhuxd mhuxh mhuxi mhuxj mhuxm mhuxr mhuxt mhuxv mi-cec mit-vax
		nbires ncrday npois npoiv nscs nwuxd ogcvax oliveb orion otuxa
		parsec pegasus philabs phonlab pitt princeton psuvax pur-ee
		purdue pyuxcc pyuxdd pyuxhh pyuxi pyuxjj pyuxk pyuxl pyuxll
		pyuxmm pyuxnn pyuxqq pyuxss pyuxvv rabbit rayssd research
		rlgvax rna rochester rocksvax sb1 sb6 sbcs scbhq scgvaxd
		sdcarl sdcrdcf sdcsvax spanky sri-unix stolaf sun sunrise
		teklabs tektronix tpsa tropix u1100a u1100s ucbcad ucbvax
		ucsfcgl uf-cgrl ulysses umcp-cs unc uniq uofm-cv ut-ngp
		utcsrgv utzoo uvacs uw-beaver uwvax vax135 vortex watcgl
		wateng watmath wb2 wbux5 we13 we53 wheps whuxk whuxlb wjh12
		zehntel zeppo }
	altos86 { amd70 microsoft sun }
	aluxz { allegra ihnp4 mhuxi }
	amd70 { allegra altos86 burl clyde decwrl eagle floyd fortune ihnp4
		ihnss ima megatest nbires packet qubix research rocksvax sco
		sri-unix sun tpsa trsvax trw-unix turtlevax twg ucbvax uf-cgrl
		uofm-cv varian vortex wjh12 zehntel }
	aplvax { brl-bmd umcp-cs }
	ariel { allegra hou5f houti ihnp4 maxvax orion vax135 }
	arizona { allegra cornell ihnp4 kpno mcnc purdue teklabs ucbvax
		utah-cs uw-beaver }
	astrovax { allegra burl cbosgd decvax ihnp4 kpno princeton rocky2 }
	atd { avsdS dsd hplabs turtlevax ucbvax }
	att3 { ll1 }
	aus86 { icalqa omsvax ut-ngp }
	auvax { alberta }
	avsdF { avsdS }
	avsdS { atd avsdF avsdT dsd }
	avsdT { avsdS }
	basservax { mhtsa sdchema }
	beesvax { allegra ima ios ism780 oz uf-cgrl utah-cs }
	bmcg { felix sdccsu3 sdcrdcf sdcsvax }
	bpa { burdvax ll1 sb1 sb6 }
	brl-bmd { aplvax decvax denelcor duke esquire hao rlgvax udrelay
		umcp-cs unc }
	bronze { iddic tekcad tekchips tekecs tekgds teklabs tekmdp tektronix }
	brunix { allegra cornell foxvax1 ihnp4 ima linus rayssd uf-cgrl
		ulysses yale-comix }
	bunker { bunkerb decvax duke ittvax philabs watmath zeppo }
	bunkerb { bunker }
	burdvax { bpa presby psuvax sdcrdcf }
	burl { allegra amd70 astrovax cbosgd clyde duke floyd ihnp4 ittral
		kcwin mcnc mgweed mhuxv otuxa sb1 sb6 spanky unm-ivax we13
		whuxk whuxlb }
	cbosg { alice allegra cbosgd cbscd5 cornell druxs ihnp4 mhuxt npois
		nscs osu-dbs pyuxhh teklabs ucbvax }
	cbosgd { allegra astrovax burl cbosg cbrap cbrmc cbscc cbscd5 cornell
		fortune ihnp4 ima linus mddc mhuxi mhuxj npois nscs osu-dbs
		philabs pur-ee rlgvax sdcrdcf ulysses }
	cbrap { cbosgd }
	cbrmc { allegra cbosgd ihnp4 mork-cb nscs }
	cbscc { allegra cbosgd cbscd5 ihnp4 }
	cbscd5 { allegra cbosg cbosgd cbscc ihnp4 }
	cca { comet csin decvax ima linus security sri-unix }
	ccieng5 { rayssd ritcv rlgvax }
	ccvaxa { uiucdcs }
	cda5d { houxz }
	cdi { metheus reed sequel }
	cdlncch { laidbak turtlevax }
	cfib { foxvax1 ima sii }
	cg-d { decvax }
	cincy { decvax ncrday }
	circe { alice allegra eagle gatech harpo ihnp4 mhuxa mhuxj mhuxt
		rabbit research ulysses }
	cires { csu-cs hao nbires }
	clyde { amd70 burl floyd ihnp4 masscomp }
	cmcl1 { cmcl2 }
	cmcl2 { allegra cmcl1 cornell esquire floyd harpo ihnp4 lanl-a nybcb
		philabs presby rna rocky2 sunrise }
	comet { cca regi ukc }
	cornell { alice allegra arizona brunix cbosg cbosgd cmcl2 ctvax decvax
		eagle esquire floyd harpo ihnp4 ihnss ima lanl-a mcnc megatest
		nbires ogcvax psuvax purdue rabbit research sask sii sun tesla
		unc utcsrgv uw-beaver vax135 yale-comix zeppo }
	crimson { tekmdp }
	crystal { uwvax }
	csin { cca sri-unix }
	csu-cs { cires denelcor hao hp-dcd hplabs lanl-a mit-vax unmvax }
	ctvax { cornell nbires parsec trsvax ut-ngp }
	cubs45 { esquire }
	cvl { rlgvax umcp-cs }
	cwruecmp { cwrunix decvax medman teklabs uf-cgrl utzoo }
	cwrunix { cwruecmp }
	dadla { dadla-a dadla-b dadla-d tekmdp }
	dadla-a { dadla }
	dadla-b { dadla }
	dadla-d { dadla }
	dcdwest { ittvax sdcsvax }
	dciem { hcr trigraph utcsrgv utzoo }
	decvax { allegra astrovax brl-bmd bunker cca cg-d cincy cornell
		cwruecmp decwrl duke genrad harpo hcr hei44 idis ihnp4 ittvax
		kpno linus masscomp mcnc mcvax microsoft philabs pur-ee
		sdchema sii teklabs tektronix trw-unix ucbvax ucf-cs unh
		utcsrgv utzoo uw-beaver vortex watmath wivax yale-comix }
	decwrl { allegra amd70 decvax flairvax ihnp4 ios purdue qubix sequel
		sun turtlevax ucbvax utcsrgv }
	denelcor { allegra brl-bmd csu-cs hao nbires }
	diku { ibt mcvax }
	dri0 { pitt }
	druxs { allegra cbosg ihnp4 ixn5c maxvax }
	dsd { atd avsdS fortune hplabs }
	duke { adiron allegra brl-bmd bunker burl decvax dvamc hplabs ihnp4
		ittvax mcnc phs reed tucc ucf-cs unc utzoo }
	dutesta { mcvax }
	dvamc { duke mcnc phs }
	dvlcn { sask }
	eagle { allegra amd70 circe cornell eisx harpo ihnp4 masscomp mh3bs
		mhtsa mhuxi mhuxj mhuxt mit-vax pur-ee purdue sb1 sb6 spanky
		teklabs ucbvax ulysses ut-ngp wb2 wheps }
	ecn-ec { ecn-pa pur-ee purdue }
	ecn-ed { ecn-pc }
	ecn-pa { ecn-ec ecn-pc pur-ee }
	ecn-pc { ecn-ed ecn-pa }
	ecs { tucc }
	edai { edee edmrc }
	edcaad { edee edmrc logica mcvax root44 ukc vax135 }
	edee { edai edcaad edmiru glasgow }
	edmiru { edee edmrc }
	edmrc { edai edcaad edmiru glasgow }
	eisx { allegra eagle ihnp4 inuxa npois npoiv pyuxjj pyuxll whuxlb }
	emory { gatech msdc sb1 sb6 }
	esquire { allegra brl-bmd cmcl2 cornell cubs45 ima inmet rna }
	fau { ucf-cs }
	felix { bmcg trw-unix vortex }
	flairvax { decwrl hpda hplabs turtlevax }
	floyd { alice allegra amd70 burl clyde cmcl2 cornell fortune harpo
		idis ihnp4 ima kpno masscomp philabs pur-ee purdue rabbit
		sunrise ucbvax unc utcsrgv utzoo vax135 vortex whuxlb }
	fluke { allegra microsoft sb1 sb6 ssc-vax teltone uf-cgrl uw-beaver
		uw-vlsi }
	fortune { allegra amd70 cbosgd dsd floyd harpo hpda ihnp4 megatest nsc
		oliveb sri-unix twg varian vortex wdl1 }
	foxvax1 { brunix cfib wjh12 }
	garfield { allegra ihnp4 linus munodie utcsrgv }
	gatech { allegra circe emory itm msdc rlgvax sb1 sb6 uf-cgrl ulysses
		unmvax ut-ngp }
	genrad { allegra decvax grkermit linus masscomp mit-eddie security
		wjh12 }
	glasgow { edee edmrc glhocus }
	glhocus { glasgow }
	grkermit { genrad masscomp mit-vax }
	gummo { allegra harpo ihnp4 whuxlb zeppo }
	hao { brl-bmd cires csu-cs denelcor hplabs hplabsb hplabsc kpno
		menlo70 nbires seismo ucsfcgl }
	harpo { harpo houxf uw-beaver }
	hcr { dciem decvax ihnp4 trigraph utcsrgv utzoo watmath }
	hei44 { decvax ittvax sii }
	hfhrv { allegra mb2c }
	hirst1 { ukc }
	hlexa { allegra hlhop ihnp4 }
	hlhop { allegra hlexa ihnp4 mhuxh }
	hocda { allegra houxm houxz idis ihnp4 inuxc machaids spanky }
	hocsf { allegra hogpc ihnp4 }
	hogpc { allegra hocsf hogpd hou5d houca houti houxm ihnp4 npois
		pegasus }
	hogpd { allegra hogpc ihnp4 }
	hou5a { allegra hou5b hou5c hou5d hou5e hou5f houca houti houxa houxf
		houxk houxm houxw houxz ihnp4 }
	hou5b { allegra hou5a hou5c hou5d hou5e hou5f houca houti houxa houxf
		houxk houxm houxw houxz ihnp4 }
	hou5c { allegra hou5a hou5b hou5d hou5e hou5f houca houti houxa houxf
		houxk houxm houxw houxz ihnp4 }
	hou5d { allegra hogpc hou5a hou5b hou5c hou5e hou5f houca houti houxa
		houxf houxk houxm houxw houxz ihnp4 }
	hou5e { allegra hou5a hou5b hou5c hou5d hou5f houca houti houxa houxf
		houxk houxm houxw houxz ihnp4 }
	hou5f { allegra ariel hou5a hou5b hou5c hou5d hou5e houca houti houxa
		houxf houxk houxm houxw houxz ihnp4 npoiv orion }
	houca { allegra hogpc hou5a hou5b hou5c hou5d hou5e hou5f houti ihnp4
		odin orion }
	houem { allegra houxm ihnp4 }
	hound { allegra houxa houxm ihnp4 }
	houti { allegra ariel hogpc hou5a hou5b hou5c hou5d hou5e hou5f houca
		ihnp4 pegasus }
	houxa { allegra hou5a hou5b hou5c hou5d hou5e hou5f hound houxf houxk
		houxm ihnp4 maxvax spanky }
	houxf { 5941ux allegra harpo hou5a hou5b hou5c hou5d hou5e hou5f houxa
		houxm ihnp4 maxvax spanky }
	houxk { allegra hou5a hou5b hou5c hou5d hou5e hou5f houxa houxm houxw
		ihnp4 maxvax spanky }
	houxm { 5941ux allegra hocda hogpc hou5a hou5b hou5c hou5d hou5e hou5f
		houem hound houxa houxf houxk houxw houxz ihnp4 maxvax mhuxa
		mhuxi npois pegasus spanky u1100a wbux5 whuxk }
	houxw { allegra hou5a hou5b hou5c hou5d hou5e hou5f houxk houxm ihnp4
		maxvax spanky }
	houxz { allegra cda5d hocda hou5a hou5b hou5c hou5d hou5e hou5f houxm
		ihnp4 maxvax npois spanky wb2 wbux5 whuxk }
	hp-cvd { hp-pcd hplabs kirk }
	hp-dcd { allegra csu-cs hp-pcd hpda hplabs }
	hp-pcd { harpo hp-cvd hp-dcd hpda hplabs microsoft ogcvax orstcs }
	hpda { flairvax fortune hp-dcd hp-pcd hpdb hpdc hplabs hptabu sun
		ucbvax }
	hpdb { hpda hpdc hptabu }
	hpdc { hpda hpdb hptabu }
	hplabs { allegra atd csu-cs dsd duke flairvax hao hp-cvd hp-dcd hp-pcd
		hpda hplabsb hplabsc icalqa mcnc menlo70 oliveb omsvax purdue
		sdcarl sdcrdcf sri-unix sytek ucbvax utah-cs zehntel }
	hplabsb { hao hplabs zehntel }
	hplabsc { hao hplabs icalqa zehntel }
	hptabu { hpda hpdb hpdc }
	hscfvax { n44a }
	hscvax { nbires wjh12 }
	hssg40 { adec23 sask }
	ibt { diku }
	icalqa { aus86 hplabs hplabsc omsvax pur-ee rocks34 }
	ico { ima }
	iddic { bronze tekcad tekchips tekecs tekgds teklabs tektronix }
	idis { decvax floyd hocda mcnc mi-cec pitt }
	ih1ap { allegra ihnp4 }
	ih4ep { ihnp4 }
	iheds { allegra ihnp4 ixn5c }
	ihhfl { ihnp4 }
	ihima { ihnp4 }
	ihldt { allegra ihnp4 ihtnt ixn5c }
	ihlts { allegra ihnp4 }
	ihn5i { allegra ihnp4 }
	ihn5l { allegra ihnp4 }
	ihnet { allegra ihnp4 }
	ihnp1 { allegra ihnp4 }
	ihnp3 { allegra ihnp4 }
	ihnp4 { 5941ux abnjh alberta alfalfa alice allegra aluxz amd70 ariel
		arizona astrovax brunix burl cbosg cbosgd cbrmc cbscc cbscd5
		circe clyde cmcl2 cornell decvax decwrl druxs duke eagle eisx
		floyd fortune garfield gummo harpo hcr hlexa hlhop hocda hocsf
		hogpc hogpd hou5a hou5b hou5c hou5d hou5e hou5f houca houem
		hound houti houxa houxf houxk houxm houxw houxz ih1ap ih4ep
		iheds ihhfl ihima ihldt ihlts ihn5i ihn5l ihnet ihnp1 ihnp3
		ihnss ihpad ihtnt ihtpa ihu1e ihu1f inuxa inuxb inuxc inuxd
		inuxe iuvax ixhte ixn5c kcwin kpno laidbak linus ll1 llkp03
		machaids masscomp mb2c mcnc mgweed mhtsa mhuxa mhuxd mhuxh
		mhuxi mhuxj mhuxm mhuxr mhuxt mhuxv npois npoiv nwuxd odin
		orion otuxa parsec pegasus phonlab princeton psuvax pur-ee
		purdue pyuxcc pyuxdd pyuxhh pyuxi pyuxjj pyuxk pyuxl pyuxll
		pyuxmm pyuxnn pyuxqq pyuxss pyuxvv rabbit research rlgvax sb1
		sb6 scbhq sdcarl sdcrdcf sdcsvax seismo spanky stolaf sun
		teklabs tektronix tropix tty3b u1100a u1100s ucbvax uiucdcs
		ulysses umn-cs uniq uofm-cv ut-ngp utcsrgv utzoo uw-beaver
		uwvax vax135 vortex watmath wb2 wbux5 we13 we53 wheps whuxk
		whuxlb wjh12 zehntel zeppo zinfandel }
	ihnss { allegra amd70 cornell ihnp4 pur-ee sdcrdcf teklabs }
	ihpad { allegra ihnp4 }
	ihtnt { allegra ihldt ihnp4 }
	ihtpa { allegra ihnp4 }
	ihu1e { allegra ihnp4 }
	ihu1f { allegra ihnp4 }
	ikonas { allegra mcnc ncsu }
	ima { alice allegra amd70 beesvax brunix cbosgd cca cfib cornell
		esquire floyd ico images imd inmet ipa ism750 ism780 n44a
		princeton rabbit research vortex wjh12 yale-comix }
	images { ima }
	imd { ima }
	inmet { esquire harpo ima masscomp }
	inuxa { allegra eisx ihnp4 inuxc pur-ee purdue }
	inuxb { allegra ihnp4 inuxc pur-ee }
	inuxc { allegra hocda ihnp4 inuxa inuxb inuxd inuxe ixn5c pur-ee }
	inuxd { allegra ihnp4 inuxc pur-ee }
	inuxe { allegra ihnp4 inuxc }
	ios { beesvax decwrl oliveb qubix uf-cgrl }
	ipa { ima }
	ism750 { ima }
	ism780 { allegra beesvax ima }
	isrnix { allegra iuvax pur-ee }
	itm { gatech msdc }
	ittral { burl ittvax laidbak mcnc ncsu }
	ittvax { allegra bunker dcdwest decvax duke hei44 ittral ndcuts psuvax
		purdue qubix qumix research sii uf-cgrl wxlvax yale-comix }
	iuvax { allegra ihnp4 isrnix pur-ee twg }
	ixhte { allegra ihnp4 }
	ixn5c { allegra druxs iheds ihldt ihnp4 inuxc }
	kcwin { allegra burl ihnp4 we53 }
	kirk { hp-cvd }
	kobold { masscomp orc }
	kpno { allegra arizona astrovax decvax floyd hao ihnp4 sdcarl sdcsvax
		seismo unc utastro vortex }
	laidbak { allegra cdlncch ihnp4 ittral trsvax }
	lanl-a { cmcl2 cornell csu-cs nmtvax purdue unm-ivax utah-cs }
	linus { allegra brunix cbosgd cca decvax garfield genrad ihnp4
		mit-eddie philabs rayssd security utcsrgv utzoo uw-beaver
		vaxine watmath wivax wjh12 yale-comix }
	ll1 { allegra att3 bpa ihnp4 ll1b otuxa sb1 sb6 }
	ll1b { ll1 sb1 sb6 }
	llkp03 { allegra ihnp4 whuxk }
	logica { edcaad }
	machaids { 5941ux allegra hocda ihnp4 }
	masscomp { allegra clyde decvax eagle floyd genrad grkermit harpo
		ihnp4 inmet kobold mit-vax orc pur-ee research tektronix
		ucbcad zeppo }
	maxvax { ariel druxs houxa houxf houxk houxm houxw houxz pegasus sask }
	mb2b { uofm-cv }
	mb2c { allegra hfhrv ihnp4 sb1 sb6 uofm-cv }
	mcnc { allegra arizona burl cornell decvax duke dvamc hplabs idis
		ihnp4 ikonas ittral msdc ncsu rlgvax tucc ulysses unc unc-c }
	mcpdp34 { mcpdp45 mcvax }
	mcpdp45 { mcpdp34 mcvax }
	mcvax { decvax diku dutesta edcaad mcpdp34 mcpdp45 nlgvax philabs
		philmds sara70 ukc uvapsy vmucnam vu44 vub zti1 }
	mddc { cbosgd }
	medman { cwruecmp }
	megatest { amd70 cornell fortune p500vax sun ubvax }
	menlo70 { hao hplabs nsc pur-ee sdcrdcf sri-unix sytek ucbvax ucsfcgl }
	metheus { cdi ogcvax uf-cgrl }
	mgweed { burl ihnp4 we13 }
	mh3bs { allegra eagle mhtsa we53 }
	mhtsa { ihnp4 }
	mhuxa { allegra circe houxm ihnp4 mhuxd mhuxh mhuxi mhuxj mhuxt mhuxv
		ulysses }
	mhuxd { allegra ihnp4 mhuxa mhuxh mhuxm mhuxv }
	mhuxh { allegra hlhop ihnp4 mhuxa mhuxd mhuxi mhuxj mhuxm mhuxt }
	mhuxi { allegra aluxz cbosgd eagle houxm ihnp4 mhuxa mhuxh mhuxj mhuxm
		mhuxt mhuxv vax135 wjh12 }
	mhuxj { allegra cbosgd circe eagle ihnp4 mhuxa mhuxh mhuxi mhuxm mhuxt
		mhuxv pyuxjj }
	mhuxm { allegra ihnp4 mhuxd mhuxh mhuxi mhuxj mhuxr mhuxt mhuxv pyuxi
		pyuxjj }
	mhuxr { allegra ihnp4 mhuxm mhuxt }
	mhuxt { allegra cbosg circe eagle ihnp4 mhuxa mhuxh mhuxi mhuxj mhuxm
		mhuxr mhuxv pyuxjj rabbit }
	mhuxv { allegra burl ihnp4 mhuxa mhuxd mhuxi mhuxj mhuxm mhuxt }
	mi-cec { allegra idis }
	micomvax { micomz philabs }
	micomz { micomvax }
	microsoft { altos86 decvax fluke hp-pcd omsvax sco trsvax ubc-vision
		uw-beaver }
	minn-ua { umn-cs }
	mit-eddie { genrad linus mit-vax tektronix }
	mit-vax { allegra csu-cs eagle grkermit masscomp mit-eddie research }
	moria { uiucdcs }
	mork-cb { cbrmc }
	mprvaxa { ubc-vision }
	msdc { emory gatech itm mcnc ncsu sb1 }
	munodie { garfield }
	n44a { hscfvax ima rna wjh12 }
	nbires { allegra amd70 cires cornell ctvax denelcor hao hscvax opus
		princeton ucbvax uofm-cv ut-ngp utah-cs }
	ncrday { allegra cincy purdue }
	ncsu { ikonas ittral mcnc msdc uvacs }
	ndcuts { ittvax }
	nlgvax { mcvax }
	nmtvax { lanl-a unm-ivax unmvax }
	noscvax { sdcsvax }
	npois { alice allegra cbosg cbosgd eisx hogpc houxm houxz ihnp4 npoiv
		u1100s ucbvax wbux5 }
	npoiv { alice allegra eisx hou5f ihnp4 npois }
	nsc { fortune menlo70 sequel ucbvax uf-che }
	nscs { allegra cbosg cbosgd cbrmc }
	nwuxd { allegra ihnp4 otuxa we13 }
	nybcb { cmcl2 }
	odin { houca ihnp4 orion }
	ogcvax { allegra cornell hp-pcd metheus omsvax sbcs sequel teklabs
		tektronix }
	oliveb { allegra fortune hplabs ios uvacs }
	omsvax { aus86 hplabs icalqa microsoft ogcvax }
	opus { nbires }
	orc { kobold masscomp }
	orion { allegra ariel hou5f houca ihnp4 odin }
	orstcs { hp-pcd sdcrdcf teklabs }
	osu-dbs { cbosg cbosgd }
	otuxa { allegra burl ihnp4 ll1 nwuxd tty3b we13 we53 }
	oz { beesvax }
	p500vax { megatest }
	packet { amd70 }
	parsec { allegra ctvax ihnp4 uiucdcs unmvax }
	pegasus { allegra hogpc houti houxm ihnp4 maxvax }
	philabs { allegra bunker cbosgd cmcl2 decvax floyd linus mcvax
		micomvax philmds pwa-b rdin sbcs sdcsvax seismo sunrise
		uiucdcs vax135 }
	philmds { mcvax philabs }
	phonlab { allegra ihnp4 pur-ee sdcarl sdcatta sdcattb sdchema sdcrdcf
		sdcsla sdcsvax }
	phs { duke dvamc }
	pitt { allegra dri0 idis }
	populi { ucbtopaz ucbvax }
	presby { burdvax cmcl2 seismo }
	princeton { allegra astrovax ihnp4 ima nbires uf-cgrl ulysses }
	psupdp1 { psuvax }
	psuvax { allegra burdvax cornell ihnp4 ittvax psupdp1 }
	pucc-h { pucc-i pur-phy purdue }
	pucc-i { pucc-h }
	pur-ee { allegra cbosgd decvax eagle ecn-ec ecn-pa floyd harpo icalqa
		ihnp4 ihnss inuxa inuxb inuxc inuxd isrnix iuvax masscomp
		menlo70 phonlab pur-phy purdue rocks34 sdcarl sequel sri-unix
		teklabs ucbvax ucsfcgl uiucdcs uofm-cv }
	pur-phy { pucc-h pur-ee purdue }
	purdue { allegra arizona cornell decwrl eagle ecn-ec floyd hplabs
		ihnp4 inuxa ittvax lanl-a ncrday pucc-h pur-ee pur-phy
		research sb1 sb6 }
	pwa-b { philabs utah-gr }
	pyuxcc { allegra ihnp4 pyuxi pyuxjj }
	pyuxdd { allegra ihnp4 pyuxjj pyuxmm pyuxnn rabbit }
	pyuxhh { allegra cbosg ihnp4 pyuxi }
	pyuxi { allegra ihnp4 mhuxm pyuxcc pyuxhh pyuxjj pyuxk pyuxl pyuxnn
		pyuxqq pyuxss pyuxvv u1100a }
	pyuxjj { allegra eisx ihnp4 mhuxj mhuxm mhuxt pyuxcc pyuxdd pyuxi
		pyuxk pyuxl pyuxll pyuxqq }
	pyuxk { allegra ihnp4 pyuxi pyuxjj pyuxl pyuxss }
	pyuxl { allegra ihnp4 pyuxi pyuxjj pyuxk pyuxvv }
	pyuxll { abnjh allegra eisx ihnp4 pyuxjj whuxlb }
	pyuxmm { allegra ihnp4 pyuxdd pyuxnn rabbit }
	pyuxnn { allegra ihnp4 pyuxdd pyuxi pyuxmm rabbit }
	pyuxqq { allegra ihnp4 pyuxi pyuxjj }
	pyuxss { allegra ihnp4 pyuxi pyuxk }
	pyuxvv { allegra ihnp4 pyuxi pyuxl }
	qubix { amd70 decwrl ios ittvax qumix }
	qumix { ittvax qubix }
	rabbit { alice allegra circe cornell floyd ihnp4 ima mhuxt pyuxdd
		pyuxmm pyuxnn ulysses unc }
	rayssd { allegra brunix ccieng5 linus }
	rdin { philabs }
	reed { cdi duke tektronix uw-beaver }
	regi { comet ukc }
	research { alice allegra amd70 circe cornell ihnp4 ima ittvax masscomp
		mhtsa mit-vax purdue rlgvax sb1 sb6 sdcrdcf ulysses unmvax
		utzoo wheps }
	ritcv { ccieng5 ritvp rochester rocks34 rocksvax tropix }
	ritvp { ritcv rocksvax }
	rlgvax { adiron allegra brl-bmd cbosgd ccieng5 cvl gatech ihnp4 mcnc
		research seismo sri-unix uf-cgrl umcp-cs we13 }
	rna { allegra cmcl2 esquire n44a }
	rochester { allegra ritcv rocksvax seismo }
	rocks34 { icalqa pur-ee ritcv rocksvax sequel tropix }
	rocksvax { allegra amd70 ritcv ritvp rochester rocks34 sunybcs }
	rocky2 { astrovax cmcl2 }
	root44 { edcaad ukc west44 }
	ru-cc44 { ru-cs44 }
	ru-cs44 { ru-cc44 ukc }
	sara70 { mcvax vu44 }
	sask { alberta cornell dvlcn hssg40 maxvax slinac utah-cs utcsrgv }
	sb1 { allegra bpa burl eagle emory fluke gatech harpo ihnp4 ll1 ll1b
		mb2c msdc purdue research sb6 scbhq uf-cgrl wbux5 }
	sb6 { allegra bpa burl eagle emory fluke gatech harpo ihnp4 ll1 ll1b
		mb2c purdue research sb1 scbhq uf-cgrl wbux5 }
	sbcs { allegra ogcvax philabs uf-cgrl }
	scbhq { allegra ihnp4 sb1 sb6 }
	scgvaxd { allegra trw-unix }
	sco { amd70 microsoft }
	sdcarl { allegra hplabs ihnp4 kpno phonlab pur-ee sdcatta sdcattb
		sdccsu3 sdchema sdcrdcf sdcsla sdcsvax ucbvax ucsfcgl }
	sdcatta { phonlab sdcarl sdcattb sdccsu3 sdchema sdcsvax }
	sdcattb { phonlab sdcarl sdcatta sdccsu3 sdchema sdcsla sdcsvax }
	sdccsu3 { bmcg sdcarl sdcatta sdcattb sdchema sdcrdcf sdcsvax }
	sdchema { basservax decvax phonlab sdcarl sdcatta sdcattb sdccsu3
		sdcsvax }
	sdcrdcf { allegra bmcg burdvax cbosgd hplabs ihnp4 ihnss menlo70
		orstcs phonlab research sdcarl sdccsu3 sdcsvax sytek trw-unix
		trwspf unc }
	sdcsla { phonlab sdcarl sdcattb sdcsvax }
	sdcsvax { allegra bmcg dcdwest ihnp4 kpno noscvax philabs phonlab
		sdcarl sdcatta sdcattb sdccsu3 sdchema sdcrdcf sdcsla ucbvax
		uw-beaver }
	security { cca genrad linus vaxine }
	seismo { hao harpo ihnp4 kpno philabs presby rlgvax rochester uf-cgrl
		umcp-cs utah-cs uwvax }
	sequel { cdi decwrl nsc ogcvax pur-ee rocks34 vax135 }
	sfucmpt { ubc-medgen ubc-vision }
	sii { cfib cornell decvax hei44 ittvax we53 }
	slinac { sask }
	spanky { alfalfa allegra burl eagle hocda houxa houxf houxk houxm
		houxw houxz ihnp4 mhtsa tpsa ulysses }
	sri-unix { allegra amd70 cca csin fortune hplabs menlo70 pur-ee rlgvax
		sun ucbvax vortex }
	ssc-vax { fluke teklabs uvicctr uw-beaver }
	stolaf { allegra harpo ihnp4 umn-cs }
	sun { allegra altos86 amd70 cornell decwrl hpda ihnp4 megatest
		sri-unix sunrise ucbvax }
	sunrise { allegra cmcl2 floyd philabs sun vax135 }
	sunybcs { rocksvax watmath }
	sytek { hplabs menlo70 sdcrdcf syteka zehntel }
	syteka { sytek }
	tekcad { bronze iddic tekchips tekecs tekgds teklabs tektronix }
	tekchips { bronze iddic tekcad tekecs tekgds teklabs tektronix }
	tekecs { bronze iddic tekcad tekchips tekgds tekid teklabs tekmdp
		tektronix }
	tekgds { bronze iddic tekcad tekchips tekecs teklabs tektronix }
	tekid { tekecs tektronix }
	teklabs { allegra arizona bronze cbosg cwruecmp decvax eagle harpo
		iddic ihnp4 ihnss ogcvax orstcs pur-ee ssc-vax tekcad tekchips
		tekecs tekgds tektronix ucbcad ucbvax unc watcgl watmath
		zehntel }
	tekmdp { bronze crimson dadla tekecs tektronix }
	tektronix { allegra bronze decvax iddic ihnp4 masscomp mit-eddie
		ogcvax reed tekcad tekchips tekecs tekgds tekid teklabs tekmdp
		ucbcad ucbvax uf-cgrl uw-beaver zehntel }
	teltone { fluke uw-beaver }
	tesla { cornell }
	tpsa { allegra amd70 spanky }
	trigraph { dciem hcr utcsrgv utzoo }
	tropix { allegra ihnp4 ritcv rocks34 }
	trsvax { amd70 ctvax laidbak microsoft }
	trw-unix { amd70 decvax felix scgvaxd sdcrdcf trwspf trwspp ucbvax }
	trwspf { sdcrdcf trw-unix trwspp }
	trwspp { trw-unix trwspf vortex }
	tty3b { ihnp4 otuxa we13 }
	tucc { duke ecs mcnc unc }
	turtlevax { amd70 atd cdlncch decwrl flairvax }
	twg { amd70 fortune iuvax }
	twin40 { unc-c }
	u1100a { abnjh allegra houxm ihnp4 pyuxi u1100s }
	u1100s { allegra ihnp4 npois u1100a }
	ubc-medgen { sfucmpt ubc-vision }
	ubc-vision { alberta microsoft mprvaxa sfucmpt ubc-medgen utcsrgv
		uvicctr uw-beaver }
	ubvax { megatest }
	ucbcad { allegra masscomp teklabs tektronix ucbesvax ucbvax }
	ucbesvax { ucbcad }
	ucbtopaz { populi ucbvax }
	ucbvax { allegra amd70 arizona atd cbosg decvax decwrl eagle floyd
		hpda hplabs ihnp4 menlo70 mhtsa nbires npois nsc populi pur-ee
		sdcarl sdcsvax sri-unix sun teklabs tektronix trw-unix ucbcad
		ucbtopaz ucsfcgl unmvax uwvax vax135 wheps zehntel }
	ucf-cs { decvax duke fau uf-cgrl uf-che }
	ucsfcgl { allegra hao menlo70 pur-ee sdcarl ucbvax uf-cgrl }
	udrelay { brl-bmd }
	uf-cgrl { allegra amd70 beesvax brunix cwruecmp fluke gatech ios
		ittvax metheus princeton rlgvax sb1 sb6 sbcs seismo tektronix
		ucf-cs ucsfcgl uf-che utah-gr uw-beaver wivax wjh12 yale-comix }
	uf-che { nsc ucf-cs uf-cgrl }
	uicsg { uicsl uiucdcs }
	uicsl { uicsg uiucdcs }
	uiucdcs { ccvaxa ctvax ihnp4 moria parsec philabs pur-ee trsvax uicsg
		uicsl uiucuxc }
	uiuceml { uiucuxc }
	uiucsrl { uiucdcs uiucuxc }
	uiucuxc { harpo uiucdcs uiuceml uiucsrl }
	ukc { comet edcaad hirst1 mcvax regi root44 ru-cs44 vax135 west44 }
	ulysses { alice allegra brunix cbosgd circe eagle gatech harpo ihnp4
		mcnc mhuxa princeton rabbit research spanky unc utah-cs }
	umcp-cs { allegra aplvax brl-bmd cvl rlgvax seismo }
	umn-cs { ihnp4 minn-ua stolaf }
	unc { allegra brl-bmd cornell duke floyd kpno mcnc rabbit sdcrdcf
		teklabs tucc ulysses }
	unc-c { mcnc twin40 }
	unh { decvax }
	uniq { allegra ihnp4 we13 }
	unm-ivax { burl lanl-a nmtvax unmvax }
	unmvax { csu-cs gatech nmtvax parsec research ucbvax unm-ivax }
	uofm-cv { allegra amd70 ihnp4 mb2b mb2c nbires pur-ee }
	ut-ngp { allegra aus86 ctvax eagle gatech ihnp4 nbires utastro vortex }
	utah-cs { arizona beesvax harpo hplabs lanl-a nbires sask seismo
		ulysses utah-gr }
	utah-gr { pwa-b uf-cgrl utah-cs vax135 }
	utastro { kpno ut-ngp }
	utcsrgv { allegra cornell dciem decvax decwrl floyd garfield hcr ihnp4
		linus mhtsa sask trigraph ubc-vision utcsstat utecfa utzoo
		uw-beaver watmath }
	utcsstat { utcsrgv utzoo }
	utecfa { utcsrgv }
	utzoo { allegra cwruecmp dciem decvax duke floyd hcr ihnp4 linus
		research trigraph utcsrgv utcsstat watmath }
	uvacs { allegra ncsu oliveb }
	uvapsy { mcvax }
	uvicctr { ssc-vax ubc-vision uw-beaver }
	uw-beaver { allegra arizona cornell decvax fluke harpo ihnp4 linus
		microsoft reed sdcsvax ssc-vax tektronix teltone ubc-vision
		uf-cgrl utcsrgv uvicctr uw-june uw-vlsi uw70 yale-comix }
	uw-june { uw-beaver uw-vlsi uw70 }
	uw-vlsi { fluke uw-beaver uw-june }
	uw70 { uw-beaver uw-june }
	uwvax { allegra crystal ihnp4 seismo ucbvax }
	varian { amd70 fortune zehntel }
	vax135 { allegra ariel cornell edcaad floyd ihnp4 mhuxi philabs sequel
		sunrise ucbvax ukc utah-gr }
	vaxine { linus security wjh12 }
	vmucnam { mcvax }
	vortex { allegra amd70 decvax felix floyd fortune ihnp4 ima kpno
		sri-unix trwspp ut-ngp }
	vu44 { mcvax sara70 }
	vub { mcvax }
	watarts { watmath }
	watcecit { wateng }
	watcgl { allegra teklabs wateng watmath }
	watdaisy { wateng watmath }
	wateng { allegra watcecit watcgl watdaisy watmath }
	watmath { allegra bunker decvax hcr ihnp4 linus sunybcs teklabs
		utcsrgv utzoo watarts watcgl watdaisy wateng }
	wb2 { allegra eagle houxz ihnp4 wbux5 }
	wbux5 { allegra houxm houxz ihnp4 npois sb1 sb6 wb2 }
	wdl1 { fortune }
	we13 { allegra burl ihnp4 mgweed nwuxd otuxa rlgvax tty3b uniq we53 }
	we53 { allegra ihnp4 kcwin mh3bs otuxa sii we13 }
	west44 { root44 ukc }
	wheps { allegra eagle ihnp4 research ucbvax zeppo }
	whuxk { allegra burl houxm houxz ihnp4 llkp03 zeppo }
	whuxlb { allegra burl eisx floyd gummo ihnp4 pyuxll zeppo }
	wivax { decvax linus uf-cgrl }
	wjh12 { allegra amd70 foxvax1 genrad hscvax ihnp4 ima linus mhtsa
		mhuxi n44a uf-cgrl vaxine }
	wxlvax { ittvax }
	yale-comix { brunix cornell decvax ima ittvax linus uf-cgrl uw-beaver }
	zehntel { allegra amd70 hplabs hplabsb hplabsc ihnp4 sytek teklabs
		tektronix ucbvax varian zinfandel zps }
	zeppo { allegra bunker cornell gummo harpo ihnp4 masscomp wheps whuxk
		whuxlb }
	zinfandel { ihnp4 zehntel }
	zps { zehntel }
	zti1 { mcvax }
Rosebud
echo map/makefile
sed 's/^	//' > map/makefile << 'Rosebud'
	#	Makefile for creating pathfile used by path(1).
	
	host = utcsrgv
	
	usage :
		more README
	
	#	Piping pathfile through "fmt" is optional,
	#	as are the -c and -a options to span.
	pathfile : graphfile
		span -c -a $(host) graphfile | fmt > pathfile
	
	graphfile : more
		awk -f ae.awk graphfile > oldef
		mv graphfile backup
		sort -u more > tmp; mv tmp more
		sort -mu more oldef > newef
		-rm more; touch more
		awk -f ea.awk newef > graphfile
		-rm oldef newef
	
	sites :	graphfile
		awk -f sites.awk graphfile > sites
	
	clean :
		rm -f pathfile sites
Rosebud
echo map/more
sed 's/^	//' > map/more << 'Rosebud'
Rosebud
echo map/oneway
sed 's/^	//' > map/oneway << 'Rosebud'
	alice mhtsa
	allegra harpo
	allegra mhtsa
	australia mhtsa
	basservax mhtsa
	circe harpo
	cmcl2 harpo
	cornell harpo
	cucard harpo
	decvax harpo
	eagle harpo
	eagle mhtsa
	floyd harpo
	fortune harpo
	gummo harpo
	harpo harpo
	hp-pcd harpo
	ihnp4 harpo
	ihuxm harpo
	inmet harpo
	masscomp harpo
	mh3bs mhtsa
	physics mhtsa
	pur-ee harpo
	research mhtsa
	sb1 harpo
	sb6 harpo
	seismo harpo
	spanky mhtsa
	stolaf harpo
	teklabs harpo
	ucbvax mhtsa
	uiucdcs ctvax
	uiucdcs trsvax
	uiucsrl uiucdcs
	uiucuxc harpo
	ulysses harpo
	utah-cs harpo
	utcsrgv mhtsa
	wjh12 mhtsa
	zeppo harpo
Rosebud
echo map/orphans
sed 's/^	//' > map/orphans << 'Rosebud'
	>>> tektinker <<<
	>>> ucbernie <<<
Rosebud
echo map/rev.awk
sed 's/^	//' > map/rev.awk << 'Rosebud'
	{ print $2, $1 }
Rosebud
echo map/sites.awk
sed 's/^	//' > map/sites.awk << 'Rosebud'
	{ if ($2 == "{") print $1 }
Rosebud
echo map/top.awk
sed 's/^	//' > map/top.awk << 'Rosebud'
	$1 > $2
Rosebud
touch map/more
-- 

# UUCP:	{ allegra cornell decvax decwrl floyd ihnp4 linus
# 	  sask ubc-vision utzoo uw-beaver watmath } !utcsrgv!oscar