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 - metrics - download
Index: T U

⟦4b6f305b6⟧ TextFile

    Length: 123665 (0x1e311)
    Types: TextFile
    Notes: Uncompressed file

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦11cb2e5aa⟧ »EurOpenD3/mail/pathalias.shar.Z« 
        └─⟦this⟧ 

TextFile

# To unbundle, sh this file
echo README 1>&2
sed 's/^-//' >README <<'//GO.SYSIN DD README'
-From citi!honey Sun Oct  4 23:30 EDT 1987
-Date: 04 Oct 1987 23:30 EDT
-From: honey@citi.umich.edu
-To: whom it may concern
-Subject: pathalias compilation instructions
-
-edit config.h
-make
-
-if getopt is undefined, obtain a copy from usenet group
-comp.sources.unix and adjust Makefile.
-
-pathalias input is regularly published in usenet group comp.mail.maps.
-
-	peter
-
-ps:  pathalias, written by steve bellovin and peter honeyman, is in the
-     public domain, and may be used by any person or organization, in
-     any way and for any purpose.
-
-pps:  There is no warranty of merchantability nor any warranty of fit-
-      ness for a particular purpose nor any other warranty, either ex-
-      press or implied, as to the accuracy of the enclosed materials or
-      as to their suitability for any particular purpose.  Accordingly,
-      the authors assume no responsibility for their use by the recipi-
-      ent.   Further, the authors assume no obligation to furnish any
-      assistance of any kind whatsoever, or to furnish any additional
-      information or documentation.  This paragraph was copied without
-      permission from an old crypt(1) man page.
//GO.SYSIN DD README
echo CHANGES 1>&2
sed 's/^-//' >CHANGES <<'//GO.SYSIN DD CHANGES'
-Nets without names.
-Allow negative cost components; prohibit negative costs.
-New input syntax: adjust {host, ...}; kill -a option.
-New input syntax: file {filename}.
-New input syntax: delete {host, host!neighbor}.
-Terminal nets.
-Prevent back links to domains.
-
--- mod.sources, 10/87 -- version 9
-Terminal edges and domains (<host> syntax and -D option).
-Dead hosts and edges in the input stream.
-Empty private list ends scope of privates.
-First hop cost in output (-f option).
-Penalize deprecated hosts (-a option).
-
--- mod.sources, 4.3bsd, 1/86 -- version 8
-Improved alias treatment.
-Routes to domain gateways.
-Leading dot in name implies domain.
-Link/host tracing (-t option).
-Use getopt().
-
--- mod.sources, 8/85 -- version 7
-Private hosts documented.
-Homegrown scanner -- it was true what they said about lex.
-Makedb.
-Domains and gateways.
-DEAD back link.
-
--- net.sources, 1/85 -- version 6
-No ! in dbm key.
-Network character must be one of !@%: -- dot is dead.
-Private hosts.
-Discourage hybrid addresses.  
-Magic @ <-> % rule.
-
--- 1983-1984 -- version 5
-Reverse sense of the -c (cost) flag.
-Use cheapest among duplicate links.
-Elide network names in output.
-
--- epoch (smb version) -- versions 1-4
//GO.SYSIN DD CHANGES
echo pathalias.8 1>&2
sed 's/^-//' >pathalias.8 <<'//GO.SYSIN DD pathalias.8'
-.\" @(#)pathalias.8	9.5 88/05/10
-.TH PATHALIAS 8 "5/10/88" "Public Domain"
-.SH NAME
-pathalias, makedb, arpatxt \- mail routing tools
-.SH SYNOPSIS
-.B pathalias
-[
-.B \-ivcDf
-] [
-.BI \-t \0link
-] [
-.BI \-l \0host
-] [
-.BI \-d \0link
-] [
-.ig
-.\" for pathparse.
-.BI \-g \0file
-] [
-..
-.I files ...
-]
-.PP
-.B makedb
-[
-.B \-a
-] [
-.BI \-o \0dbmfile
-] [
-.I files ...
-]
-.PP
-.B arpatxt
-[
-.B \-@fi
-] [
-.BI \-g \0gateway
-] [
-.BI \-p \0privatefile
-] [
-.BI \-d \0directory
-] [
-.I files ...
-]
-.ad b
-.SH DESCRIPTION
-.I Pathalias
-computes the shortest paths and corresponding routes from one host
-(computer system) to all other known, reachable hosts.
-.I Pathalias
-reads host-to-host connectivity
-information on standard input or in the named
-.IR files ,
-and writes a list of
-host-route pairs on the standard output.
-.PP
-Here are the
-.I pathalias
-options:
-.TP 6
-.B \-i
-Ignore case:  map all host names to lower case.
-By default, case is significant.
-.TP
-.B \-c
-Print costs: print the path cost before each host-route pair.
-.TP
-.B \-v
-Verbose: report some statistics on the standard error output.
-.TP
-.B \-D
-Terminal domains: see 
-.I domains 
-section.
-.TP
-.B \-f
-First hop cost: the printed cost is the cost to the first relay in a path,
-instead of the cost of the path itself; implies (and overrides) the
-.B \-c
-option.
-.ig
-.\" the -g option is for pathparse and is not for public consumption (yet!).
-.TP
-.BI \-g \0file
-Dump the edges of the graph into the named file.
-..
-.TP
-.BI \-l \0host
-Set local host name to
-.IR host .
-By default,
-.I pathalias
-discovers the local host name in a system-dependent way.
-.TP
-.BI \-d \0arg
-Declare a dead link, host, or network.
-If
-.I arg
-is of the form ``host-1!host-2,'' the link from host-1 to host-2
-is treated as an extremely high cost (\fIi.e.\fP, \s-1DEAD\s0) link.
-If
-.I arg
-is a single host name,
-that host is treated as dead
-and is used as a relay host of last resort on any path.
-If
-.I arg
-is a network name, the network requires a gateway.
-.TP
-.BI \-t \0arg
-Trace input for link, host or network on the standard error output.
-The form of
-.I arg
-is as above.
-.PP
-.I Makedb
-takes
-.I pathalias
-output and creates or appends to a
-.IR dbm (3)
-database.
-.PP
-Here are the
-.I makedb
-options:
-.TP 6
-.B \-a
-Append to an existing database;
-by default,
-.I makedb
-truncates the database.
-.TP
-.BI \-o \0dbmfile
-Identify the output file base name.
-.PP
-.I Arpatxt
-converts the Internet hosts table
-.I hosts.txt
-into
-.I pathalias
-input.
-.PP
-Here are the
-.I arpatxt
-options:
-.TP 6
-.B \-@
-Generate
-.I pathalias
-input that specifies `@' style addressing.  The default
-is to produce
-.I pathalias
-input that specifies `!' style addressing.
-.TP
-.B \-f
-\&``Filter mode'' \(em write output on stdout.  Normally,
-.I arpatxt
-writes the description of each domain into a separate file.
-.TP
-.B \-i
-Map output to lower case.
-.TP
-.BI \-g \0arg
-Declare a gateway to the Internet or one of its subdomains.  If
-.I arg
-contains one or more dots, the left-hand side component that contains
-no dots is declared a gateway to the domain to the right of the dot.
-Otherwise,
-.I arg
-is declared a gateway to the Internet as a whole.
-.TP
-.BI \-p \0privatefile
-.I Privatefile
-contains a list of host names that conflict with other names.
-.TP
-.BI \-d \0directory
-Write output files in
-.IR directory .
-.SS \fIPathalias\fP Input Format
-A line beginning with white space continues the preceding line.
-Anything following `#' on an input line is ignored.
-.PP
-A list of host-to-host connections consists of a ``from'' host in column 1,
-followed by white space,
-followed by a comma-separated list of ``to' hosts, called
-.IR links .
-A link may be preceded or followed by a network character to use
-in the route.
-Valid network characters are `!' (default), `@', `:', and `%'.
-A link (and network character, if present) may be
-followed by a ``cost'' enclosed in parentheses.
-Costs may be arbitrary
-arithmetic expressions involving numbers, parentheses, `+', `\-', `*',
-and `/'.
-Negative costs are prohibited.
-The following symbolic costs are
-recognized:
-.PP
-.RS
-.nf
-.ta 14mR 17m
-\s-1LOCAL\s0	25	(local-area network connection)
-\s-1DEDICATED\s0	95	(high speed dedicated link)
-\s-1DIRECT\s0	200	(toll-free call)
-\s-1DEMAND\s0	300	(long-distance call)
-\s-1HOURLY\s0	500	(hourly poll)
-\s-1EVENING\s0	1800	(time restricted call)
-\s-1DAILY\s0	5000	(daily poll, also called \s-1POLLED\s0)
-\s-1WEEKLY\s0	30000	(irregular poll)
-.fi
-.RE
-.PP
-In addition,
-.SM DEAD
-is a very large number (effectively infinite),
-.SM HIGH
-and
-.SM LOW
-are \-5 and +5 respectively,
-for baud-rate or quality bonuses/penalties,
-and
-.SM FAST
-is \-80, for adjusting costs of links that use high-speed (9.6 Kbaud or more) modems.
-These symbolic costs represent an imperfect measure of bandwidth,
-monetary cost, and frequency of connections.
-For most mail traffic, it is important to minimize the number
-of hosts in a route,
-thus,
-.IR e.g. ,
-.SM HOURLY
-\&* 24
-is much larger than
-.SM DAILY.
-If no cost is given,
-a default of 4000 is used.
-.PP
-For the most part, arithmetic expressions that mix symbolic constants
-other than
-.SM HIGH,
-.SM LOW,
-and
-.SM FAST
-make no sense.
-.IR E.g. ,
-if a host calls a local neighbor whenever there is work,
-and additionally polls every evening,
-the cost is
-.SM DIRECT,
-.B not
-.SM DIRECT+EVENING.
-.PP
-Some examples:
-.PP
-.RS
-.nf
-.ta 10m 15m
-down	princeton!(\s-1DEDICATED\s0), tilt,
-	%thrash(\s-1LOCAL\s0)
-princeton	topaz!(\s-1DEMAND\s0+\s-1LOW\s0)
-topaz	@rutgers(\s-1LOCAL\s0+1)
-.fi
-.RE
-.PP
-If a link is encountered more than once,
-the least-cost occurrence dictates the cost and network character.
-Links are treated as bidirectional but asymmetric:
-for each link declared in the input, a
-.SM DEAD
-reverse link is assumed.
-.PP
-If the ``to'' host in a link is surrounded by angle brackets,
-the link is considered
-.IR terminal ,
-and
-further links beyond this one are heavily penalized.
-.IR E.g. ,
-with input
-.PP
-.RS
-.nf
-.ta 10m 15m
-seismo	<research>(10), research(100), ihnp4(10)
-research	allegra(10)
-ihnp4	allegra(50)
-.fi
-.RE
-.PP
-the path from seismo to research is direct, but the path from seismo
-to allegra
-uses ihnp4 as a relay, not research.
-.PP
-The set of names by which a host is known to its neighbors is
-called its
-.IR aliases .
-Aliases are declared as follows:
-.PP
-.RS
-name = alias, alias ...
-.RE
-.PP
-The name used in the route to or through aliased hosts
-is the name by which the host is known
-to its predecessor in the route.
-.PP
-Fully connected networks, such as the
-.SM ARPANET
-or a local-area network,
-are declared as follows:
-.PP
-.RS
-net = {host, host, ...}
-.RE
-.PP
-The host-list may be preceded or followed by a routing
-character (`!' default), and may be followed by a cost (default 4000).
-The network name is optional; if not given,
-.I pathalias
-makes one up.
-.PP
-.RS
-.nf
-etherhosts = {rahway, milan, joliet}!(\s-1LOCAL\s0)
-ringhosts = @{gimli, alida, almo}(\s-1DEDICATED\s0)
-= {etherhosts, ringhosts}(0)
-.fi
-.RE
-.PP
-The routing character used in a route to a network member is the one
-encountered when ``entering'' the network.
-See also the sections on
-.I gateways
-and
-.I domains .
-.PP
-Connection data may be given while hiding host names
-by declaring
-.PP
-.RS
-private {host, host, ...}
-.RE
-.PP
-.I Pathalias
-will not generate routes for private hosts, but may produce routes
-through them.
-The scope of a private declaration extends from the declaration to the end of
-the input file in which it appears, or to a private declaration with an empty
-host list, whichever comes first.
-The latter scope rule offers a way to retain the
-semantics of private declarations when
-reading from the standard input.
-.PP
-Dead hosts, links, or networks may be presented in the input stream by declaring
-.PP
-.RS
-dead {arg, ...}
-.RE
-.PP
-where
-.I arg
-has the same form as the argument to the
-.B \-d
-option.
-.PP
-To force a specific cost for a link, delete all prior declarations with
-.PP
-.RS
-delete {host-1!host-2}
-.RE
-.PP
-and declare the link as desired.
-To delete a host and all its links, use
-.PP
-.RS
-delete {host}
-.RE
-.PP
-Error diagnostics refer to the file in which the error was found.
-To alter the file name, use
-.PP
-.RS
-file {filename}
-.RE
-.PP
-Fine-tuning is possible by adjusting the weights
-of all links from a given host, as in
-.PP
-.RS
-adjust {host-1, host-2(LOW), host-3(\-1)}
-.RE
-.PP
-If no cost is given a default of 4000 is used.
-.PP
-Input from compressed (and uncompressed) files can be
-piped into 
-.I pathalias
-with the following script.
-.PP
-.RS
-.nf
-for i in $*; do
-	case $i in
-	*.Z)	echo "file {`expr $i : '\(.*\).Z'`}
-		zcat $i ;;
-	*)	echo "file {$i}"
-		cat $i ;;
-	esac
-	echo "private {}"
-done
-.fi
-.RE
-.PP
-.SS Output Format
-A list of host-route pairs is written to the standard output,
-where route is a string appropriate for use with
-.IR printf (3),
-.IR e.g. ,
-.PP
-.RS
-.nf
-.ta 10m 20m
-rutgers	princeton!topaz!%s@rutgers
-.fi
-.RE
-.PP
-The ``%s'' in the route string should be replaced by the
-user name at the destination host.
-(This task is normally performed by a mailer.)
-.PP
-Except for
-.IR domains ,
-the name of a network is never used in
-routes.
-Thus, in the earlier example, the path from down to
-up would be ``up!%s,'' not ``princeton-ethernet!up!%s.''
-.SS Gateways
-A network is represented by
-a pseudo-host and a set of network members.
-Links from the members to the network have the weight given in
-the input, while the cost from the network to the members is zero.
-If a network is declared dead,
-the member-to-network links are marked dead,
-which effectively prohibits access to the network
-from its members.
-.PP
-However, if the input also shows an explicit link from any host to the network,
-then that host can be used as a gateway.
-(In particular, the gateway need not be a network member.)
-.PP
-.IR E.g. ,
-if
-.SM CSNET
-is declared dead
-and the input contains
-.PP
-.RS
-.nf
-.ta 10m 20m
-\s-1CSNET\s0 = {...}
-csnet-relay	\s-1CSNET\s0
-.fi
-.RE
-.PP
-then routes to
-.SM CSNET
-hosts will use csnet-relay as a gateway.
-.SS Domains
-A network whose name begins with `.' is called
-a domain.
-Domains are presumed to require gateways,
-.IR i.e. ,
-they are \s-1DEAD\s0.
-The route given by a path through a domain is similar to
-that for a network, but here
-the domain name is tacked onto the end of the next host.
-Subdomains are permitted.
-.PP
-.IR E.g. ,
-.PP
-.RS
-.nf
-.ta 1i
-.ta 10m 20m 30m
-harvard	.\s-1EDU\s0	# harvard is gateway to .EDU domain
-\&.\s-1EDU\s0	= {.\s-1BERKELEY\s0, .\s-1UMICH\s0}
-\&.\s-1BERKELEY\s0	= {ernie}
-.fi
-.RE
-.PP
-yields
-.PP
-.RS
-.nf
-.ta 10m 20m
-ernie	...!harvard!ernie.\s-1BERKELEY\s0.\s-1EDU\s0!%s
-.fi
-.RE
-.PP
-Output is given for the nearest gateway
-to a domain,
-.IR e.g. ,
-the example above gives
-.PP
-.RS
-.nf
-.ta 10m 25m
-\&.\s-1EDU\s0	...!harvard!%s
-.fi
-.RE
-.PP
-Output is given for a subdomain if it has a different
-route than its parent domain, or if all its ancestor domains are private.
-.PP
-If the
-.B \-D
-option is given on the command line,
-.I pathalias
-treats a link from a domain to a host member of that domain as terminal.
-This property extends to host members of subdomains,
-.IR etc ,
-and discourages
-routes that use any domain member as a relay.
-.SS Databases
-.I Makedb
-builds a
-.IR dbm (3)
-database from the standard input or from the named
-.IR files .
-Input is expected to be sequence of
-.SM ASCII
-records,
-each consisting of a key field and a data field separated by a single tab.
-If the tab is missing, the data field is assumed to be empty.
-.SH FILES ET AL.
-.ta \w'/usr/local/lib/palias.{dir,pag}     'u
-/usr/local/lib/palias.{dir,pag}	default dbm output
-.br
-newsgroup comp.mail.maps	likely location of some input files
-.br
-.IR getopt (3),
-available from comp.sources.unix archives (if not in the C library).
-.SH BUGS
-The
-.B \-i
-option should be the default.
-.PP
-The order of arguments is significant.
-In particular,
-.B \-i
-and
-.B \-t
-should appear early.
-.PP
-.I Pathalias
-can generate hybrid (\fIi.e.\fP ambiguous) routes, which are
-abhorrent and most certainly should not be given as examples
-in the manual entry.
-Experienced mappers largely shun `@' when preparing input; this
-is historical, but also reflects \s-1UUCP\s0's
-facile syntax for source routes.
-.PP
-Multiple `@'s in routes are loathsome, so
-.I pathalias
-resorts to the ``magic %'' rule when necessary.
-This convention is not documented anywhere, including here.
-.PP
-The
-.B \-D
-option elides insignificant routes to domain members.
-This is benign, perhaps even beneficial, but confusing, since the
-behavior is undocumented and somewhat unpredictable.
-.SH SEE ALSO
-P. Honeyman and S.M. Bellovin, ``\s-1PATHALIAS\s0 \fIor\fP The Care and Feeding
-of Relative Addresses,''
-in \fIProc. Summer \s-1USENIX\s0 Conf.\fP, Atlanta, 1986.
//GO.SYSIN DD pathalias.8
echo Makefile 1>&2
sed 's/^-//' >Makefile <<'//GO.SYSIN DD Makefile'
-#!/bin/make -f
-# pathalias -- by steve bellovin, as told to peter honeyman
-
-### begin configuration section
-###
-# if you can't or don't intend to use dbm files,
-# don't bother with DBM or makedb
-DBM = -ldbm
-# or if you roll your own ...
-# DBM = dbm.o
-###
-# where is getopt (if not in the c library)?
-# GETOPT = getopt.o
-### end of configuration section 
-
-
-CC = cc
-CFLAGS = -O
-LDFLAGS = -s $(GETOPT)
-YFLAGS = -d
-
-OBJ = addlink.o addnode.o local.o main.o mapit.o mapaux.o mem.o parse.o printit.o
-HDRS = def.h config.h
-CSRC = addlink.c addnode.c local.c main.c mapit.c mapaux.c mem.c printit.c
-LSRC = $(CSRC) parse.c
-SRC = $(CSRC) parse.y makedb.c arpatxt.c
-
-pathalias: $(OBJ)
-	$(CC) $(OBJ) $(LDFLAGS) -o pathalias
-
-all: pathalias makedb arpatxt
-
-$(OBJ):	$(HDRS)
-
-parse.c: parse.y $(HDRS)
-	$(YACC) $(YFLAGS) parse.y
-	mv y.tab.c parse.c
-
-makedb: makedb.o
-	$(CC) makedb.o $(LDFLAGS) $(DBM) -o makedb
-
-makedb.o: config.h
-
-arpatxt: arpatxt.o
-	$(CC) arpatxt.o $(LDFLAGS) -o arpatxt
-
-clean:
-	rm -f *.o y.tab.? parse.c
-
-clobber: clean
-	rm -f pathalias makedb arpatxt
-
-tags: $(SRC) $(HDRS)
-	ctags -w $(HDRS) $(SRC)
-
-bundle:
-	@bundle README CHANGES pathalias.1 Makefile ${HDRS} ${SRC}
-
-lint:	$(LSRC)
-	lint $(CFLAGS) $(LSRC)
-	lint makedb.c
-	lint arpatxt.c
-
-install:
-	@echo "install pathalias, makedb, arpatxt, and pathalias.1"
-	@echo "according to local conventions"
//GO.SYSIN DD Makefile
echo def.h 1>&2
sed 's/^-//' >def.h <<'//GO.SYSIN DD def.h'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-
-#ifndef lint
-#ifdef MAIN
-static char	*h_sccsid = "@(#)def.h	9.5 88/05/09";
-#endif /*MAIN*/
-#endif /*lint*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include "config.h"
-
-typedef	long Cost;
-typedef struct node node;
-typedef struct link link;
-
-#ifdef lint
-#define vprintf fprintf
-#else /*!lint -- this gives null effect warning*/
-/* because it's there ... */
-#define vprintf		!Vflag ? 0 : fprintf
-#endif /*lint*/
-
-#define NTRACE	16	/* can trace up to NTRACE hosts/links */
-
-/* flags for n_flag */
-#define ISPRIVATE  0x0001 /* invisible outside its definition file */
-#define NALIAS	   0x0002 /* heaped as an alias */
-#define ATSIGN	   0x0004 /* seen an at sign?  used for magic @/% rules */
-#define MAPPED	   0x0008 /* extracted from heap */
-#define	NDEAD	   0x0010 /* out links are dead */
-#define HASLEFT	   0x0020 /* has a left side net character */
-#define HASRIGHT   0x0040 /* route has a right side net character */
-#define	NNET	   0x0080 /* network pseudo-host */
-#define INDFS	   0x0100 /* used when removing net cycles (for -g) */
-#define DUMP	   0x0200 /* we have dumped this net's edges (for -g) */
-#define PRINTED	   0x0400 /* this host has been printed */
-#define NTERMINAL  0x0800 /* heaped as terminal edge (or alias thereto) */
-#define NREF	   0x1000 /* node has an "interesting" reference */
-
-#define ISADOMAIN(n)	 ((n)->n_name[0] == '.')
-#define ISANET(n)	 (((n)->n_flag & NNET) || ISADOMAIN(n))
-#define ALTEREGO(n1, n2) ((n1)->n_name == (n2)->n_name)
-#define DEADHOST(n)	 (((n)->n_flag & (NDEAD | NTERMINAL)) && !ISANET(n))
-#define DEADLINK(l)	 ((l)->l_flag & LDEAD)
-#define DEADNET(n)	 (((n)->n_flag & (NNET | NDEAD)) == (NNET | NDEAD))
-#define GATEWAYED(n)	 (DEADNET(n) || ISADOMAIN(n))
-
-#ifndef DEBUG
-/*
- * save some space in nodes -- there are > 10,000 allocated!
- */
-
-#define n_root un1.nu_root
-#define n_net un1.nu_net
-#define n_copy un1.nu_copy
-
-#define n_private un2.nu_priv
-#define n_parent  un2.nu_par
-
-/* WARNING: if > 2^16 nodes, type of n_tloc must change */
-struct node {
-	char	*n_name;	/* host name */
-	link	*n_link;	/* adjacency list */
-	Cost	n_cost;		/* cost to this host */
-	union {
-		node *nu_net;	/* others in this network (parsing) */
-		node *nu_root;	/* root of net cycle (graph dumping) */
-		node *nu_copy;	/* circular copy list (mapping) */
-	} un1;
-	union {
-		node *nu_priv;	/* other privates in this file (parsing) */
-		node *nu_par;	/* parent in shortest path tree (mapping) */
-	} un2;
-	unsigned short n_tloc;	/* back ptr to heap/hash table */
-	unsigned short n_flag;		/* see manifests above */
-};
-
-#endif /*DEBUG*/
-
-#define MILLION (1000L * 1000L)
-#define	DEFNET	'!'			/* default network operator */
-#define	DEFDIR	LLEFT			/* host on left is default */
-#define	DEFCOST	((Cost) 4000)		/* default cost of a link */
-#define	INF	((Cost) 100 * MILLION)	/* infinitely expensive link */
-#define DEFPENALTY ((Cost) 200)		/* default avoidance cost */
-
-/* data structure for adjacency list representation */
-
-/* flags for l_dir */
-
-#define NETDIR(l)	((l)->l_flag & LDIR)
-#define NETCHAR(l)	((l)->l_netop)
-
-#define LDIR	  0x0008	/* 0 for left, 1 for right */
-#define LRIGHT	  0x0000	/* user@host style */
-#define LLEFT	  0x0008	/* host!user style */
-
-#define LDEAD	  0x0010	/* this link is dead */
-#define LALIAS	  0x0020	/* this link is an alias */
-#define LTREE	  0x0040	/* member of shortest path tree */
-#define LGATEWAY  0x0080	/* this link is a gateway */
-#define LTERMINAL 0x0100	/* this link is terminal */
-
-#ifndef DEBUG
-/*
- * borrow a field for link/node tracing.  there's a shitload of
- * edges -- every word counts.  only so much squishing is possible:
- * alignment dictates that the size be a multiple of four.
- */
-
-#define l_next un.lu_next
-#define l_from un.lu_from
-
-struct link {
-	node	*l_to;		/* adjacent node */
-	Cost	l_cost;		/* edge cost */
-	union {
-		link *lu_next;	/* rest of adjacency list (not tracing) */
-		node *lu_from;	/* source node (tracing) */
-	} un;
-	short	l_flag;		/* right/left syntax, flags */
-	char	l_netop;	/* network operator */
-};
-
-#endif /*DEBUG*/
-
-#ifdef DEBUG
-/*
- * flattening out the unions makes it easier
- * to debug (when pi is unavailable).
- */
-struct node {
-	char	*n_name;
-	link	*n_link;
-	Cost	n_cost;
-	node	*n_net;
-	node	*n_root;
-	node	*n_copy;
-	node	*n_private;
-	node	*n_parent;
-	unsigned short n_tloc;
-	unsigned short n_flag;
-};
-struct link {
-	node	*l_to;
-	Cost	l_cost;
-	link	*l_next;
-	node	*l_from;
-	short	l_flag;
-	char	l_netop;
-};
-#endif /*DEBUG*/
//GO.SYSIN DD def.h
echo config.h 1>&2
sed 's/^-//' >config.h <<'//GO.SYSIN DD config.h'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-
-/**************************************************************************
- * +--------------------------------------------------------------------+ *
- * |                    begin configuration section                     | *
- * +--------------------------------------------------------------------+ *
- **************************************************************************/
-
-#undef STRCHR		/* have strchr -- system v and many others */
-
-#undef UNAME		/* have uname() -- probably system v or 8th ed. */
-#undef MEMSET		/* have memset() -- probably system v or 8th ed. */
-
-#define GETHOSTNAME	/* have gethostname() -- probably bsd */
-#define BZERO		/* have bzero() -- probably bsd */
-
-/* default place for dbm output of makedb (or use -o at run-time) */
-#define	ALIASDB	"/usr/local/lib/palias"
-
-/**************************************************************************
- * +--------------------------------------------------------------------+ *
- * |                    end of configuration section                    | *
- * +--------------------------------------------------------------------+ *
- **************************************************************************/
-
-
-
-#ifdef MAIN
-#ifndef lint
-static char	*c_sccsid = "@(#)config.h	9.2 89/03/03";
-#endif /*lint*/
-#endif /*MAIN*/
-
-/*
- * malloc/free fine tuned for pathalias.
- *
- * MYMALLOC should work everwhere, so it's not a configuration
- * option (anymore).  nonetheless, if you're getting strange
- * core dumps (or panics!), comment out the following manifest,
- * and use the inferior C library malloc/free.
- */
-#define MYMALLOC	/**/
-
-#ifdef MYMALLOC
-#define malloc mymalloc
-#define calloc(n, s) malloc ((n)*(s))
-#define free(s)
-#define cfree(s)
-extern char *memget();
-#else /* !MYMALLOC */
-extern char *calloc();
-#endif /* MYMALLOC */
-
-#ifdef STRCHR
-#define index strchr
-#define rindex strrchr
-#else
-#define strchr index
-#define strrchr rindex
-#endif
-
-#ifdef BZERO
-#define strclear(s, n)	((void) bzero((s), (n)))
-#else /*!BZERO*/
-
-#ifdef MEMSET
-extern char	*memset();
-#define strclear(s, n)	((void) memset((s), 0, (n)))
-#else /*!MEMSET*/
-extern void	strclear();
-#endif /*MEMSET*/
-
-#endif /*BZERO*/
-
-extern char	*malloc();
-extern char	*strcpy(), *index(), *rindex();
-
-#ifndef STATIC
-
-#ifdef DEBUG
-#define STATIC extern
-#else /*DEBUG*/
-#define STATIC static
-#endif /*DEBUG*/
-
-#endif /*STATIC*/
//GO.SYSIN DD config.h
echo addlink.c 1>&2
sed 's/^-//' >addlink.c <<'//GO.SYSIN DD addlink.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)addlink.c	9.7 88/06/10";
-#endif /* lint */
-
-#include "def.h"
-
-/* exports */
-extern link *addlink();
-extern void deadlink(), atrace(), freelink();
-extern int tracelink(), maptrace();
-char *Netchars = "!:@%";	/* sparse, but sufficient */
-long Lcount;			/* how many edges? */
-
-/* imports */
-extern int Tflag, Dflag;
-extern link *newlink();
-extern node *addnode();
-extern void yyerror(), die();
-extern int strcmp(), strlen();
-
-/* privates */
-STATIC void netbits(), ltrace(), ltrprint();
-static link	*Trace[NTRACE];
-static int	Tracecount;
-
-#define EQ(n1, n2)	(strcmp((n1)->n_name, (n2)->n_name) == 0)
-#define LTRACE		if (Tflag) ltrace
-
-link *
-addlink(from, to, cost, netchar, netdir)
-	node *from;
-	register node *to;
-	Cost cost;
-	char netchar, netdir;
-{	register link *l, *prev = 0;
-
-	LTRACE(from, to, cost, netchar, netdir, "");
-	/*
-	 * maintain uniqueness for dead links (only).
-	 */
-	for (l = from->n_link; l; l = l->l_next) {
-		if (!DEADLINK(l))
-			break;
-		if (to == l->l_to) {
-			/* what the hell, use cheaper dead 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;
-	/* add penalty */
-	if ((l->l_cost = cost + from->n_cost) < 0) {
-		char buf[100];
-
-		l->l_flag |= LDEAD;
-		sprintf(buf, "link to %s ignored with negative cost", to->n_name);
-		yyerror(buf);
-	}
-	if (netchar == 0) {
-		netchar = DEFNET;
-		netdir = DEFDIR;
-	}
-	netbits(l, netchar, netdir);
-	if (Dflag && ISADOMAIN(from))
-		l->l_flag |= LTERMINAL;
-
-	return l;
-}
-
-void
-deadlink(nleft, nright) 
-	node *nleft, *nright;
-{	link *l, *lhold = 0, *lprev, *lnext;
-
-	/* DEAD host */
-	if (nright == 0) {
-		nleft->n_flag |= NDEAD;		/* DEAD host */
-		return;
-	}
-
-	/* DEAD link */
-
-	/* grab <nleft, nright> instances at head of nleft adjacency list */
-	while ((l = nleft->n_link) != 0 && l->l_to == nright) {
-		nleft->n_link = l->l_next;	/* disconnect */
-		l->l_next = lhold;		/* terminate */
-		lhold = l;			/* add to lhold */
-	}
-
-	/* move remaining <nleft, nright> instances */
-	for (lprev = nleft->n_link; lprev && lprev->l_next; lprev = lprev->l_next) {
-		if (lprev->l_next->l_to == nright) {
-			l = lprev->l_next;
-			lprev->l_next = l->l_next;	/* disconnect */
-			l->l_next = lhold;		/* terminate */
-			lhold = l;
-		}
-	}
-
-	/* check for emptiness */
-	if (lhold == 0) {
-		addlink(nleft, nright, INF / 2, DEFNET, DEFDIR)->l_flag |= LDEAD;
-		return;
-	}
-
-	/* reinsert deleted edges as DEAD links */
-	for (l = lhold; l; l = lnext) {
-		lnext = l->l_next;
-		addlink(nleft, nright, l->l_cost, NETCHAR(l), NETDIR(l))->l_flag |= LDEAD;
-		freelink(l);
-	}
-}
-
-STATIC void
-netbits(l, netchar, netdir)
-	register link *l;
-	char netchar, netdir;
-{
-	l->l_flag &= ~LDIR;
-	l->l_flag |= netdir;
-	l->l_netop = netchar;
-}
-
-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 = addnode(arg);
-	Trace[Tracecount++] = l;
-	return 0;
-}
-
-/*
- * the obvious choice for testing equality is to compare struct
- * addresses, but that misses private nodes, so we use strcmp().
- */
-
-STATIC void
-ltrace(from, to, cost, netchar, netdir, message)
-	node *from, *to;
-	Cost cost;
-	char netchar, netdir, *message;
-{	link *l;
-	int i;
-
-	for (i = 0; i < Tracecount; i++) {
-		l = Trace[i];
-		/* overkill, but you asked for it! */
-		if (l->l_to == 0) {
-			if (EQ(from, l->l_from) || EQ(to, l->l_from))
-				break;
-		} else if (EQ(from, l->l_from) && EQ(to, l->l_to))
-			break;
-		else if (EQ(from, l->l_to) && EQ(to, l->l_from))
-			break;	/* potential dead backlink */
-	}
-	if (i < Tracecount)
-		ltrprint(from, to, cost, netchar, netdir, message);
-}
-
-/* print a trace item */
-STATIC void
-ltrprint(from, to, cost, netchar, netdir, message)
-	node *from, *to;
-	Cost cost;
-	char netchar, netdir, *message;
-{	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) %s", cost, message);
-	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;
-		}
-	}
-}
-
-int
-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 (EQ(from, l->l_from) || EQ(to, l->l_from))
-				return 1;
-		} else if (EQ(from, l->l_from) && EQ(to, l->l_to))
-				return 1;
-	}
-	return 0;
-}
-
-void
-deletelink(from, to)
-	node *from;
-	node *to;
-{	register link *l, *lnext;
-
-	l = from->n_link;
-
-	/* delete all neighbors of from */
-	if (to == 0) {
-		while (l) {
-			LTRACE(from, l->l_to, l->l_cost, NETCHAR(l), NETDIR(l), "DELETED");
-			lnext = l->l_next;
-			freelink(l);
-			l = lnext;
-		}
-		from->n_link = 0;
-		return;
-	}
-
-	/* delete from head of list */
-	while (l && EQ(to, l->l_to)) {
-		LTRACE(from, to, l->l_cost, NETCHAR(l), NETDIR(l), "DELETED");
-		lnext = l->l_next;
-		freelink(l);
-		l = from->n_link = lnext;
-	}
-
-	/* delete from interior of list */
-	if (l == 0)
-		return;
-	for (lnext = l->l_next; lnext; lnext = l->l_next) {
-		if (EQ(to, lnext->l_to)) {
-			LTRACE(from, to, l->l_cost, NETCHAR(l), NETDIR(l), "DELETED");
-			l->l_next = lnext->l_next;
-			freelink(lnext);
-			/* continue processing this link */
-		} else
-			l = lnext;	/* next link */
-	}
-}
//GO.SYSIN DD addlink.c
echo addnode.c 1>&2
sed 's/^-//' >addnode.c <<'//GO.SYSIN DD addnode.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)addnode.c	9.6 89/05/05";
-#endif
-
-#include "def.h"
-
-#define EQ(n, s)	(*(n)->n_name == *(s) && strcmp((n)->n_name, (s)) == 0)
-
-/* exports */
-node *addnode(), *addprivate();
-void alias(), hashanalyze(), fixprivate();
-node **Table;				/* hash table ^ priority queue */
-long Tabsize;				/* size of Table */	
-
-/* imports */
-extern link *addlink();
-extern node *newnode(), **newtable();
-extern char *strsave();
-extern int Iflag, Tflag, Vflag;
-extern node **Table;
-extern long Ncount, Tabsize;
-extern char **Argv;
-extern void atrace(), die(), freetable();
-extern int strcmp();
-
-/* privates */
-STATIC void crcinit(), rehash(), lowercase();
-STATIC long fold();
-STATIC long hash();
-STATIC node *isprivate();
-static node *Private;	/* list of private nodes in current input file */
-/*
- * these numbers are chosen because:
- *	-> they are prime,
- *	-> they are monotonic increasing,
- *	-> each is a tad smaller than a multiple of 1024,
- *	-> they form a fibonacci sequence (almost).
- * the first point yields good hash functions, the second is used for the
- * standard re-hashing implementation of open addressing, the third
- * optimizes for quirks in some mallocs i have seen, and the fourth simply
- * appeals to me.
- */
-static long Primes[] = {
-	1021, 2039, 3067, 5113, 8179, 13309, 21499, 34807, 56311, 0
-};
-
-static int	Tabindex;
-static long	Tab128;		/* Tabsize * 128 */
-
-node	*
-addnode(name)
-	register char *name;
-{	register long i;
-	register node *n;
-
-	if (Iflag)
-		lowercase(name);
-
-	/* is it a private host? */
-	n = isprivate(name);
-	if (n)
-		return n;
-
-	i = hash(name, 0);
-	if (Table[i]) 
-		return Table[i];
-
-	n = newnode();
-	n->n_name = strsave(name);
-	Table[i] = n;
-	n->n_tloc = i;	/* essentially a back link to the table */
-
-	return n;
-}
-
-void
-alias(n1, n2)
-	node *n1, *n2;
-{
-	link	*l;
-
-	if (ISADOMAIN(n1) && ISADOMAIN(n2)) {
-		fprintf(stderr, "%s: domain alias %s = %s is illegal\n", Argv[0], n1->n_name, n2->n_name);
-		return;
-	}
-	l = addlink(n1, n2, (Cost) 0, DEFNET, DEFDIR);
-	l->l_flag |= LALIAS;
-	l = addlink(n2, n1, (Cost) 0, DEFNET, DEFDIR);
-	l->l_flag |= LALIAS;
-	if (Tflag)
-		atrace(n1, n2);
-}
-
-/*
- * fold a string into a long int.  31 bit crc (from andrew appel).
- * the crc table is computed at run time by crcinit() -- we could
- * precompute, but it takes 1 clock tick on a 750.
- *
- * This fast table calculation works only if POLY is a prime polynomial
- * in the field of integers modulo 2.  Since the coefficients of a
- * 32-bit polynomail won't fit in a 32-bit word, the high-order bit is
- * implicit.  IT MUST ALSO BE THE CASE that the coefficients of orders
- * 31 down to 25 are zero.  Happily, we have candidates, from
- * E. J.  Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962):
- *	x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0
- *	x^31 + x^3 + x^0
- *
- * We reverse the bits to get:
- *	111101010000000000000000000000001 but drop the last 1
- *         f   5   0   0   0   0   0   0
- *	010010000000000000000000000000001 ditto, for 31-bit crc
- *	   4   8   0   0   0   0   0   0
- */
-
-#define POLY32 0xf5000000	/* 32-bit polynomial */
-#define POLY31 0x48000000	/* 31-bit polynomial */
-#define POLY POLY31	/* use 31-bit to avoid sign problems */
-
-static long CrcTable[128];
-
-STATIC void
-crcinit()
-{	register int i,j;
-	register long sum;
-
-	for (i = 0; i < 128; i++) {
-		sum = 0;
-		for (j = 7-1; j >= 0; --j)
-			if (i & (1 << j))
-				sum ^= POLY >> j;
-		CrcTable[i] = sum;
-	}
-}
-
-STATIC long
-fold(s)
-	register char *s;
-{	register long sum = 0;
-	register int c;
-
-	while ((c = *s++) != 0)
-		sum = (sum >> 7) ^ CrcTable[(sum ^ c) & 0x7f];
-	return sum;
-}
-
-
-#define HASH1(n) ((n) % Tabsize);
-#define HASH2(n) (Tabsize - 2 - ((n) % (Tabsize-2)))	/* sedgewick */
-
-/*
- * when alpha is 0.79, there should be 2 probes per access (gonnet).
- * use long constant to force promotion.  Tab128 biases HIGHWATER by
- * 128/100 for reduction in strength in isfull().
- */
-#define HIGHWATER	79L
-#define isfull(n)	((n) * 128 >= Tab128)
-	
-STATIC long
-hash(name, unique)
-	char *name;
-	int unique;
-{	register long probe;
-	register long hash2;
-	register node *n;
-
-	if (isfull(Ncount)) {
-		if (Tabsize == 0) {		/* first time */
-			crcinit();
-			Tabindex = 0;
-			Tabsize = Primes[0];
-			Table = newtable(Tabsize);
-			Tab128 = (HIGHWATER * Tabsize * 128L)/100L;
-		} else
-			rehash();		/* more, more! */
-	}
-
-	probe = fold(name);
-	hash2 = HASH2(probe);
-	probe = HASH1(probe);
-
-	/*
-	 * probe the hash table.
-	 * if unique is set, we require a fresh slot.
-	 * otherwise, use double hashing to find either
-	 *  (1) an empty slot, or
-	 *  (2) a non-private copy of this host name
-	 *
-	 * this is an "inner loop."
-	 */
-	while ((n = Table[probe]) != 0) {
-		if (EQ(n, name) && !(n->n_flag & ISPRIVATE) && !unique)
-			return probe;	/* this is it! */
-
-		probe -= hash2;		/* double hashing */
-		if (probe < 0)
-			probe += Tabsize;
-	}
-	return probe;					/* brand new */
-}
-
-STATIC void
-rehash()
-{	register node **otable, **optr;
-	register long probe;
-	long osize;
-
-#ifdef DEBUG
-	hashanalyze();
-#endif
-	optr = Table + Tabsize - 1;	/* ptr to last */
-	otable = Table;
-	osize = Tabsize;
-	Tabsize = Primes[++Tabindex];
-	if (Tabsize == 0)
-		die("too many hosts");	/* need more prime numbers */
-	vprintf(stderr, "rehash into %d\n", Tabsize);
-	Table = newtable(Tabsize);
-	Tab128 = (HIGHWATER * Tabsize * 128L)/100L;
-
-	do {
-		if (*optr == 0)
-			continue;	/* empty slot in old table */
-		probe = hash((*optr)->n_name,
-			((*optr)->n_flag & ISPRIVATE) != 0);
-		if (Table[probe] != 0)
-			die("rehash error");
-		Table[probe] = *optr;
-		(*optr)->n_tloc = probe;
-	} while (optr-- > otable);
-	freetable(otable, osize);
-}
-
-void
-hashanalyze()
-#if 0
-{ 	long	probe, hash2;
-	int	count, i, collision[8];
-	int	longest = 0, total = 0, slots = 0, longprobe = 0;
-	int	nslots = sizeof(collision)/sizeof(collision[0]);
-
-	if (!Vflag)
-		return;
-
-	strclear((char *) collision, sizeof(collision));
-	for (i = 0; i < Tabsize; i++) {
-		if (Table[i] == 0)
-			continue;
-		/* private hosts too hard to account for ... */
-		if (Table[i]->n_flag & ISPRIVATE)
-			continue;
-		count = 1;
-		probe = fold(Table[i]->n_name);
-		/* don't change the order of the next two lines */
-		hash2 = HASH2(probe);
-		probe = HASH1(probe);
-		/* thank you! */
-		while (Table[probe] != 0
-		    && strcmp(Table[probe]->n_name, Table[i]->n_name) != 0) {
-			count++;
-			probe -= hash2;
-			if (probe < 0)
-				probe += Tabsize;
-		}
-		if (Table[probe] == 0)
-			die("impossible hash error");
-		
-		total += count;
-		slots++;
-		if (count > longest) {
-			longest = count;
-			longprobe = i;
-		}
-		if (count >= nslots)
-			count = 0;
-		collision[count]++;
-	}
-	for (i = 1; i < nslots; i++)
-		if (collision[i])
-			fprintf(stderr, "%d chains: %d (%ld%%)\n",
-				i, collision[i], (collision[i] * 100L)/ slots);
-		if (collision[0])
-			fprintf(stderr, "> %d chains: %d (%ld%%)\n",
-				nslots - 1, collision[0],
-				(collision[0] * 100L)/ slots);
-	fprintf(stderr, "%2.2f probes per access, longest chain: %d, %s\n",
-		(double) total / slots, longest, Table[longprobe]->n_name);
-	if (Vflag < 2)
-		return;
-	probe = fold(Table[longprobe]->n_name);
-	hash2 = HASH2(probe);
-	probe = HASH1(probe);
-	while (Table[probe] != 0
-	    && strcmp(Table[probe]->n_name, Table[longprobe]->n_name) != 0) {
-		fprintf(stderr, "%5d %s\n", probe, Table[probe]->n_name);
-		probe -= hash2;
-		if (probe < 0)
-			probe += Tabsize;
-	}
-	fprintf(stderr, "%5d %s\n", probe, Table[probe]->n_name);
-	
-}
-#else
-{
-	/* the hash algorithms are perfect -- leave them alone */
-}
-#endif
-
-/* convert to lower case in place */
-STATIC void
-lowercase(s)
-	register char *s;
-{
-	do {
-		if (isupper(*s))
-			*s -= 'A' - 'a';	/* ASCII */
-	} while (*s++);
-}
-
-/*
- * this might need change if privates catch on
- */
-STATIC node *
-isprivate(name)
-	register char *name;
-{	register node *n;
-
-	for (n = Private; n != 0; n = n->n_private)
-		if (strcmp(name, n->n_name) == 0)
-			return n;
-	return 0;
-}
-
-/*  Add a private node so private that nobody can find it.  */
-node *
-addhidden(name)
-	register char *name;
-{	register node *n;
-	register int i;
-	if (Iflag)
-		lowercase(name);
-
-	n = newnode();
-	n->n_name = strsave(name);
-	n->n_flag = ISPRIVATE;
-	i = hash(n->n_name, 1);
-	if (Table[i] != 0)
-		die("impossible hidden node error");
-	Table[i] = n;
-	n->n_tloc = i;
-	n->n_private = 0;
-	return n;
-}
-
-void
-fixprivate()
-{	register node *n, *next;
-	register long i;
-
-	for (n = Private; n != 0; n = next) {
-		n->n_flag |= ISPRIVATE;		/* overkill, but safe */
-		i = hash(n->n_name, 1);
-		if (Table[i] != 0)
-			die("impossible private node error");
-	
-		Table[i] = n;
-		n->n_tloc = i;	/* essentially a back link to the table */
-		next = n->n_private;
-		n->n_private = 0;	/* clear for later use */
-	}
-	Private = 0;
-}
-
-node *
-addprivate(name)
-	register char *name;
-{	register node *n;
-
-	if (Iflag)
-		lowercase(name);
-	if ((n = isprivate(name)) != 0)
-		return n;
-
-	n = newnode();
-	n->n_name = strsave(name);
-	n->n_private = Private;
-	Private = n;
-	return n;
-}
//GO.SYSIN DD addnode.c
echo local.c 1>&2
sed 's/^-//' >local.c <<'//GO.SYSIN DD local.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)local.c	9.2 88/06/10";
-#endif /* lint */
-
-#include <stdio.h>
-#include "config.h"
-
-#ifdef	UNAME
-#include <sys/utsname.h>
-
-char	*
-local()
-{
-	static struct utsname utsname;
-	extern int uname();
-
-	(void) uname(&utsname);
-	return(utsname.nodename);
-}
-
-#else /* !UNAME */
-
-char	*
-local()
-{
-	static char lname[64];
-	extern int gethostname();
-
-	(void) gethostname(lname, (int) sizeof(lname));
-	lname[sizeof(lname)] = 0;
-	return(lname);
-}
-
-#ifndef GETHOSTNAME
-
-STATIC int
-gethostname(name, len)
-	char *name;
-	int len;
-{	FILE *whoami;
-	char *ptr;
-	extern int pclose();
-	extern FILE *fopen(), *popen();
-
-	*name = '\0';
-
-	/* try /etc/whoami */
-	if ((whoami = fopen("/etc/whoami", "r")) != 0) {
-		(void) fgets(name, len, whoami);
-		(void) fclose(whoami);
-		if ((ptr = index(name, '\n')) != 0)
-			*ptr = '\0';
-	}
-	if (*name)
-		return 0;
-
-	/* try /usr/include/whoami.h */
-	if ((whoami = fopen("/usr/include/whoami.h", "r")) != 0) {
-		while (!feof(whoami)) {
-			char	buf[100];
-
-			if (fgets(buf, 100, whoami) == 0)
-				break;
-			if (sscanf(buf, "#define sysname \"%[^\"]\"", name))
-				break;
-		}
-		(void) fclose(whoami);
-		if (*name)
-			return 0;
-	}
-
-	/* ask uucp */
-	if ((whoami = popen("uuname -l", "r")) != 0) {
-		(void) fgets(name, len, whoami);
-		(void) pclose(whoami);
-		if ((ptr = index(name, '\n')) != 0)
-			*ptr = '\0';
-	}
-	if (*name)
-		return 0;
-	
-	/* aw hell, i give up!  is this really unix? */
-	return -1;
-}
-#endif /* GETHOSTNAME */
-#endif /* UNAME */
//GO.SYSIN DD local.c
echo main.c 1>&2
sed 's/^-//' >main.c <<'//GO.SYSIN DD main.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)main.c	9.5 88/06/10";
-#endif
-
-#define MAIN	/* for sccsid in header files */
-
-#include "def.h"
-
-/* exports */
-char *Cfile;	/* current input file */
-char *Graphout;	/* file for dumping edges (-g option) */
-char *Linkout;	/* file for dumping shortest path tree */
-char **Argv;	/* external copy of argv (for input files) */
-node *Home;	/* node for local host */
-int Cflag;	/* print costs (-c option) */
-int Dflag;	/* penalize routes beyond domains (-D option) */
-int Iflag;	/* ignore case (-i option) */
-int Tflag;	/* trace links (-t option) */
-int Vflag;	/* verbose (-v option) */
-int Fflag;	/* print cost of first hop */
-int Lineno = 1;	/* line number within current input file */
-int Argc;	/* external copy of argc (for input files) */
-extern void die();
-extern int tracelink();
-
-/* imports */
-extern char *optarg;
-extern int optind;
-extern long Lcount, Ncount;
-extern long allocation();
-extern void wasted(), mapit(), hashanalyze(), deadlink();
-extern char *local();
-extern node *addnode();
-extern int getopt(), yyparse();
-extern void printit();
-
-#define USAGE "usage: %s [-vciDf] [-l localname] [-d deadlink] [-t tracelink] [-g edgeout] [-s treeout] [-a avoid] [files ...]\n"
-
-main(argc, argv) 
-	register int argc; 
-	register char **argv;
-{	char *locname = 0, *bang;
-	register int c;
-	int errflg = 0;
-
-	setbuf(stderr, (char *) 0);
-	(void) allocation();	/* initialize data space monitoring */
-	Cfile = "[deadlinks]";	/* for tracing dead links */
-	Argv = argv;
-	Argc = argc;
-
-	while ((c = getopt(argc, argv, "cd:Dfg:il:s:t:v")) != EOF)
-		switch(c) {
-		case 'c':	/* print cost info */
-			Cflag++;
-			break;
-		case 'd':	/* dead host or link */
-			if ((bang = index(optarg, '!')) != 0) {
-				*bang++ = 0;
-				deadlink(addnode(optarg), addnode(bang));
-			} else
-				deadlink(addnode(optarg), (node *) 0);
-			break;
-		case 'D':	/* penalize routes beyond domains */
-			Dflag++;
-			break;
-		case 'f':	/* print cost of first hop */
-			Cflag++;
-			Fflag++;
-			break;
-		case 'g':	/* graph output file */
-			Graphout = optarg;
-			break;
-		case 'i':	/* ignore case */
-			Iflag++;
-			break;
-		case 'l':	/* local name */
-			locname = optarg;
-			break;
-		case 's':	/* show shortest path tree */
-			Linkout = optarg;
-			break;
-		case 't':	/* trace this link */
-			if (tracelink(optarg) < 0) {
-				fprintf(stderr, "%s: can trace only %d links\n", Argv[0], NTRACE);
-				exit(1);
-			}
-			Tflag = 1;
-			break;
-		case 'v':	/* verbose stderr, mixed blessing */
-			Vflag++;
-			break;
-		default:
-			errflg++;
-		}
-
-	if (errflg) {
-		fprintf(stderr, USAGE, Argv[0]);
-		exit(1);
-	}
-	argv += optind;		/* kludge for yywrap() */
-
-	if (*argv)
-		freopen("/dev/null", "r", stdin);
-	else
-		Cfile = "[stdin]";
-
-	if (!locname) 
-		locname = local();
-	if (*locname == 0) {
-		locname = "lostinspace";
-		fprintf(stderr, "%s: using \"%s\" for local name\n",
-				Argv[0], locname);
-	}
-
-	Home = addnode(locname);	/* add home node */
-	Home->n_cost = 0;		/* doesn't cost to get here */
-
-	(void) yyparse();			/* read in link info */
-
-	if (Vflag > 1)
-		hashanalyze();
-	vprintf(stderr, "%d nodes, %d links, alloc %ldk\n", 
-				Ncount, Lcount, allocation());
-
-	Cfile = "[backlinks]";	/* for tracing back links */
-	Lineno = 0;
-
-	/* compute shortest path tree */
-	mapit();
-	vprintf(stderr, "allocation is %ldk after mapping\n", allocation());
-
-	/* traverse tree and print paths */
-	printit();
-	vprintf(stderr, "allocation is %ldk after printing\n", allocation());
-
-	wasted();	/* how much was wasted in memory allocation? */
-
-	return 0;
-}
-
-void
-die(s)
-	char *s;
-{
-#ifdef DEBUG
-	extern int abort();
-
-	fprintf(stderr, "%s: %s\n", Argv[0], s);
-	fflush(stdout);
-	fflush(stderr);
-	abort();
-#else
-	fprintf(stderr, "%s: %s; notify the authorities\n", Argv[0], s);
-	exit(-1);
-#endif
-}
//GO.SYSIN DD main.c
echo mapit.c 1>&2
sed 's/^-//' >mapit.c <<'//GO.SYSIN DD mapit.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)mapit.c	9.13 88/06/12";
-#endif
-
-#include "def.h"
-
-#define chkheap(i)	/* void */
-#define chkgap()	/* int */
-
-#define trprint(stream, n) \
-	fprintf((stream), (n)->n_flag & NTERMINAL ? "<%s>" : "%s", (n)->n_name)
-
-/* exports */
-/* invariant while mapping: Nheap < Hashpart */
-long Hashpart;		/* start of unreached nodes */
-long Nheap;		/* end of heap */
-long NumNcopy, Nlink, NumLcopy;
-
-void mapit();
-
-/* imports */
-extern long Nheap, Hashpart, Tabsize, Tcount;
-extern int Tflag, Vflag;
-extern node **Table, *Home;
-extern char *Linkout, *Graphout;
-
-extern void freelink(), resetnodes(), printit(), dumpgraph();
-extern void showlinks(), die();
-extern long pack(), allocation();
-extern link *newlink(), *addlink();
-extern int maptrace(), tiebreaker();
-extern node *ncopy();
-
-
-/* privates */
-static long	Heaphighwater;
-static link	**Heap;
-
-STATIC void insert(), heapup(), heapdown(), heapswap(), backlinks();
-STATIC void setheapbits(), mtracereport(), heapchildren(), otracereport();
-STATIC link *min_node();
-STATIC int dehash(), skiplink(), skipterminalalias();
-STATIC Cost costof();
-STATIC node *mappedcopy();
-
-/* transform the graph to a shortest-path tree by marking tree edges */
-void
-mapit()
-{	register node *n;
-	register link *l;
-
-	vprintf(stderr, "*** mapping\ttcount = %ld\n", Tcount);
-	Tflag = Tflag && Vflag;		/* tracing here only if verbose */
-	/* re-use the hash table space for the heap */
-	Heap = (link **) Table;
-	Hashpart = pack(0L, Tabsize - 1);
-
-	/* expunge penalties from -a option and make circular copy lists */
-	resetnodes();
-
-	if (Linkout && *Linkout)	/* dump cheapest links */
-		showlinks();
-	if (Graphout && *Graphout)	/* dump the edge list */
-		dumpgraph();
-
-	/* insert Home to get things started */
-	l = newlink();		/* link to get things started */
-	l->l_to = Home;
-	(void) dehash(Home);
-	insert(l);
-
-	/* main mapping loop */
-	do {
-		Heaphighwater = Nheap;
-		while ((l = min_node()) != 0) {
-			l->l_flag |= LTREE;
-			n = l->l_to;
-			if (n->n_flag & MAPPED)		/* sanity check */
-				die("mapped node in heap");
-			if (Tflag && maptrace(n, n))
-				otracereport(n);	/* tracing */
-			chkheap(1); chkgap();		/* debugging */
-			n->n_flag |= MAPPED;
-			heapchildren(n);	/* add children to heap */
-		}
-		vprintf(stderr, "heap hiwat %d\nalloc %ldk, ncopy = %ld, nlink = %ld, lcopy = %ld\n", Heaphighwater, allocation(), NumNcopy, Nlink, NumLcopy);
-
-		if (Nheap != 0)		/* sanity check */
-			die("null entry in heap");
-
-		/*
-		 * add back links from unreachable hosts to reachable
-		 * neighbors, then remap.  asymptotically, this is
-		 * quadratic; in practice, this is done once or twice,
-		 * when n is small.
-		 */
-		backlinks();
-	} while (Nheap > 0);
-
-	if (Hashpart < Tabsize) {
-		int foundone = 0;
-
-		for ( ; Hashpart < Tabsize; Hashpart++) {
-			if (Table[Hashpart]->n_flag & ISPRIVATE)
-				continue;
-			if (foundone++ == 0)
-				fputs("You can't get there from here:\n", stderr);
-			putc('\t', stderr);
-			trprint(stderr, Table[Hashpart]);
-			putc('\n', stderr);
-		}
-	}
-}
-
-STATIC void
-heapchildren(n)
-	register node *n;
-{	register link *l;
-	register node *next;
-	register int mtrace;
-	register Cost cost;
-
-	for (l = n->n_link; l; l = l->l_next) {
-
-		next = l->l_to;		/* neighboring node */
-		mtrace = Tflag && maptrace(n, next);
-
-		if (l->l_flag & LTREE)
-			continue;
-
-		if (l->l_flag & LTERMINAL)
-			l->l_to = next = ncopy(n, l);
-
-		if ((n->n_flag & NTERMINAL) && (l->l_flag & LALIAS))
-			if (skipterminalalias(n, next))
-				continue;
-			else
-				l->l_to = next = ncopy(n, l);
-
-		if (next->n_flag & MAPPED) {
-			if (mtrace)
-				mtracereport(n, l, "-\talready mapped");
-			continue;
-		}
-		cost = costof(n, l);
-
-		if (skiplink(l, n, cost, mtrace))
-			continue;
-
-		/*
-		 * put this link in the heap and restore the
-		 * heap property.
-		 */
-		if (mtrace) {
-			if (next->n_parent)
-				mtracereport(next->n_parent, l, "*\tdrop");
-			mtracereport(n, l, "+\tadd");
-		}
-		next->n_parent = n;
-		if (dehash(next) == 0) {  /* first time */
-			next->n_cost = cost;
-			insert(l);	  /* insert at end */
-			heapup(l);
-		} else {
-			/* replace inferior path */
-			Heap[next->n_tloc] = l;
-			if (cost > next->n_cost) {
-				/* increase cost (gateway) */
-				next->n_cost = cost;
-				heapdown(l);
-			} else if (cost < next->n_cost) {
-				/* cheaper route */
-				next->n_cost = cost;
-
-				heapup(l);
-			}
-		}
-		setheapbits(l);
-		chkheap(1);
-
-	}
-}
-
-/* 
- * bizarro special case.  this merits comment.
- * 
- * n is a terminal node just sucked out of the heap, next is an alias
- * for n.  because n is terminal, it must have one or more "copies."
- * if next is one of those copies, don't put next in the heap.
- *
- * does that clear things up?
- */
-STATIC int
-skipterminalalias(n, next)
-	node *n, *next;
-{
-
-	while (n->n_flag & NALIAS) {
-		n = n->n_parent;
-		if (ALTEREGO(n, next))
-			return 1;
-	}
-	return 0;
-}
-
-/*
- * return 1 if we definitely don't want want this link in the
- * shortest path tree, 0 if we might want it, i.e., best so far.
- *
- * if tracing is turned on, report only if this node is being skipped.
- */
-STATIC int
-skiplink(l, parent, cost, trace)
-	link *l;		/* new link to this node */
-	node *parent;		/* (potential) new parent of this node */
-	register Cost cost;	/* new cost to this node */
-	int trace;		/* trace this link? */
-{	register node *n;	/* this node */
-	register link *lheap;		/* old link to this node */
-
-	n = l->l_to;
-
-	/* first time we've reached this node? */
-	if (n->n_tloc >= Hashpart)
-		return 0;
-
-	lheap = Heap[n->n_tloc];
-
-	/* examine links to nets that require gateways */
-	if (GATEWAYED(n)) {
-		/* if exactly one is a gateway, use it */
-		if ((lheap->l_flag & LGATEWAY) && !(l->l_flag & LGATEWAY)) {
-			if (trace)
-				mtracereport(parent, l, "-\told gateway");
-			return 1;	/* old is gateway */
-		}
-		if (!(lheap->l_flag & LGATEWAY) && (l->l_flag & LGATEWAY))
-			return 0;	/* new is gateway */
-
-		/* no gateway or both gateways;  resolve in standard way ... */
-	}
-
-	/* examine dup link (sanity check) */
-	if (n->n_parent == parent && (DEADLINK(lheap) || DEADLINK(l)))
-		die("dup dead link");
-
-	/*  examine cost */
-	if (cost < n->n_cost)
-		return 0;
-	if (cost > n->n_cost) {
-		if (trace)
-			mtracereport(parent, l, "-\tcheaper");
-		return 1;
-	}
-
-	/* all other things being equal, ask the oracle */
-	if (tiebreaker(n, parent)) {
-		if (trace)
-			mtracereport(parent, l, "-\ttiebreaker");
-		return 1;
-	}
-	return 0;
-}
-
-/* compute cost to l->l_to via parent */
-STATIC Cost
-costof(prev, l)
-	register node *prev;
-	register link *l;
-{	register node *next;
-	register Cost cost;
-
-	if (l->l_flag & LALIAS)
-		return prev->n_cost;	/* by definition */
-
-	next = l->l_to;
-	cost = prev->n_cost + l->l_cost;	/* basic cost */
-
-	/*
-	 * heuristics:
-	 *    charge for a dead link.
-	 *    charge for getting past a terminal host
-	 *    	or getting out of a dead host.
-	 *    charge for getting into a gatewayed net (except at a gateway).
-	 *    discourage mixing of syntax (when prev is a host).
-	 *
-	 * life was simpler when pathalias computed true shortest paths.
-	 */
-	if (DEADLINK(l))
-		cost += INF;				/* dead link */
-	if (DEADHOST(prev))
-		cost += INF;				/* dead parent */
-	if (GATEWAYED(next) && !(l->l_flag & LGATEWAY))
-		cost += INF;				/* not gateway */
-	if (!ISANET(prev)) {
-		if ((NETDIR(l) == LLEFT && (prev->n_flag & HASRIGHT))
-		 || (NETDIR(l) == LRIGHT && (prev->n_flag & HASLEFT)))
-			cost += INF;			/* mixed syntax */
-	}
-
-	return cost;
-}
-
-/* binary heap implementation of priority queue */
-
-STATIC void
-insert(l)
-	link *l;
-{	register node *n;
-
-	n = l->l_to;
-	if (n->n_flag & MAPPED)
-		die("insert mapped node");
-
-	Heap[n->n_tloc] = 0;
-	if (Heap[Nheap+1] != 0)
-		die("heap error in insert");
-	if (Nheap++ == 0) {
-		Heap[1] = l;
-		n->n_tloc = 1;
-		return;
-	}
-	if (Vflag && Nheap > Heaphighwater)
-		Heaphighwater = Nheap;	/* diagnostics */
-
-	/* insert at the end.  caller must heapup(l). */
-	Heap[Nheap] = l;
-	n->n_tloc = Nheap;
-}
-
-/*
- * "percolate" up the heap by exchanging with the parent.  as in
- * min_node(), give tiebreaker() a chance to produce better, stable
- * routes by moving nets and domains close to the root, nets closer
- * than domains.
- *
- * i know this seems obscure, but it's harmless and cheap.  trust me.
- */
-STATIC void
-heapup(l)
-	link *l;
-{	register long cindx, pindx;	/* child, parent indices */
-	register Cost cost;
-	register node *child, *parent;
-
-	child = l->l_to;
-
-	cost = child->n_cost;
-	for (cindx = child->n_tloc; cindx > 1; cindx = pindx) {
-		pindx = cindx / 2;
-		if (Heap[pindx] == 0)	/* sanity check */
-			die("impossible error in heapup");
-		parent = Heap[pindx]->l_to;
-		if (cost > parent->n_cost)
-			return;
-
-		/* net/domain heuristic */
-		if (cost == parent->n_cost) {
-			if (!ISANET(child))
-				return;
-			if (!ISADOMAIN(parent))
-				return;
-			if (ISADOMAIN(child))
-				return;
-		}
-		heapswap(cindx, pindx);
-	}
-}
-
-/* extract min (== Heap[1]) from heap */
-STATIC link	*
-min_node()
-{	link *rval, *lastlink;
-	register link **rheap;
-
-	if (Nheap == 0)
-		return 0;
-
-	rheap = Heap;		/* in register -- heavily used */
-	rval = rheap[1];	/* return this one */
-
-	/* move last entry into root and reheap */
-	lastlink = rheap[Nheap];
-	rheap[Nheap] = 0;
-
-	if (--Nheap) {
-		rheap[1] = lastlink;
-		lastlink->l_to->n_tloc = 1;
-		heapdown(lastlink);	/* restore heap property */
-	}
-
-	return rval;
-}
-
-/*
- * swap Heap[i] with smaller child, iteratively down the tree.
- *
- * given the opportunity, attempt to place nets and domains
- * near the root.  this helps tiebreaker() shun domain routes.
- */
-
-STATIC void
-heapdown(l)
-	link *l;
-{	register long pindx, cindx;
-	register link **rheap = Heap;	/* in register -- heavily used */
-	node *child, *rchild, *parent;
-
-	pindx = l->l_to->n_tloc;
-	parent = rheap[pindx]->l_to;	/* invariant */
-	for ( ; (cindx = pindx * 2) <= Nheap; pindx = cindx) {
-		/* pick lhs or rhs child */
-		child = rheap[cindx]->l_to;
-		if (cindx < Nheap) {
-			/* compare with rhs child */
-			rchild = rheap[cindx+1]->l_to;
-			/*
-			 * use rhs child if smaller than lhs child.
-			 * if equal, use rhs if net or domain.
-			 */
-			if (child->n_cost > rchild->n_cost) {
-				child = rchild;
-				cindx++;
-			} else if (child->n_cost == rchild->n_cost)
-				if (ISANET(rchild)) {
-					child = rchild;
-					cindx++;
-				}
-		}
-
-		/* child is the candidate for swapping */
-		if (parent->n_cost < child->n_cost)
-			break;
-
-		/*
-		 * heuristics:
-		 *	move nets/domains up
-		 *	move nets above domains
-		 */
-		if (parent->n_cost == child->n_cost) {
-			if (!ISANET(child))
-				break;
-			if (ISANET(parent) && ISADOMAIN(child))
-				break;
-		}
-
-		heapswap(pindx, cindx);
-	}
-}
-
-/* exchange Heap[i] and Heap[j] pointers */
-STATIC void
-heapswap(i, j)
-	long i, j;
-{	register link *temp, **rheap;
-
-	rheap = Heap;	/* heavily used -- put in register */
-	temp = rheap[i];
-	rheap[i] = rheap[j];
-	rheap[j] = temp;
-	rheap[j]->l_to->n_tloc = j;
-	rheap[i]->l_to->n_tloc = i;
-}
-
-/* return 1 if n is already de-hashed (n_tloc < Hashpart), 0 o.w. */
-STATIC int
-dehash(n)
-	register node *n;
-{
-	if (n->n_tloc < Hashpart)
-		return 1;
-
-	/* swap with entry in Table[Hashpart] */
-	Table[Hashpart]->n_tloc = n->n_tloc;
-	Table[n->n_tloc] = Table[Hashpart];
-	Table[Hashpart] = n;
-
-	n->n_tloc = Hashpart++;
-	return 0;
-}
-
-/*
- * everything reachable has been mapped.  what to do about any
- * unreachable hosts?  the sensible thing to do is to dump them on
- * stderr and be done with it.  unfortunately, there are hundreds of
- * such hosts in the usenet maps.  so we take the low road: for each
- * unreachable host, we add a back link from its cheapest mapped child,
- * in the faint that a reverse path works.
- *
- * beats me why people want their error output in their map databases.
- */
-STATIC void
-backlinks()
-{	register link *l;
-	register node *n, *child;
-	node *nomap;
-	long i;
-
-	/* hosts from Hashpart to Tabsize are unreachable */
-	for (i = Hashpart; i < Tabsize; i++) {
-		nomap = Table[i];
-		/* if a copy has been mapped, we're ok */
-		if (nomap->n_copy != nomap) {
-			dehash(nomap);
-			Table[nomap->n_tloc] = 0;
-			nomap->n_tloc = 0;
-			continue;
-		}
-
-		/* TODO: simplify this */		
-		/* add back link from minimal cost child */
-		child = 0;
-		for (l = nomap->n_link; l; l = l->l_next) {
-			n = l->l_to;
-			/* never ever ever crawl out of a domain */
-			if (ISADOMAIN(n))
-				continue;
-			if ((n = mappedcopy(n)) == 0)
-				continue;
-			if (child == 0) {
-				child = n;
-				continue;
-			}
-			if (n->n_cost > child->n_cost)
-				continue;
-			if (n->n_cost == child->n_cost) {
-				nomap->n_parent = child; /* for tiebreaker */
-				if (tiebreaker(nomap, n))
-					continue;
-			}
-			child = n;
-		}
-		if (child == 0)
-			continue;
-		(void) dehash(nomap);
-		l = addlink(child, nomap, INF, DEFNET, DEFDIR);	/* INF cost */
-		nomap->n_parent = child;
-		nomap->n_cost = costof(child, l);
-		insert(l);
-		heapup(l);
-		if (Vflag > 1)
-			fprintf(stderr, "backlink: %s <- %s\n", nomap->n_name, child->n_name);
-	}
-	vprintf(stderr, "%d backlinks\n", Nheap);
-}
-
-/* find a mapped copy of n if it exists */
-STATIC node *
-mappedcopy(n)
-	register node *n;
-{	register node *ncp;
-
-	if (n->n_flag & MAPPED)
-		return n;
-	for (ncp = n->n_copy; ncp != n; ncp = ncp->n_copy)
-		if (ncp->n_flag & MAPPED)
-			return ncp;
-	return 0;
-}
-
-/*
- * l has just been added or changed in the heap,
- * so reset the state bits for l->l_to.
- */
-STATIC void
-setheapbits(l)
-	register link *l;
-{	register node *n;
-	register node *parent;
-
-	n = l->l_to;
-	parent = n->n_parent;
-	n->n_flag &= ~(NALIAS|HASLEFT|HASRIGHT);	/* reset */
-
-	/* record whether link is an alias */
-	if (l->l_flag & LALIAS) {
-		n->n_flag |= NALIAS;
-		/* TERMINALity is inherited by the alias */
-		if (parent->n_flag & NTERMINAL)
-			n->n_flag |= NTERMINAL;
-	}
-
-	/* set left/right bits */
-	if (NETDIR(l) == LLEFT || (parent->n_flag & HASLEFT))
-		n->n_flag |= HASLEFT;
-	if (NETDIR(l) == LRIGHT || (parent->n_flag & HASRIGHT))
-		n->n_flag |= HASRIGHT;
-}
-
-STATIC void
-mtracereport(from, l, excuse)
-	node *from;
-	link *l;
-	char *excuse;
-{	node *to = l->l_to;
-
-	fprintf(stderr, "%-16s ", excuse);
-	trprint(stderr, from);
-	fputs(" -> ", stderr);
-	trprint(stderr, to);
-	fprintf(stderr, " (%ld, %ld, %ld) ", from->n_cost, l->l_cost, to->n_cost);
-	if (to->n_parent) {
-		trprint(stderr, to->n_parent);
-		fprintf(stderr, " (%ld)", to->n_parent->n_cost);
-	}
-	putc('\n', stderr);
-}
-
-STATIC void
-otracereport(n)
-	node *n;
-{
-	if (n->n_parent)
-		trprint(stderr, n->n_parent);
-	else
-		fputs("[root]", stderr);
-	fputs(" -> ", stderr);
-	trprint(stderr, n);
-	fputs(" mapped\n", stderr);
-}
-	
-#if 0
-/* extremely time consuming, exhaustive check of heap sanity. */
-chkheap(i)
-{	int lhs, rhs;
-
-	lhs = i * 2;
-	rhs = lhs + 1;
-
-	if (lhs <= Nheap) {
-		if (Heap[i]->l_to->n_cost > Heap[lhs]->l_to->n_cost)
-			die("chkheap failure on lhs");
-		chkheap(lhs);
-	}
-	if (rhs <= Nheap) {
-		if (Heap[i]->l_to->n_cost > Heap[rhs]->l_to->n_cost)
-			die("chkheap failure on rhs");
-		chkheap(rhs);
-	}
-#if 00
-	/* this hasn't been used for years */
-	for (i = 1; i < Nheap; i++) {
-		link *l;
-
-		vprintf(stderr, "%5d %-16s", i, Heap[i]->l_to->n_name);
-		if ((l = Heap[i]->l_to->n_link) != 0) do {
-			vprintf(stderr, "%-16s", l->l_to->n_name);
-		} while ((l = l->l_next) != 0);
-		vprintf(stderr, "\n");
-	}
-	for (i = Hashpart; i < Tabsize; i++) {
-		link *l;
-		node *n;
-
-		vprintf(stderr, "%5d %-16s", i, Table[i]->n_name);
-		if ((l = Table[i]->n_link) != 0) do {
-			vprintf(stderr, "%-16s", l->l_to->n_name);
-		} while ((l = l->l_next) != 0);
-		vprintf(stderr, "\n");
-	}
-#endif /*00*/
-		
-}
-#endif /*0*/
-
-/* this isn't much use */
-#if 0
-STATIC int
-chkgap()
-{	static int gap = -1;
-	int newgap;
-
-	newgap = Hashpart - Nheap;
-	if (gap == -1 || newgap < gap)
-		gap = newgap;
-	return gap;
-}
-#endif /*0*/
//GO.SYSIN DD mapit.c
echo mapaux.c 1>&2
sed 's/^-//' >mapaux.c <<'//GO.SYSIN DD mapaux.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)mapaux.c	9.4 89/03/01";
-#endif /* lint */
-
-#include "def.h"
-
-/* imports */
-extern long Nheap, Hashpart, Tabsize, NumNcopy, Nlink, NumLcopy;
-extern node **Table, *Home;
-extern char *Graphout, *Linkout, *Netchars, **Argv;
-extern int Vflag;
-extern void freelink(), die();
-extern long pack();
-extern link *newlink();
-extern node *newnode();
-extern char *strsave();
-extern int strcmp(), strlen();
-
-/* exports */
-extern long pack();
-extern void resetnodes(), dumpgraph(), showlinks(), terminalnet();
-extern int tiebreaker();
-extern node *ncopy();
-
-/* privates */
-static FILE *Gstream;	/* for dumping graph */
-STATIC void dumpnode(), untangle(), dfs();
-STATIC int height();
-STATIC link *lcopy();
-
-
-/*
- * slide everything from Table[low] to Table[high]
- * up toward the high end.  make room!  make room!
- */
-long
-pack(low, high)
-	long low, high;
-{	long hole, next;
-
-	/* find first "hole " */
-	for (hole = high; hole >= low && Table[hole] != 0; --hole)
-		;
-
-	/* repeatedly move next filled entry into last hole */
-	for (next = hole - 1; next >= low; --next) {
-		if (Table[next] != 0) {
-			Table[hole] = Table[next];
-			Table[hole]->n_tloc = hole;
-			Table[next] = 0;
-			while (Table[--hole] != 0)	/* find next hole */
-				;
-		}
-	}
-	return hole + 1;
-}
-
-void
-resetnodes()
-{	register long i;
-	register node *n;
-
-	for (i = Hashpart; i < Tabsize; i++)
-		if ((n = Table[i]) != 0) {
-			n->n_cost = (Cost) 0;
-			n->n_flag &= ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT|NTERMINAL);
-			n->n_copy = n;
-		}
-		
-	Home->n_cost = (Cost) 0;
-	Home->n_flag &= ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT|NTERMINAL);
-	Home->n_copy = Home;
-}
-
-void	
-dumpgraph()
-{	register long i;
-	register node *n;
-
-	if ((Gstream = fopen(Graphout, "w")) == NULL) {
-		fprintf(stderr, "%s: ", Argv[0]);
-		perror(Graphout);
-		return;
-	}
-
-	untangle();	/* untangle net cycles for proper output */
-
-	for (i = Hashpart; i < Tabsize; i++) {
-		n = Table[i];
-		if (n == 0)
-			continue;	/* impossible, but ... */
-		/* a minor optimization ... */
-		if (n->n_link == 0)
-			continue;
-		/* pathparse doesn't need these */
-		if (n->n_flag & NNET)
-			continue;
-		dumpnode(n);
-	}
-}
-
-STATIC void
-dumpnode(from)
-	register node *from;
-{	register node *to;
-	register link *l;
-	link *lnet = 0, *ll, *lnext;
-
-	for (l = from->n_link ; l; l = l->l_next) {
-		to = l->l_to;
-		if (from == to)
-			continue;	/* oops -- it's me! */
-
-		if ((to->n_flag & NNET) == 0) {
-			/* host -> host -- print host>host */
-			if (l->l_cost == INF)
-				continue;	/* phoney link */
-			fputs(from->n_name, Gstream);
-			putc('>', Gstream);
-			fputs(to->n_name, Gstream);
-			putc('\n', Gstream);
-		} else {
-			/*
-			 * host -> net -- just cache it for now.
-			 * first check for dups.  (quadratic, but
-			 * n is small here.)
-			 */
-			while (to->n_root && to != to->n_root)
-				to = to->n_root;
-			for (ll = lnet; ll; ll = ll->l_next)
-				if (strcmp(ll->l_to->n_name, to->n_name) == 0)
-					break;
-			if (ll)
-				continue;	/* dup */
-			ll = newlink();
-			ll->l_next = lnet;
-			ll->l_to = to;
-			lnet = ll;
-		}
-	}
-
-	/* dump nets */
-	if (lnet) {
-		/* nets -- print host@\tnet,net, ... */
-		fputs(from->n_name, Gstream);
-		putc('@', Gstream);
-		putc('\t', Gstream);
-		for (ll = lnet; ll; ll = lnext) {
-			lnext = ll->l_next;
-			fputs(ll->l_to->n_name, Gstream);
-			if (lnext)
-				fputc(',', Gstream);
-			freelink(ll);
-		}
-		putc('\n', Gstream);
-	}
-}
-
-/*
- * remove cycles in net definitions. 
- *
- * depth-first search
- *
- * for each net, run dfs on its neighbors (nets only).  if we return to
- * a visited node, that's a net cycle.  mark the cycle with a pointer
- * in the n_root field (which gets us closer to the root of this
- * portion of the dfs tree).
- */
-STATIC void
-untangle()
-{	register long i;
-	register node *n;
-
-	for (i = Hashpart; i < Tabsize; i++) {
-		n = Table[i];
-		if (n == 0 || (n->n_flag & NNET) == 0 || n->n_root)
-			continue;
-		dfs(n);
-	}
-}
-
-STATIC void
-dfs(n)
-	register node *n;
-{	register link *l;
-	register node *next;
-
-	n->n_flag |= INDFS;
-	n->n_root = n;
-	for (l = n->n_link; l; l = l->l_next) {
-		next = l->l_to;
-		if ((next->n_flag & NNET) == 0)
-			continue;
-		if ((next->n_flag & INDFS) == 0) {
-			dfs(next);
-			if (next->n_root != next)
-				n->n_root = next->n_root;
-		} else
-			n->n_root = next->n_root;
-	}
-	n->n_flag &= ~INDFS;
-}
-
-void
-showlinks() 
-{	register link *l;
-	register node *n;
-	register long i;
-	FILE	*estream;
-
-	if ((estream = fopen(Linkout, "w")) == 0)
-		return;
-
-	for (i = Hashpart; i < Tabsize; i++) {
-		n = Table[i];
-		if (n == 0 || n->n_link == 0)
-			continue;
-		for (l = n->n_link; l; l = l->l_next) {
-			fputs(n->n_name, estream);
-			putc('\t', estream);
-			if (NETDIR(l) == LRIGHT)
-				putc(NETCHAR(l), estream);
-			fputs(l->l_to->n_name, estream);
-			if (NETDIR(l) == LLEFT)
-				putc(NETCHAR(l), estream);
-			fprintf(estream, "(%d)\n", l->l_cost);
-		}
-	}
-	(void) fclose(estream);
-}
-
-/*
- * n is node in heap, newp is candidate for new parent.
- * choose between newp and n->n_parent for parent.
- * return 0 to use newp, non-zero o.w.
- */
-#define NEWP 0
-#define OLDP 1
-int
-tiebreaker(n, newp)
-	node *n;
-	register node *newp;
-{	register char *opname, *npname, *name;
-	register node *oldp;
-	int metric;
-
-	oldp = n->n_parent;
-
-	/* given the choice, avoid gatewayed nets */
-	if (GATEWAYED(newp) && !GATEWAYED(oldp))
-		return OLDP;
-	if (!GATEWAYED(newp) && GATEWAYED(oldp))
-		return NEWP;
-
-	/* look at real parents, not nets */
-	while ((oldp->n_flag & NNET) && oldp->n_parent)
-		oldp = oldp->n_parent;
-	while ((newp->n_flag & NNET) && newp->n_parent)
-		newp = newp->n_parent;
-
-	/* use fewer hops, if possible */
-	metric = height(oldp) - height(newp);
-	if (metric < 0)
-		return OLDP;
-	if (metric > 0)
-		return NEWP;
-
-	/*
-	 * compare names
-	 */
-	opname = oldp->n_name;
-	npname = newp->n_name;
-	name = n->n_name;
-
-	/* use longest common prefix with parent */
-	while (*opname == *name && *npname == *name && *name) {
-		opname++;
-		npname++;
-		name++;
-	}
-	if (*opname == *name)
-		return OLDP;
-	if (*npname == *name)
-		return NEWP;
-
-	/* use shorter host name */
-	metric = strlen(opname) - strlen(npname);
-	if (metric < 0)
-		return OLDP;
-	if (metric > 0)
-		return NEWP;
-
-	/* use larger lexicographically */
-	metric = strcmp(opname, npname);
-	if (metric < 0)
-		return NEWP;
-	return OLDP;
-}
-
-STATIC int
-height(n)
-	register node *n;
-{	register int i = 0;
-
-	if (n == 0)
-		return 0;
-	while ((n = n->n_parent) != 0)
-		if (ISADOMAIN(n) || !(n->n_flag & NNET))
-			i++;
-	return i;
-}
-	
-/*
- * return a copy of n ( == l->l_to).  we rely on n and its copy
- * pointing to the same name string, which is kludgey, but works
- * because the name is non-volatile.
- */
-
-#define REUSABLE(n, l)	(((n)->n_flag & NTERMINAL) == 0 \
-		      && ((n)->n_copy->n_flag & NTERMINAL) \
-		      && !((n)->n_copy->n_flag & NALIAS) \
-		      && !((l)->l_flag & LALIAS))
-node *
-ncopy(parent, l)
-	register node *parent;
-	register link *l;
-{	register node *n, *ncp;
-
-#ifdef DEBUG
-	if (Vflag > 1)
-		vprintf(stderr, "<%s> <- %s\n", l->l_to->n_name, parent->n_name);
-#endif
-	n = l->l_to;
-	if (REUSABLE(n, l)) {
-		Nlink++;
-		return n->n_copy;	/* re-use */
-	}
-	NumNcopy++;
-	l->l_to = ncp = newnode();
-	ncp->n_name = n->n_name;	/* nonvolatile */
-	ncp->n_tloc = --Hashpart;	/* better not be > 20% of total ... */
-	if (Hashpart == Nheap)
-		die("too many terminal links");
-	Table[Hashpart] = ncp;
-	ncp->n_copy = n->n_copy;	/* circular list */
-	n->n_copy = ncp;
-	ncp->n_link = lcopy(parent, n);
-	ncp->n_flag = (n->n_flag & ~(NALIAS|ATSIGN|MAPPED|HASLEFT|HASRIGHT)) | NTERMINAL;
-	return ncp;
-}
-
-/*
- * copy l, but don't include any links to parent.
- *
- * this is a little messier than it should be, because
- * of the funny test for ancestry, and because it wants
- * to be recursive, but the recursion might be very deep
- * (for a long link list), so it's done iteratively.
- */
-STATIC link *
-lcopy(parent, n)
-	register node *parent, *n;
-{	register link *l, *lcp;
-	link *first = 0, *last = 0;
- 
-	for (l = n->n_link; l != 0; l = l->l_next) {
-		/* avoid vestigial descendants */
-		if ((l->l_to->n_flag & MAPPED) != 0
-		 || ALTEREGO(l->l_to, parent))
-			continue;
-#ifdef DEBUG
-		if (Vflag > 1)
-			vprintf(stderr, "\t-> %s\n", l->l_to->n_name);
-#endif
-		NumLcopy++;
-		lcp = newlink();
-		*lcp = *l;	/* struct copy */
-		lcp->l_flag &= ~LTREE;
-		if (ISANET(n))
-			lcp->l_flag |= LTERMINAL;
- 
-		if (first == 0) {
-			first = last = lcp;
-		} else {
-			last->l_next = lcp;
-			last = lcp;
-		}
-	}
-	if (last)
-		last->l_next = 0;
-	return first;
-}
//GO.SYSIN DD mapaux.c
echo mem.c 1>&2
sed 's/^-//' >mem.c <<'//GO.SYSIN DD mem.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)mem.c	9.2 88/06/10";
-#endif
-
-#include "def.h"
-
-/* exports */
-long Ncount;
-extern void freelink(), wasted(), freetable();
-extern long allocation();
-
-/* imports */
-extern char *Netchars;
-extern int Vflag;
-extern char *sbrk();
-extern void die();
-extern int strlen();
-
-/* privates */
-STATIC void nomem();
-static link *Lcache;
-static unsigned int Memwaste;
-
-link	*
-newlink()
-{	register link *rval;
-
-	if (Lcache) {
-	 	rval = Lcache;
-		Lcache = Lcache->l_next;
-		strclear((char *) rval, sizeof(link));
-	} else if ((rval = (link * ) calloc(1, sizeof(link))) == 0)
-		nomem();
-	return rval;
-}
-
-/* caution: this destroys the contents of l_next */
-void
-freelink(l)
-	link *l;
-{
-	l->l_next = Lcache;
-	Lcache = l;
-}
-
-node	*
-newnode()
-{	register node *rval;
-
-	if ((rval = (node * ) calloc(1, sizeof(node))) == 0)
-		nomem();
-	Ncount++;
-	return rval;
-}
-
-char	*
-strsave(s)
-	char *s;
-{	register char *r;
-
-	if ((r = malloc((unsigned) strlen(s) + 1)) == 0)
-		nomem();
-	(void) strcpy(r, s);
-	return r;
-}
-
-#ifndef strclear
-void
-strclear(str, len)
-	register char *str;
-	register long len;
-{
-	while (--len >= 0)
-		*str++ = 0;
-}
-#endif /*strclear*/
-
-node	**
-newtable(size)
-	long size;
-{	register node **rval;
-
-	if ((rval = (node **) calloc(1, (unsigned int) size * sizeof(node *))) == 0) 
-		nomem();
-	return rval;
-}
-
-void
-freetable(t, size)
-	node **t;
-	long size;
-{
-#ifdef MYMALLOC
-	extern void addtoheap();
-
-	addtoheap((char *) t, size * sizeof(node *));
-#else
-	free((char *) t);
-#endif
-}
-
-STATIC void
-nomem()
-{
-	static char epitaph[128];
-
-	sprintf(epitaph, "out of memory (%ldk allocated)", allocation());
-	die(epitaph);
-}
-
-/* data space allocation -- main sets `dataspace' very early */
-long
-allocation()
-{
-	static char *dataspace;
-	long rval;
-
-	if (dataspace == 0) {		/* first time */
-		dataspace = sbrk(0);	/* &end? */
-		return 0;
-	}
-	rval = (sbrk(0) - dataspace)/1024;
-	if (rval < 0)			/* funny architecture? */
-		rval = -rval;
-	return rval;
-}
-
-/* how much memory has been wasted? */
-void
-wasted()
-{
-	if (Memwaste == 0)
-		return;
-	vprintf(stderr, "memory allocator wasted %ld bytes\n", Memwaste);
-}
-
-#ifdef MYMALLOC
-
-/* use c library malloc/calloc here, and here only */
-#undef malloc
-#undef calloc
-
-/* imports */
-extern char *malloc(), *calloc();
-
-/* private */
-STATIC int align();
-
-/* allocate in MBUFSIZ chunks.  4k works ok (less 16 for malloc quirks). */
-#define MBUFSIZ (4 * 1024 - 16)
-
-/* 
- * mess with ALIGN at your peril.  longword (== 0 mod 4)
- * alignment seems to work everywhere.
- */
-
-#define ALIGN 2
-
-typedef struct heap heap;
-struct heap {
-	heap *h_next;
-	long h_size;
-};
-
-static heap *Mheap;	/* not to be confused with a priority queue */
-
-STATIC void
-addtoheap(p, size)
-	char *p;
-	long size;
-{	int adjustment;
-	heap *pheap;
-
-	/* p is aligned, but it doesn't hurt to check */
-	adjustment = align(p);
-	p += adjustment;
-	size -= adjustment;
-
-	if (size < 1024)
-		return;		/* can't happen */
-	pheap = (heap *) p;	/* pheap is shorthand */
-	pheap->h_next = Mheap;
-	pheap->h_size = size;
-	Mheap = pheap;
-}
-
-/*
- * buffered malloc()
- *	returns space initialized to 0.  calloc isn't used, since
- *	strclear can be faster.
- *
- * free is ignored, except for very large objects,
- * which are returned to the heap with addtoheap(). 
- */
-
-char	*
-mymalloc(n)
-	register unsigned int n;
-{	static unsigned int size; /* how much do we have on hand? */
-	static char *mstash;	  /* where is it? */
-	register char *rval;
-
-	if (n >= 1024) {		/* for hash table */
-		rval = malloc(n);	/* aligned */
-		if (rval)
-			strclear(rval, n);
-		return rval;
-	}
-
-	n += align((char *) n);	/* keep everything aligned */
-
-	if (n > size) {
-		Memwaste += size;	/* toss the fragment */
-		/* look in the heap */
-		if (Mheap) {
-			mstash = (char *) Mheap;	/* aligned */
-			size = Mheap->h_size;
-			Mheap = Mheap->h_next;
-		} else {
-			mstash = malloc(MBUFSIZ);	/* aligned */
-			if (mstash == 0) {
-				size = 0;
-				return 0;
-			}
-			size = MBUFSIZ;
-		}
-		strclear(mstash, size);		/* what if size > 2^16? */
-	}
-	rval = mstash;
-	mstash += n;
-	size -= n;
-	return rval;
-}
-
-/*
- * what's the (mis-)alignment of n?  return the complement of
- * n mod 2^ALIGN
- */
-STATIC int
-align(n)
-	char *n;
-{	register int abits;	/* misalignment bits in n */
-
-	abits = (int) n & ~(0xff << ALIGN) & 0xff;
-	if (abits == 0)
-		return 0;
-	return (1 << ALIGN) - abits;
-}
-
-#endif /*MYMALLOC*/
//GO.SYSIN DD mem.c
echo printit.c 1>&2
sed 's/^-//' >printit.c <<'//GO.SYSIN DD printit.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)printit.c	9.4 89/02/07";
-#endif
-
-#include "def.h"
-
-/*
- * print the routes by traversing the shortest path tree in preorder.
- * use lots of char bufs -- profiling indicates this costs about 5 kbytes
- */
-
-/* exports */
-extern void printit();
-
-/* imports */
-extern int Cflag, Vflag, Dflag, Fflag;
-extern node *Home;
-extern char *Netchars;
-extern void die();
-extern int strlen();
-
-/* privates */
-static link *Ancestor;	/* for -f option */
-STATIC void preorder(), setpath(), printhost(), printdomain();
-STATIC char *hostpath();
-STATIC int printable();
-
-/* in practice, even the longest paths are < 100 bytes */
-#define PATHSIZE 512
-
-void
-printit()
-{	link *l;
-	char pbuf[PATHSIZE];
-
-	/* print home */
-	if (Cflag)
-		printf("%ld\t", (long) Home->n_cost);
-	printf("%s\t%%s\n", Home->n_name);
-	
-	strcpy(pbuf, "%s");
-	for (l = Home->n_link; l; l = l->l_next) {
-		if (l->l_flag & LTREE) {
-			l->l_flag &= ~LTREE;
-			Ancestor = l;
-			preorder(l, pbuf);
-			strcpy(pbuf, "%s");
-		}
-	}
-	fflush(stdout);
-	fflush(stderr);
-}
-
-/*
- * preorder traversal of shortest path tree.
- */
-STATIC void
-preorder(l, ppath)
-	register link *l;
-	char *ppath;
-{	register node *n;
-	node *ncp;		/* circular copy list */
-	Cost cost;
-	char npath[PATHSIZE];
-	short p_dir;		/* DIR bits of parent (for nets) */
-	char p_op;		/* net op of parent (for nets) */
-
-	setpath(l, ppath, npath);
-	n = l->l_to;
-	if (printable(n)) {
-		if (Fflag)
-			cost = Ancestor->l_to->n_cost;
-		else
-			cost = n->n_cost;
-		if (ISADOMAIN(n))
-			printdomain(n, npath, cost);
-		else if (!(n->n_flag & NNET)) {
-			printhost(n, npath, cost);
-		}
-		n->n_flag |= PRINTED;
-		for (ncp = n->n_copy; ncp != n; ncp = ncp->n_copy)
-			ncp->n_flag |= PRINTED;
-	}
-
-	/* prepare routing bits for domain members */
-	p_dir = l->l_flag & LDIR;
-	p_op = l->l_netop;
-
-	/* recursion */
-	for (l = n->n_link; l; l = l->l_next) {
-		if (!(l->l_flag & LTREE))
-			continue;
-		/* network member inherits the routing syntax of its gateway */
-		if (ISANET(n)) {
-			l->l_flag = (l->l_flag & ~LDIR) | p_dir;
-			l->l_netop = p_op;
-		}
-		l->l_flag &= ~LTREE;
-		preorder(l, npath);
-	}
-}
-
-STATIC int
-printable(n)
-	register node *n;
-{	node *ncp;
-	link *l;
-
-	if (n->n_flag & PRINTED)
-		return 0;
-
-	/* is there a cheaper copy? */
-	for (ncp = n->n_copy; n != ncp; ncp = ncp->n_copy) {
-		if (!(ncp->n_flag & MAPPED))
-			continue;	/* unmapped copy */
-
-		if (n->n_cost > ncp->n_cost)
-			return 0;	/* cheaper copy */
-
-		if (n->n_cost == ncp->n_cost && !(ncp->n_flag & NTERMINAL))
-			return 0;	/* synthetic copy */
-	}
-
-	/* will a domain route suffice? */
-	if (Dflag && !ISANET(n) && ISADOMAIN(n->n_parent)) {
-		/*
-		 * are there any interesting links?  a link
-		 * is interesting if it doesn't point back
-		 * to the parent, and is not an alias.
-		 */
-
-		/* check n */
-		for (l = n->n_link; l; l = l->l_next) {
-			if (l->l_to == n->n_parent)
-				continue;
-			if (!(l->l_flag & LALIAS))
-				return 1;
-		}
-
-		/* check copies of n */
-		for (ncp = n->n_copy; ncp != n; ncp = ncp->n_copy) {
-			for (l = ncp->n_link; l; l = l->l_next) {
-				if (l->l_to == n->n_parent)
-					continue;
-				if (!(l->l_flag & LALIAS))
-					return 1;
-			}
-		}
-
-		/* domain route suffices */
-		return 0;
-	}
-	return 1;
-}
-
-STATIC void
-setpath(l, ppath, npath) 
-	link *l;
-	register char *ppath, *npath;
-{	register node *next, *parent;
-	char netchar;
-
-	next = l->l_to;
-	parent = next->n_parent;
-	netchar = NETCHAR(l);
-
-	/* for magic @->% conversion */
-	if (parent->n_flag & ATSIGN)
-		next->n_flag |= ATSIGN;
-
-	/*
-	 * i've noticed that distant gateways to domains frequently get
-	 * ...!gateway!user@dom.ain wrong.  ...!gateway!user%dom.ain
-	 * seems to work, so if next is a domain and the parent is
-	 * not the local host, force a magic %->@ conversion.  in this
-	 * context, "parent" is the nearest ancestor that is not a net.
-	 */
-	while (ISANET(parent))
-		parent = parent->n_parent;
-	if (ISADOMAIN(next) && parent != Home)
-		next->n_flag |= ATSIGN;
-
-	/*
-	 * special handling for nets (including domains) and aliases.
-	 * part of the trick is to treat aliases to domains as 0 cost
-	 * links.  (the author believes they should be declared as such
-	 * in the input, but the world disagrees).
-	 */
-	if (ISANET(next) || ((l->l_flag & LALIAS) && !ISADOMAIN(parent))) {
-		strcpy(npath, ppath);
-		return;
-	}
-		
-	if (netchar == '@')
-		if (next->n_flag & ATSIGN)
-			netchar = '%';	/* shazam?  shaman? */
-		else
-			next->n_flag |= ATSIGN;
-
-	/* remainder should be a sprintf -- foo on '%' as an operator */
-	for ( ; (*npath = *ppath) != 0; ppath++) {
-		if (*ppath == '%') {
-			switch(ppath[1]) {
-			case 's':
-				ppath++;
-				npath = hostpath(npath, l, netchar);
-				break;
-
-			case '%':
-				*++npath = *++ppath;
-				npath++;
-				break;
-
-			default:
-				die("unknown escape in setpath");
-				break;
-			}
-		} else
-			npath++;
-	}
-}
-
-STATIC char *
-hostpath(path, l, netchar)
-	register char *path;
-	register link *l;
-	char netchar;
-{	register node *prev;
-
-	prev = l->l_to->n_parent;
-	if (NETDIR(l) == LLEFT) {
-		/* host!%s */
-		strcpy(path, l->l_to->n_name);
-		path += strlen(path);
-		while (ISADOMAIN(prev)) {
-			strcpy(path, prev->n_name);
-			path += strlen(path);
-			prev = prev->n_parent;
-		}
-		*path++ = netchar;
-		if (netchar == '%')
-			*path++ = '%';
-		*path++ = '%';
-		*path++ = 's';
-	} else {
-		/* %s@host */
-		*path++ = '%';
-		*path++ = 's';
-		*path++ = netchar;
-		if (netchar == '%')
-			*path++ = '%';
-		strcpy(path, l->l_to->n_name);
-		path += strlen(path);
-		while (ISADOMAIN(prev)) {
-			strcpy(path, prev->n_name);
-			path += strlen(path);
-			prev = prev->n_parent;
-		}
-	}
-	return path;
-}
-
-STATIC void
-printhost(n, path, cost)
-	register node *n;
-	char *path;
-	Cost cost;
-{
-	if (n->n_flag & PRINTED)
-		die("printhost called twice");
-	n->n_flag |= PRINTED;
-	/* skip private hosts */
-	if ((n->n_flag & ISPRIVATE) == 0) {
-		if (Cflag)
-			printf("%ld\t", (long) cost);
-		fputs(n->n_name, stdout);
-		putchar('\t');
-		puts(path);
-	}
-}
-
-STATIC void
-printdomain(n, path, cost)
-	register node *n;
-	char *path;
-	Cost cost;
-{	node *p;
-
-	if (n->n_flag & PRINTED)
-		die("printdomain called twice");
-	n->n_flag |= PRINTED;
-
-	/*
-	 * print a route for dom.ain if it is a top-level domain, unless
-	 * it is private.
-	 *
-	 * print a route for sub.dom.ain only if all its ancestor dom.ains
-	 * are private and sub.dom.ain is not private.
-	 */
-	if (!ISADOMAIN(n->n_parent)) {
-		/* top-level domain */
-		if (n->n_flag & ISPRIVATE) {
-			vprintf(stderr, "ignoring private top-level domain %s\n", n->n_name);
-			return;
-		}
-	} else {
-		/* subdomain */
-		for (p = n->n_parent; ISADOMAIN(p); p = p->n_parent)
-			if (!(p->n_flag & ISPRIVATE))
-				return;
-		if (n->n_flag & ISPRIVATE)
-			return;
-	}
-
-	/* print it (at last!) */
-	if (Cflag)
-		printf("%ld\t", (long) cost);
-	do {
-		fputs(n->n_name, stdout);
-		n = n->n_parent;
-	} while (ISADOMAIN(n));
-	putchar('\t');
-	puts(path);
-}
//GO.SYSIN DD printit.c
echo parse.y 1>&2
sed 's/^-//' >parse.y <<'//GO.SYSIN DD parse.y'
-%{
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)parse.y	9.10 88/09/07";
-#endif /* lint */
-
-#include "def.h"
-
-/* scanner states (yylex, parse) */
-#define OTHER		0
-#define COSTING		1
-#define NEWLINE		2
-#define FILENAME	3
-
-/* exports */
-long Tcount;
-extern void yyerror();
-
-/* imports */
-extern node *addnode(), *addprivate();
-extern void fixprivate(), alias(), deadlink(), deletelink();
-extern link *addlink();
-extern int strcmp();
-extern char *strsave();
-extern int optind;
-extern char *Cfile, *Netchars, **Argv;
-extern int Lineno, Argc;
-
-/* privates */
-STATIC void fixnet(), adjust();
-STATIC int yylex(), yywrap(), getword();
-static int Scanstate = NEWLINE;	/* scanner (yylex) state */
-
-/* flags for ys_flags */
-#define TERMINAL 1
-%}
-
-%union {
-	node	*y_node;
-	Cost	y_cost;
-	char	y_net;
-	char	*y_name;
-	struct {
-		node *ys_node;
-		Cost ys_cost;
-		short ys_flag;
-		char ys_net;
-		char ys_dir;
-	} y_s;
-}
-
-%type <y_s>	site asite
-%type <y_node>	links aliases plist network nlist host nhost
-%type <y_node>	usite delem dlist
-%type <y_cost>	cost cexpr
-
-%token <y_name>	SITE HOST STRING
-%token <y_cost>	COST
-%token <y_net>	NET
-%token EOL PRIVATE DEAD DELETE FILETOK ADJUST
-
-%left	'+' '-'
-%left	'*' '/'
-
-%%
-map	:	/* empty */
-	|	map		EOL
-	|	map links	EOL
-	|	map aliases	EOL
-	|	map network	EOL
-	|	map private	EOL
-	|	map dead	EOL
-	|	map delete	EOL
-	|	map file	EOL
-	|	map adjust	EOL
-	|	error		EOL
-	;
-
-links	: host site cost {
-		struct link *l;
-
-		l = addlink($1, $2.ys_node, $3, $2.ys_net, $2.ys_dir);
-		if (GATEWAYED($2.ys_node))
-			l->l_flag |= LGATEWAY;
-		if ($2.ys_flag & TERMINAL)
-			l->l_flag |= LTERMINAL;
-	  }			
-	| links ',' site cost {
-		struct link *l;
-
-		l = addlink($1, $3.ys_node, $4, $3.ys_net, $3.ys_dir);
-		if (GATEWAYED($3.ys_node))
-			l->l_flag |= LGATEWAY;
-		if ($3.ys_flag & TERMINAL)
-			l->l_flag |= LTERMINAL;
-	  }
-	| links ','	/* benign error */
-	;
-
-host	: HOST		{$$ = addnode($1);}
-	| PRIVATE	{$$ = addnode("private");}
-	| DEAD		{$$ = addnode("dead");}
-	| DELETE	{$$ = addnode("delete");}
-	| FILETOK	{$$ = addnode("file");}
-	| ADJUST	{$$ = addnode("adjust");}
-	;
-
-site	: asite {
-		$$ = $1;
-		$$.ys_net = DEFNET;
-		$$.ys_dir = DEFDIR;
-	  }
-	| NET asite {
-		$$ = $2;
-		$$.ys_net = $1;
-		$$.ys_dir = LRIGHT;
-	  }
-	| asite NET {
-		$$ = $1;
-		$$.ys_net = $2;
-		$$.ys_dir = LLEFT;
-	  }
-	;
-
-asite	: SITE {
-		$$.ys_node = addnode($1);
-		$$.ys_flag = 0;
-	  }
-	| '<' SITE '>' {
-		Tcount++;
-		$$.ys_node = addnode($2);
-		$$.ys_flag = TERMINAL;
-	  }
-	;
-
-aliases	: host '=' SITE	{alias($1, addnode($3));}
-	| aliases ',' SITE	{alias($1, addnode($3));}
-	| aliases ','	/* benign error */
-	;
-
-network	: nhost '{' nlist '}' cost	{fixnet($1, $3, $5, DEFNET, DEFDIR);}
-	| nhost NET '{' nlist '}' cost	{fixnet($1, $4, $6, $2, LRIGHT);}
-	| nhost '{' nlist '}' NET cost	{fixnet($1, $3, $6, $5, LLEFT);}
-	;
-
-nhost	: '='		{$$ = 0;	/* anonymous net */}
-	| host '='	{$$ = $1;	/* named net */}
-	;
-
-nlist	: SITE		{$$ = addnode($1);}
-	| nlist ',' SITE {
-		node *n;
-
-		n = addnode($3);
-		if (n->n_net == 0) {
-			n->n_net = $1;
-			$$ = n;
-		}
-	  }
-	| nlist ','	/* benign error */
-	;
-		
-private	: PRIVATE '{' plist '}'			/* list of privates */
-	| PRIVATE '{' '}'	{fixprivate();}	/* end scope of privates */
-	;
-
-plist	: SITE			{addprivate($1)->n_flag |= ISPRIVATE;}
-	| plist ',' SITE	{addprivate($3)->n_flag |= ISPRIVATE;}
-	| plist ','		/* benign error */
-	;
-
-dead	: DEAD '{' dlist '}';
-
-dlist	: delem
-	| dlist ',' delem
-	| dlist ','		/* benign error */
-	;
-
-delem	: SITE			{deadlink(addnode($1), (node *) 0);}
-	| usite NET usite	{deadlink($1, $3);}
-	;
-
-usite	: SITE	{$$ = addnode($1);} ;	/* necessary unit production */
-
-delete	: DELETE '{' dellist '}';
-
-dellist	: delelem
-	| dellist ',' delelem
-	| dellist ','		/* benign error */
-	;
-
-delelem	: SITE {
-		node *n;
-
-		n = addnode($1);
-		deletelink(n, (node *) 0);
-		n->n_flag |= ISPRIVATE;
-	  }
-	| usite NET usite	{deletelink($1, $3);}
-	;
-
-file	: FILETOK '{' {Scanstate = FILENAME;} STRING {Scanstate = OTHER;} '}' {
-		Lineno = 0;
-		Cfile = strsave($4);
-	}
-
-adjust	: ADJUST '{' adjlist '}' ;
-
-adjlist	: adjelem
-	| adjlist ',' adjelem
-	| adjlist ','		/* benign error */
-	;
-
-adjelem	: usite cost	{adjust($1, $2);} ;
-
-cost	: {$$ = DEFCOST;	/* empty -- cost is always optional */}
-	| '(' {Scanstate = COSTING;} cexpr {Scanstate = OTHER;} ')'
-		{$$ = $3;}
-	;
-
-cexpr	: COST
-	| '-' cexpr	  {$$ = -$2;}
-	| '(' cexpr ')'   {$$ = $2;}
-	| cexpr '+' cexpr {$$ = $1 + $3;}
-	| cexpr '-' cexpr {$$ = $1 - $3;}
-	| cexpr '*' cexpr {$$ = $1 * $3;}
-	| cexpr '/' cexpr {
-		if ($3 == 0)
-			yyerror("zero divisor\n");
-		else
-			$$ = $1 / $3;
-	  }
-	;
-%%
-
-void
-#ifdef YYDEBUG
-/*VARARGS1*/
-yyerror(fmt, arg)
-	char *fmt, *arg;
-#else
-yyerror(s)
-	char *s;
-#endif
-{
-	/* a concession to bsd error(1) */
-	fprintf(stderr, "\"%s\", ", Cfile);
-#ifdef YYDEBUG
-	fprintf(stderr, "line %d: ", Lineno);
-	fprintf(stderr, fmt, arg);
-	putc('\n', stderr);
-#else
-	fprintf(stderr, "line %d: %s\n", Lineno, s);
-#endif
-}
-
-/*
- * patch in the costs of getting on/off the network.
- *
- * for each network member on netlist, add links:
- *	network -> member	cost = 0;
- *	member -> network	cost = parameter.
- *
- * if network and member both require gateways, assume network
- * is a gateway to member (but not v.v., to avoid such travesties
- * as topaz!seismo.css.gov.edu.rutgers).
- *
- * note that members can have varying costs to a network, by suitable
- * multiple declarations.  this is a feechur, albeit a useless one.
- */
-STATIC void
-fixnet(network, nlist, cost, netchar, netdir)
-	register node *network;
-	node *nlist;
-	Cost cost;
-	char netchar, netdir;
-{	register node *member, *nextnet;
-	link *l;
-	static int netanon = 0;
-	char anon[25];
-
-	if (network == 0) {
-		sprintf(anon, "[unnamed net %d]", netanon++);
-		network = addnode(anon);
-	}
-	network->n_flag |= NNET;
-
-	/* insert the links */
-	for (member = nlist ; member; member = nextnet) {
-
-		/* network -> member, cost is 0 */
-		l = addlink(network, member, (Cost) 0, netchar, netdir);
-		if (GATEWAYED(network) && GATEWAYED(member))
-			l->l_flag |= LGATEWAY;
-
-		/* member -> network, cost is parameter */
-		/* never ever ever crawl up from a domain*/
-		if (!ISADOMAIN(network))
-			(void) addlink(member, network, cost, netchar, netdir);
-
-		nextnet = member->n_net;
-		member->n_net = 0;	/* clear for later use */
-	}
-}
-
-/* scanner */
-
-#define QUOTE '"'
-#define STR_EQ(s1, s2) (s1[2] == s2[2] && strcmp(s1, s2) == 0)
-#define NLRETURN() {Scanstate = NEWLINE; return EOL;}
-
-static struct ctable {
-	char *cname;
-	Cost cval;
-} ctable[] = {
-	/* ordered by frequency of appearance in a "typical" dataset */
-	{"DIRECT", 200},
-	{"DEMAND", 300},
-	{"DAILY", 5000},
-	{"HOURLY", 500},
-	{"DEDICATED", 100},
-	{"EVENING", 2000},
-	{"LOCAL", 25},
-	{"LOW", 5},	/* baud rate, quality penalty */
-	{"DEAD", MILLION},
-	{"POLLED", 5000},
-	{"WEEKLY", 30000},
-	{"HIGH", -5},	/* baud rate, quality bonus */
-	{"FAST", -80},	/* high speed (>= 9.6 kbps) modem */
-	/* deprecated */
-	{"ARPA", 100},
-	{"DIALED", 300},
-	{0, 0}
-};
-
-STATIC int
-yylex()
-{	static char retbuf[128];	/* for return to yacc part */
-	register int c;
-	register char *buf = retbuf;
-	register struct ctable *ct;
-	register Cost cost;
-	char errbuf[128];
-
-	if (feof(stdin) && yywrap())
-		return EOF;
-
-	/* count lines, skip over space and comments */
-	if ((c = getchar()) == EOF)
-		NLRETURN();
-    
-continuation:
-	while (c == ' ' || c == '\t')
-		if ((c = getchar()) == EOF)
-			NLRETURN();
-
-	if (c == '#')
-		while ((c = getchar()) != '\n')
-			if (c == EOF)
-				NLRETURN();
-
-	/* scan token */
-	if (c == '\n') {
-		Lineno++;
-		if ((c = getchar()) != EOF) {
-			if (c == ' ' || c == '\t')
-				goto continuation;
-			ungetc(c, stdin);
-		}
-		NLRETURN();
-	}
-
-	switch(Scanstate) {
-	case COSTING:
-		if (isdigit(c)) {
-			cost = c - '0';
-			for (c = getchar(); isdigit(c); c = getchar())
-				cost = (cost * 10) + c - '0';
-			ungetc(c, stdin);
-			yylval.y_cost = cost;
-			return COST;
-		}
-
-		if (getword(buf, c) == 0) {
-			for (ct = ctable; ct->cname; ct++)
-				if (STR_EQ(buf, ct->cname)) {
-					yylval.y_cost = ct->cval;
-					return COST;
-				}
-			sprintf(errbuf, "unknown cost (%s), using default", buf);
-			yyerror(errbuf);
-			yylval.y_cost = DEFCOST;
-			return COST;
-		}
-
-		return c;	/* pass the buck */
-
-	case NEWLINE:
-		Scanstate = OTHER;
-		if (getword(buf, c) != 0)
-			return c;
-		/*
-		 * special purpose tokens.
-		 *
-		 * the "switch" serves the dual-purpose of recognizing
-		 * unquoted tokens only.
-		 */
-		switch(c) {
-		case 'p':
-			if (STR_EQ(buf, "private"))
-				return PRIVATE;
-			break;
-		case 'd':
-			if (STR_EQ(buf, "dead"))
-				return DEAD;
-			if (STR_EQ(buf, "delete"))
-				return DELETE;
-			break;
-		case 'f':
-			if (STR_EQ(buf, "file"))
-				return FILETOK;
-			break;
-		case 'a':
-			if (STR_EQ(buf, "adjust"))
-				return ADJUST;
-			break;
-		}
-
-		yylval.y_name = buf;
-		return HOST;
-
-	case FILENAME:
-		while (c != EOF && isprint(c)) {
-			if (c == ' ' || c == '\t' || c == '\n' || c == '}')
-				break;
-			*buf++ = c;
-			c = getchar();
-		}
-		if (c != EOF)
-			ungetc(c, stdin);
-		*buf = 0;
-		yylval.y_name = retbuf;
-		return STRING;
-	}
-
-	if (getword(buf, c) == 0) {
-		yylval.y_name = buf;
-		return SITE;
-	}
-
-	if (index(Netchars, c)) {
-		yylval.y_net = c;
-		return NET;
-	}
-
-	return c;
-}
-
-/*
- * fill str with the next word in [0-9A-Za-z][-._0-9A-Za-z]+ or a quoted
- * string that contains no newline.  return -1 on failure or EOF, 0 o.w.
- */ 
-STATIC int
-getword(str, c)
-	register char *str;
-	register int c;
-{
-	if (c == QUOTE) {
-		while ((c = getchar()) != QUOTE) {
-			if (c == '\n') {
-				yyerror("newline in quoted string\n");
-				ungetc(c, stdin);
-				return -1;
-			}
-			if (c == EOF) {
-				yyerror("EOF in quoted string\n");
-				return -1;
-			}
-			*str++ = c;
-		}
-		*str = 0;
-		return 0;
-	}
-
-	/* host name must start with alphanumeric or `.' */
-	if (!isalnum(c) && c != '.')
-		return -1;
-
-yymore:
-	do {
-		*str++ = c;
-		c = getchar();
-	} while (isalnum(c) || c == '.' || c == '_');
-
-	if (c == '-' && Scanstate != COSTING)
-		goto yymore;
-
-	ungetc(c, stdin);
-	*str = 0;
-	return 0;
-}
-
-STATIC int
-yywrap()
-{	char errbuf[100];
-
-	fixprivate();	/* munge private host definitions */
-	Lineno = 1;
-	while (optind < Argc) {
-		if (freopen((Cfile = Argv[optind++]), "r", stdin) != 0)
-			return 0;
-		sprintf(errbuf, "%s: %s", Argv[0], Cfile);
-		perror(errbuf);
-	}
-	freopen("/dev/null", "r", stdin);
-	return -1;
-}
-
-STATIC void
-adjust(n, cost)
-	node *n;
-	Cost cost;
-{	link *l;
-
-	n->n_cost += cost;	/* cumulative */
-
-	/* hit existing links */
-	for (l = n->n_link; l; l = l->l_next) {
-		if ((l->l_cost += cost) < 0) {
-			char buf[100];
-
-			l->l_flag |= LDEAD;
-			sprintf(buf, "link to %s deleted with negative cost",
-							l->l_to->n_name);
-			yyerror(buf);
-		}
-	}
-}
//GO.SYSIN DD parse.y
echo makedb.c 1>&2
sed 's/^-//' >makedb.c <<'//GO.SYSIN DD makedb.c'
-/* pathalias -- by steve bellovin, as told to peter honeyman */
-#ifndef lint
-static char	*sccsid = "@(#)makedb.c	9.1 87/10/04";
-#endif /* lint */
-
-#include <stdio.h>
-#include "config.h"
-
-typedef struct {
-	char *dptr;
-	int dsize;
-} datum;
-
-char *Ofile = ALIASDB, *ProgName;
-
-#define USAGE "%s [-o dbmname] [-a] [file ...]\n"
-
-main(argc, argv)
-	char *argv[];
-{	char *ofptr;
-	int c, append = 0;
-	extern int optind;
-	extern char *optarg;
-
-	ProgName = argv[0];
-	while ((c = getopt(argc, argv, "o:a")) != EOF)
-		switch(c) {
-		case 'o':	/* dbm output file */
-			Ofile = optarg;
-			break;
-
-		case 'a':	/* append mode */
-			append++;
-			break;
-
-		default:
-			fprintf(stderr, USAGE, ProgName);
-			exit(1);
-			break;
-		}
-
-
-	if ((ofptr = rindex(Ofile, '/')) != 0)
-		ofptr++;
-	else
-		ofptr = Ofile;
-	if (strlen(ofptr) > 10) {
-		ofptr[10] = 0;
-		fprintf(stderr, "%s: using %s for dbm output\n", ProgName, Ofile);
-	}
-
-	if (append == 0 && dbfile(Ofile) != 0) {
-		perror_(Ofile);
-		exit(1);
-	}
-
-	if (dbminit(Ofile) < 0) {
-		perror_(Ofile);
-		exit(1);
-	}
-
-	if (optind == argc)
-		makedb((char *) 0);
-	else for ( ; optind < argc; optind++)
-		makedb(argv[optind]);
-	exit(0);
-}
-
-dbfile(dbf)
-	char *dbf;
-{
-	return (dbcreat(dbf, "dir") != 0 || dbcreat(dbf, "pag") != 0);
-}
-
-dbcreat(dbf, suffix)
-	char *dbf, *suffix;
-{	char buf[BUFSIZ];
-	int fd;
-
-	(void) sprintf(buf, "%s.%s", dbf, suffix);
-	if ((fd = creat(buf, 0666)) < 0)
-		return(-1);
-	(void) close(fd);
-	return(0);
-}
-
-
-makedb(ifile)
-	char *ifile;
-{	char line[BUFSIZ];
-	datum key, val;
-
-	if (ifile && (freopen(ifile, "r", stdin) == NULL)) {
-		perror_(ifile);
-		return;
-	}
-
-	/*
-	 * keys and values are 0 terminated.  this wastes time and (disk) space,
-	 * but does lend simplicity and backwards compatibility.
-	 */
-	key.dptr = line;
-	while (fgets(line, sizeof(line), stdin) != NULL) {
-		char *op, *end;
-
-		end = line + strlen(line);
-		end[-1] = 0;	/* kill newline, stuff null terminator */
-		op = index(line, '\t');
-		if (op != 0) {
-			*op++ = 0;
-			key.dsize = op - line;		/* 0 terminated */
-			val.dptr = op;
-			val.dsize = end - op;		/* 0 terminated */
-		} else {
-			key.dsize = end - line;		/* 0 terminated */
-			val.dptr = "\0";		/* why must i do this? */
-			val.dsize = 1;
-		}
-		if (store(key, val) < 0)
-			perror_(Ofile);
-	}
-}
-
-perror_(str)
-	char	*str;
-{
-	fprintf(stderr, "%s: ", ProgName);
-	perror(str);
-}
//GO.SYSIN DD makedb.c
echo arpatxt.c 1>&2
sed 's/^-//' >arpatxt.c <<'//GO.SYSIN DD arpatxt.c'
-#ifndef lint
-static char *sccsid = "@(#)arpatxt.c	9.4 88/09/21";
-#endif
-
-/*
- * convert hosts.txt into pathalias format.
- *
- * alias rule: "host.dom.ain,nickname.arpa,..." -> host = nickname, ...
- */
-
-/* remove the next line for standard or research unix */
-#define BSD
-
-#ifdef BSD
-#define strchr index
-#endif /* BSD */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* imports */
-extern char *re_comp(), *malloc(), *strchr(), *calloc();
-extern char *gets(), *strcpy(), *fgets();
-extern FILE *fopen();
-
-typedef struct node node;
-
-struct node {
-	node *child;	/* subdomain or member host */
-	node *parent;	/* parent domain */
-	node *next;	/* sibling in domain tree or host list */
-	char *name;	/* host name */
-	node *alias;	/* list of aliases */
-	node *bucket;
-	node *gateway;
-	int  flag;
-};
-
-node *Top;
-int Atflag, Fflag, Iflag, Vflag;
-char *DotArpa = ".ARPA";
-char Fname[256], *Fstart;
-
-node *newnode(), *find();
-char *strsave(), *lowercase();
-void crcinit();
-long fold();
-FILE *mkfile();
-int insert();
-
-#define ISADOMAIN(n) ((n) && *((n)->name) == '.')
-
-/* for node.flag */
-#define COLLISION 1
-
-/* for formatprint() */
-#define PRIVATE		0
-#define HOSTS		1
-#define SUBDOMAINS	2
-
-/* for usage() */
-#define USAGE "usage: %s [-i@] [-g gateway] [-p privatefile] [-f | -d directory] [file ...]\n"
-
-main(argc, argv)
-	char **argv;
-{	int c;
-	char *progname;
-	extern char *optarg;
-	extern int optind;
-
-	if ((progname = strchr(argv[0], '/')) != 0)
-		progname++;
-	else
-		progname = argv[0];
-	crcinit();
-
-	Top = newnode();	/* needed for adding gateways */
-	while ((c = getopt(argc, argv, "d:fg:ip:v@")) != EOF)
-		switch(c) {
-		case 'd':
-			strcpy(Fname, optarg);
-			break;
-		case 'f':	/* filter mode -- write on stdout */
-			Fflag++;
-			break;
-		case 'g':
-			gateway(optarg);
-			break;
-		case 'i':
-			Iflag++;
-			break;
-		case 'p':
-			readprivates(optarg);
-			break;
-		case 'v':
-			Vflag++;
-			break;
-		case '@':
-			Atflag++;
-			break;
-		default:
-			usage(progname);
-		}
-
-	if (Fflag && *Fname)
-		usage(progname);
-	if (Iflag)
-		(void) lowercase(DotArpa);
-	if (Top->gateway == 0)
-		fprintf(stderr, "%s: warning: no gateway to top level domains\n", progname);
-
-	Fstart = Fname + strlen(Fname);
-	if (Fstart != Fname) {
-		*Fstart++ = '/';
-		*Fstart = 0;
-	}
-	/* should do the mkdir here instead of the shell script ...*/
-		
-	Top->name = "internet";
-	if (optind == argc)
-		scan();
-	else for ( ; optind < argc; optind++) {
-		if (freopen(argv[optind], "r", stdin) == 0) {
-			perror(argv[optind]);
-			continue;
-		}
-		scan();
-	}
-	setuniqflag(Top);	/* look for and mark collisions */
-	hashanalyze();		/* check hash algorithm performance */
-	merge();		/* make unique domain names */
-	dump(Top);		/* print */
-	return 0;
-}
-
-scan()
-{	static first;
-	char buf0[BUFSIZ], buf1[BUFSIZ], buf2[BUFSIZ];
-
-	if (first++ == 0)
-		(void) re_comp("^HOST.*SMTP");
-	while (gets(buf0) != 0) {
-		if (re_exec(buf0) == 0)
-			continue;
-		if (sscanf(buf0, "HOST : %[^:] : %[^: ]", buf1, buf2) != 2)
-			continue;
-		if (Iflag)
-			(void) lowercase(buf2);
-		if (insert(buf2) != 0)
-			fprintf(stderr, "input error: %s\n", buf0);
-	}
-}
-/*
- * format of private file:
- *	one per line, optionally followed by white space and comments
- *	line starting with # is comment
- */
-readprivates(pfile)
-	char *pfile;
-{	FILE *f;
-	node *n;
-	char buf[BUFSIZ], *bptr;
-
-	if ((f = fopen(pfile, "r")) == 0) {
-		perror(pfile);
-		return;
-	}
-	while (fgets(buf, BUFSIZ, f) != 0) {
-		if (*buf == '#')
-			continue;
-		if ((bptr = strchr(buf, ' ')) != 0)
-			*bptr = 0;
-		if ((bptr = strchr(buf, '\t')) != 0)
-			*bptr = 0;
-		if (*buf == 0)
-			continue;
-		n = newnode();
-		n->name = strsave(buf);
-		hash(n);
-	}
-	(void) fclose(f);
-}
-usage(progname)
-	char *progname;
-{
-	fprintf(stderr, USAGE, progname);
-	exit(1);
-}
-
-dumpgateways(ndom, f)
-	node *ndom;
-	FILE *f;
-{	node *n;
-
-	for (n = ndom->gateway; n; n = n->next) {
-		fprintf(f, "%s ", n->name);
-		if (Atflag)
-			putc('@', f);
-		fprintf(f, "%s(%s)\t# gateway\n", ndom->name,
-				ndom == Top ? "DEDICATED" : "LOCAL");
-	}
-}
-
-gateway(buf)
-	char *buf;
-{	node *n, *dom;
-	char *dot;
-
-	dot = strchr(buf, '.');
-	if (dot) {
-		dom = find(dot);
-		*dot = 0;
-	} else
-		dom = Top;
-
-	n = newnode();
-	n->name = strsave(buf);
-	n->next = dom->gateway;
-	dom->gateway = n;
-}
-	
-int
-insert(buf)
-	char *buf;
-{	char host[BUFSIZ], *hptr, *dot;
-	node *n;
-
-	for (hptr = host; *hptr = *buf++; hptr++)
-		if (*hptr == ',')
-			break;
-
-	if (*hptr == ',')
-		*hptr = 0;
-	else
-		buf = 0;	/* no aliases */
-
-	if ((dot = strchr(host, '.')) == 0)
-		return 1;	/* can't happen */
-	
-	if (strcmp(dot, DotArpa) == 0)
-		buf = 0;		/* no aliases */
-
-	n = find(dot);
-	*dot = 0;
-
-	addchild(n, host, buf);
-	return 0;
-}
-
-node *
-find(domain)
-	char *domain;
-{	char *dot;
-	node *parent, *child;
-
-	if (domain == 0)
-		return Top;
-	if ((dot = strchr(domain+1, '.')) != 0) {
-		parent = find(dot);
-		*dot = 0;
-	} else
-		parent = Top;
-
-	for (child = parent->child; child; child = child->next)
-		if (strcmp(domain, child->name) == 0)
-			break;
-	if (child == 0) {
-		child = newnode();
-		child->next = parent->child;
-		parent->child = child;
-		child->parent = parent;
-		child->name = strsave(domain);
-	}
-	return child;
-}
-
-node *
-newnode()
-{
-	node *n;
-
-	if ((n = (node *) calloc(1, sizeof(node))) == 0)
-		abort();
-	return n;
-}
-
-char *
-strsave(buf)
-	char *buf;
-{	char *mstr;
-
-	if ((mstr = malloc(strlen(buf)+1)) == 0)
-		abort();
-	strcpy(mstr, buf);
-	return mstr;
-}
-
-addchild(n, host, aliases)
-	node *n;
-	char *host, *aliases;
-{	node *child;
-
-	/* check for dups?  nah! */
-	child = newnode();
-	child->name = strsave(host);
-	child->parent = n;
-	child->next = n->child;
-	makealiases(child, aliases);
-	n->child = child;
-}
-
-/* yer basic tree walk to make output */
-dump(n)
-	node *n;
-{	node *child;
-	FILE *f;
-	int privates;
-
-	/* sanity check */
-	if (n != Top && ! ISADOMAIN(n))
-		abort();
-
-	f = mkfile(n);		/* prepare the output file */
-	privates = domprint(n, f);		/* print this domain */
-	dumpgateways(n, f);	/* print any gateways to this domain */
-	if (privates || n == Top)
-		fputs("private {}\n", f);	/* end scope of privates */
-	if (Fflag)
-		putc('\n', f);
-	else
-		(void) fclose(f);
-	for (child = n->child; child; child = child->next)
-		if (child->child)
-			dump(child);
-}
-
-qcmp(a, b)
-	node **a, **b;
-{
-	return strcmp((*a)->name, (*b)->name);
-}
-
-domprint(n, f)
-	node *n;
-	FILE *f;
-{	node *table[8191], *child, *alias;
-	char *cost = 0;
-	int nelem, i, privates = 0;
-
-	/*
-	 * dump private definitions.  
-	 * sort hosts and aliases for pretty output.
-	 */
-	if (n != Top) {
-		i = 0;
-		for (child = n->child; child; child = child->next) {
-			table[i++] = child;
-			for (alias = child->alias; alias; alias = alias->next)
-				table[i++] = alias;
-		}
-
-		qsort((char *) table, i, sizeof(table[0]), qcmp);
-		privates = formatprint(f, table, i, PRIVATE, "private", cost);
-	}
-
-	/* dump domains and aliases, sorted for pretty output */
-	i = 0;
-	for (child = n->child; child; child = child->next)
-		table[i++] = child;
-	qsort((char *) table, i, sizeof(table[0]), qcmp);
-
-	/* cost is DEDICATED for hosts in top-level domains, LOCAL o.w. */
-	if (n->parent == Top && strchr(n->name + 1, '.') == 0)
-		cost = "DEDICATED";
-	else
-		cost = "LOCAL";
-
-	(void) formatprint(f, table, i, HOSTS, n->name, cost);
-	(void) formatprint(f, table, i, SUBDOMAINS, n->name, "0");
-
-	/* dump aliases */
-	nelem = i;
-	for (i = 0; i < nelem; i++) {
-		if ((alias = table[i]->alias) == 0)
-			continue;
-		fprintf(f, "%s = %s", table[i]->name, alias->name);
-		for (alias = alias->next; alias; alias = alias->next)
-			fprintf(f, ", %s", alias->name);
-		putc('\n', f);
-	}
-	return privates;
-}
-
-int
-formatprint(f, table, nelem, type, lhs, cost)
-	FILE *f;
-	node **table;
-	char *lhs, *cost;
-{	int i, didprint;
-	char buf[128], *bptr;
-
-	sprintf(buf, "%s%s{" /*}*/, lhs, type == PRIVATE ? " " : " = ");
-	bptr = buf + strlen(buf);
-
-	didprint = 0;
-	for (i = 0; i < nelem; i++) {
-		if (type == PRIVATE && ! (table[i]->flag & COLLISION))
-			continue;
-		else if (type == HOSTS && ISADOMAIN(table[i]) )
-			continue;
-		else if (type == SUBDOMAINS && ! ISADOMAIN(table[i]) )
-			continue;
-
-		if ((bptr - buf) + strlen(table[i]->name) > 69) {
-			*bptr = 0;
-			fprintf(f, "%s\n ", buf);	/* continuation */
-			bptr = buf;
-		}
-		sprintf(bptr, "%s, ", table[i]->name);
-		bptr += strlen(bptr);
-		didprint++;
-	}
-	*bptr = 0;
-
-	if (didprint) {
-		fprintf(f, /*{*/ "%s}", buf);
-		if (type != PRIVATE)
-			fprintf(f, "(%s)", cost);
-		putc('\n', f);
-	}
-	return didprint;
-}
-
-FILE *				
-mkfile(n)
-	node *n;
-{	node *parent;
-	char *bptr;
-	FILE *f;
-
-	/* build up the domain name in Fname[] */
-	bptr = Fstart;
-	if (n == Top)
-		strcpy(bptr, n->name);
-	else {
-		strcpy(bptr, n->name + 1);	/* skip leading dot */
-		bptr = bptr + strlen(bptr);
-		parent = n->parent;
-		while (ISADOMAIN(parent)) {
-			strcpy(bptr, parent->name);
-			bptr += strlen(bptr);
-			parent = parent->parent;
-		}
-		*bptr = 0;
-	}
-
-	/* get a stream descriptor */
-	if (Fflag) {
-		printf("# %s\n", Fstart);
-		f = stdout;
-	} else {
-#ifndef BSD
-		Fstart[14] = 0;
-#endif
-		if ((f = fopen(Fname, "w")) == 0) {
-			perror(Fname);
-			exit(1);
-		}
-	}
-	if (n == Top)
-		fprintf(f, "private {%s}\ndead {%s}\n", Top->name, Top->name);
-	return f;
-}
-
-/* map to lower case in place.  return parameter for convenience */
-char *
-lowercase(buf)
-	char *buf;
-{	char *str;
-
-	for (str = buf ; *str; str++)
-		if (isupper(*str))
-			*str -= 'A' - 'a';
-	return buf;
-}
-
-/* get the interesting aliases, attach to n->alias */
-makealiases(n, line)
-	node *n;
-	char *line;
-{	char *next, *dot;
-	node *a;
-
-	if (line == 0 || *line == 0)
-		return;
-
-	for ( ; line; line = next) {
-		next = strchr(line, ',');
-		if (next)
-			*next++ = 0;
-		if ((dot = strchr(line, '.')) == 0)
-			continue;
-		if (strcmp(dot, DotArpa) != 0)
-			continue;
-		*dot = 0;
-
-		if (strcmp(n->name, line) == 0)
-			continue;
-
-		a = newnode();
-		a->name = strsave(line);
-		a->next = n->alias;
-		n->alias = a;
-	}
-}
-
-/* make unique domain names */
-merge()
-{	register node *n;
-
-	for (n = Top->child; n; n = n->next)
-		make_children_unique(n);
-}
-
-/*
- * another recursive tree walk, this time to make unique domain
- * components.
- *
- * for domains like cc.umich.edu and cc.berkeley.edu, it's inaccurate
- * to describe cc as a member of umich.edu or berkeley.edu.  (i.e., the
- * lousy scoping rules for privates don't permit a clean syntax.)  so.
- *
- * to prevent confusion, tack on to any such domain name its parent domain
- * and promote it in the tree.  e.g., make cc.umich and cc.berkeley
- * subdomains of edu.
- */
-
-make_children_unique(parent)
-	node *parent;
-{	node *prev, *child, *next;
-	char buf[BUFSIZ];
-
-	prev = 0;
-	for (child = parent->child; child; child = next) {
-		next = child->next;
-
-		/* skip hosts */
-		if (!ISADOMAIN(child)) {
-			prev = child;
-			continue;
-		}
-
-		/*
-		 * promote non-unique domain, or any domain with a
-		 * gateway.  (the latter get promoted all the way to
-		 * top-level.)
-		 */
-		if ((child->flag & COLLISION) == 0 && child->gateway == 0) {
-			/*
-			 * uninteresting domain.  make its children
-			 * unique and bump prev.
-			 */
-			make_children_unique(child);
-			prev = child;
-			continue;
-		}
-
-		/*
-		 * gateway or dup domain name found.  don't bump
-		 * prev: this node is moving up the tree.
-		 */
-
-		/* qualify child domain name */
-		sprintf(buf, "%s%s", child->name, parent->name);
-		cfree(child->name);
-		child->name = strsave(buf);
-
-		/* unlink child out of sibling chain */
-		if (prev)
-			prev->next = child->next;
-		else
-			parent->child = child->next;
-
-		/* link child in as peer of parent */
-		child->next = parent->next;
-		parent->next = child;
-		child->parent = parent->parent;
-
-		/*
-		 * reset collision flag; may promote again on
-		 * return to caller.
-		 */
-		child->flag &= ~COLLISION;
-		hash(child);
-	}
-}
-
-/* another recursive tree walk, this time to set the COLLISION bit. */
-setuniqflag(n)
-	node *n;
-{	node *child, *alias;
-
-	/* mark this node in the hash table */
-	hash(n);
-	/* mark the aliases of this node */
-	for (alias = n->alias; alias; alias = alias->next)
-		hash(alias);
-	/* recursively mark this node's children */
-	for (child = n->child; child; child = child->next)
-		setuniqflag(child);
-}
-
-#define NHASH 8191		/* must be prime */
-node *Htable[NHASH];		/* hash table */
-
-hash(n)
-	node *n;
-{	node **bucket, *b;
-
-	bucket = Htable + (fold(n->name) % NHASH);
-	for (b = *bucket; b; b = b->bucket)
-		if (strcmp(n->name, b->name) == 0) {
-			b->flag |= COLLISION;
-			n->flag |= COLLISION;
-			return;
-		}
-
-	n->bucket = *bucket;
-	*bucket = n;
-}
-
-/* stolen from pathalias:addnode.c, q.v. */
-#define POLY	0x48000000		/* 31-bit polynomial */
-long CrcTable[128];
-
-void
-crcinit()
-{	register int i,j;
-	register long sum;
-
-	for (i = 0; i < 128; i++) {
-		sum = 0;
-		for (j = 7-1; j >= 0; --j)
-			if (i & (1 << j))
-				sum ^= POLY >> j;
-		CrcTable[i] = sum;
-	}
-}
-
-long
-fold(s)
-	register char *s;
-{	register long sum = 0;
-	register int c;
-
-	while (c = *s++)
-		sum = (sum >> 7) ^ CrcTable[(sum ^ c) & 0x7f];
-	return sum;
-}
-
-hashanalyze()
-{	int nodecount = 0, maxlen = 0, len, i, probes = 0;
-	node *n;
-
-	if (!Vflag)
-		return;
-
-	for (i = 0; i < NHASH; i++) {
-		len = 0;
-		for (n = Htable[i]; n; n = n->bucket) {
-			len++;
-			probes += len;
-		}
-		nodecount += len;
-		if (len > maxlen)
-			maxlen = len;
-	}
-	fprintf(stderr,
-	  "load = %2.2f, probes/access = %2.2f, %d nodes, max chain is %d\n",
-	  (double) nodecount / (double) NHASH,
-	  (double) probes / (double) nodecount, nodecount, maxlen);
-}
//GO.SYSIN DD arpatxt.c
echo arpa-privates 1>&2
sed 's/^-//' >arpa-privates <<'//GO.SYSIN DD arpa-privates'
-#################################################################
-#	arpa-privates file for arpatxt/pathalias		#
-#								#
-#	updated from hosts.txt ver. 750 and the			#
-#	UUCP Project map data as of 17-Jun-88			#
-#################################################################
-#	"master" file is available for anonymous ftp at:	#
-#	swan.ulowell.edu:~ftp/hosts/arpa-privates		#
-#	citi.umich.edu:~ftp/pub/honey/arpa-privates		#
-#								#
-#	Send updates to postmaster at one of above sites.	#
-#################################################################
-#			format:					#
-#	host	map.file (for registered UUCP hosts)		#
-#	host	[map.file] (for unregistered UUCP hosts)	#
-#	Everything after white space is ignored, and is		#
-#	primarily intended to keep the file easier to update.	#
-#	Order does not matter, but case does.			#
-#################################################################
-a		usa.ca
-aardvark	usa.or
-abbott		usa.ca
-ac1		[usa.ca] nsc
-ac6		[usa.ca] cerebus, esl
-achilles	[att]
-acorn		gbr
-adam		swe
-adams		swe
-admin		usa.ca
-alamo		usa.tx
-alex		usa.va
-alf		[usa.az] ellymae
-algedi		[usa.wa] pilchuck
-alien		usa.ca
-alpha		usa.in
-altair		[usa.tx] juniper
-amc		usa.wa
-amos		[usa.ca] suntan
-andy		[att]
-antares		usa.nj
-anubis		usa.il
-apollo		usa.ma
-aqua		usa.ma
-arc		usa.ca
-ares		swe
-argon		usa.nj
-argus		usa.nj
-ariadne		grc
-ariel		[usa.oh] mtune-isn
-aris		grc
-arthur		[usa.mo] wuphys
-asgard		usa.or
-astro		[usa.tx] milano
-athena		[usa.ca] daisy
-atlas		[att]
-att		
-b21		deu
-bacchus		usa.nc
-bert		usa.ca
-bezier		[usa.oh] bgsuvax
-blue		jpn
-bluto		[usa.tx] im4u
-bobcat		[usa.ca] vortex
-boojum		[att]
-boole		[att]
-bosco		[esp]
-bounty		[usa.az] ellymae
-bourbaki	usa.il
-bridge		[usa.il] richp1
-bugs		[usa.ca] cuschico
-bull		usa.ca
-cac		usa.ma
-cad		dmk (ibt)
-calico		usa.ny
-callisto	usa.in
-calvin		[usa.ca] ucdavis
-cantor		[usa.il] gargoyle, luccpud
-carl		swe
-carmel		[usa.az] verde
-carrara		[usa.ma] talcott
-casper		usa.or
-castor		[att]
-ccb		[kor] kaist
-ccd		usa.fl (pd1)
-ccs		[usa.tx] convex
-cerberus	usa.ca
-chaos		usa.ok
-cheetah		usa.oh
-chem		usa.ca
-cheops		[usa.ca] esl
-chip		usa.ca
-chiron		usa.ny
-chopin		[att]
-cims1		usa.ga
-cip		ita
-circe		[att]
-clara		usa.ny
-clover		usa.ca
-cls		[usa.nh] sii
-clutx		[usa.fl] gould
-cmr		usa.fl
-cogito		[att]
-cognac		usa.pa
-colby		usa.me
-condor		usa.ma
-cookie		usa.ne
-coral		usa.ca
-cortex		[usa.tx] CNLNET/soma
-cottage		gbr
-crash		usa.ca
-cs1		usa.ca
-csab		[usa.va] xanth, [usa.il] uiucdcs
-csc		can.on
-csd1		[usa.ny] cmcl2
-csd2		[usa.ny] cmcl2
-cssun		[usa.ny] albanycs
-csun1		usa.ga
-csun2		usa.ga
-cti		usa.ca
-curie		usa.tx
-cygnus		usa.ny
-dalek		usa.ca
-dali		[esp] goya
-darwin		can.on
-david		usa.oh
-dcn1		[usa.ca] scgvaxd
-deimos		[usa.oh] codas
-delphi		ita
-deneb		[can.bc] ubc-cs
-descartes	[usa.ca] nosc
-devvax		usa.ny (until Larry fixes news path on jpl-devvax)
-dewey		[usa.ca] hpda
-dipl		usa.ca
-disc		[usa.ca] ucdavis
-dorothy		usa.ca
-draco		[usa.tx] petro
-ea		usa.ok
-eagle		[usa.ca] ames
-earth		[att]
-east		fra
-ecn		nld
-ed		gbr
-edam		[att]
-edith		[usa.oh] mtune
-eli		usa.dc
-else		jpn
-elvira		[usa.dc] sundc
-emily		[usa.nj] althea
-ems		usa.mn
-ernie		usa.ca
-escher		usa.ca
-etl		[usa.va] potomac
-eunice		usa.fl
-europa		usa.ri
-evans		[usa.ca] ucbvax
-eve		[usa.ny] clara
-ewok		[usa.nc] suntri
-falcon		[usa.nc] suntri
-faraday		usa.ny
-faust		usa.ma
-fenway		usa.ga
-fergvax		[usa.ne] upba
-fisher		usa.nj
-flight		[usa.or] argent
-fluke		usa.wa
-foobar		usa.or
-forest		[usa.tx] hal6000
-forty2		che
-fred		usa.co
-frisbee		usa.co
-frog		usa.ma
-gaia		usa.co
-galaxy		usa.nj
-gamma		[usa.oh] codas
-gandalf		can.on
-garfield	can.nf
-gateway		[usa.ut] pedro
-gemini		usa.ca
-george		usa.tx
-gilbert		[usa.wa] pilchuck
-gizmo		[usa.ca] sun
-godot		usa.nc
-godzilla	[att]
-golem		usa.ca
-gort		[usa.ok] romed
-gould		usa.fl
-granite		[usa.nh] decvax
-green		[usa.md] jhunix
-grendel		[usa.oh] mtune
-grinch		usa.ca
-groucho		[att]
-grumpy		[usa.oh] codas
-gull		usa.tx
-hal		usa.oh
-hamster		[usa.ca] qantel
-happy		usa.ca
-hawk		[usa.ca] nosc
-hector		[att]
-helios		can.on
-hermes		[att]
-hollywood	[usa.ca] fortune
-hottub		usa.ca
-hq		sgp
-hub		[usa.ca] comdesign
-hugo		usa.va
-hydra		usa.nj
-hydro		[usa.ca] csustan
-ibd		[att]
-ibis		usa.tx
-icarus		[usa.ri] brunix
-ice		usa.wi
-imagen		usa.ca
-indra		[usa.oh] codas
-intrepid	usa.ar
-io		[usa.oh] mtune
-ipac		[usa.az] noao, [usa.ca] csula-ps
-ircam		fra
-iris		usa.ri
-isi		usa.ca
-isis		usa.co
-island		usa.ca
-jack		usa.ca
-janus		usa.ca
-jhereg		[usa.mn] bungia
-juniper		usa.tx
-kaos		usa.ma
-kiwi		bel
-kontiki		dmk
-kronos		grc
-lafite		[usa.nh] decvax
-lassen		usa.ca
-laura		deu
-leg		[fra] geocub
-lego		dmk
-leopard		[att]
-lilac		kor
-linus		usa.ma
-lion		[att]
-lola		[usa.oh] codas
-lono		usa.ca
-lynx		usa.ca
-macom1		usa.md
-magic		[usa.ca] idi
-manatee		usa.fl
-manta		usa.pa
-marge		usa.ca
-mars		usa.nj
-maui		usa.va
-max		[att]
-maxwell		usa.mo
-mcl		can.sk
-mcs		usa.md
-medusa		usa.nj
-megalon		deu
-mercury		[usa.ma] interlan
-merlin		[usa.ma] masscomp
-mickey		usa.ca
-mimas		nld
-minnie		usa.co
-miranda		[usa.oh] mtune
-mirage		gbr
-moe		[usa.nv] jimi
-mojave		usa.ca
-moses		[usa.mi] umich
-mouse		usa.de
-mozart		usa.ny
-mruxd		[att]
-ms		can.on
-mycroft		[usa.ca] hplabs
-myrddin		[usa.ca] amdahl-bartender
-netman		[att]
-newton		[can.bc] ubc-cs
-nexus		usa.dc
-nirvana		usa.va
-noether		[usa.ny] mozart
-nova		usa.ok
-oac		[att]
-nps		[usa.il] cerl
-nyquiest	[att]
-oahu		[usa.nj] hjuxa
-oak		[usa.ct] clunker
-oasis		usa.ca	(precautionary. llnl clashes with oasis.sait.ko.kr)
-ocean		[usa.ca] ucsbcsl
-odin		[att]
-opus		[att]
-orbit		usa.mn
-orca		[usa.az] ellymae
-orcas		usa.wa
-oregon		usa.or	{believe it or not}
-orion		[att]
-orville		usa.ny
-oscar		[usa.oh] bcd-dyn
-osiris		usa.md
-oz		usa.wa
-pallas		usa.il
-pandora		[usa.ma] harv-net
-pegasus		[att]
-percival	usa.or
-phobos		usa.vt
-phoebus		gbr
-phoenix		[att]
-physics		[usa.ny] ccnysci
-picasso		[esp] goya
-pilchuck	usa.wa
-pioneer		usa.md
-pixar		usa.ca
-plasma		usa.ca
-plato		usa.ca
-pluto		usa.ny
-pokey		[usa.va] men2a
-polaris		[usa.wa] camco
-pollux		usa.tx
-postel		nld
-presto		usa.md
-priam		[che] cernvax
-prime		usa.ma
-prism		usa.nj
-prodigal	usa.pa
-prometheus	usa.md
-psc		usa.md
-psych		[aus]
-psyche		usa.nc
-puppy		usa.ny
-qat		[usa.tx] techsup
-quark		[usa.ca] csuchico
-ra		[can.bc] ubc-cs
-rainier		swe
-ralph		usa.la
-rdm		usa.ga
-reason		usa.ny
-rebel		usa.ga
-red		jpn
-redwood		[usa.ca] amdcad
-ridge		usa.ca
-robin		[usa.oh] bgsuvax [usa.ma] linus
-rodan		usa.or
-rome		usa.ok
-rosetta		[usa.tx] rice
-rover		[usa.az] ellymae
-rsch		[usa.ma] harvard
-sable		[usa.ca] pyramid
-sabre		[usa.oh] codas
-sal		swe
-sam		usa.il
-sandy		[usa.tx] woton
-sas		[usa.nc] rti
-saturn		[kor] ketri
-scarecrow	[usa.pa] lehi3b15
-scooter		usa.ca
-select		nld
-service		gbr
-shamash		usa.mn
-shaw		[att]
-shockeye	usa.pa
-shrike		[usa.tx] MBIRNET
-shrimp		usa.tx
-sierra		usa.ca
-simon		usa.il
-sirius		[usa.nh] dartvax
-smith		[can.ab] edm
-snark		usa.pa
-snucom		kor
-sol		usa.nh
-solar		usa.nm
-soleil		usa.nj
-spam		usa.nj
-sparky		[usa.oh] codas
-sphinx		usa.il
-spike		usa.la
-spock		usa.ct
-sri		aus.qld
-ssi		usa.wi
-star		[usa.oh] codas
-stars		[can.ns] dalcs
-stuart		[usa.md] prometheus
-stymie		[usa.ma] harvard
-suna		[usa.mn] mscunx
-sunburn		usa.az
-sunrise		usa.nj
-sunspot		usa.nm
-suntan		usa.ca
-sunup		usa.wa
-super		usa.md
-svc		[usa.md] epiwrl
-swamp		[usa.ca] amdahl
-swan		usa.tx
-taurus		isr
-te		gbr
-terminus	[att]
-thermo		[usa.nv] stride1
-thor		dmk
-thunder		can.on
-tiger		usa.nj
-tinman		usa.ca
-titan		usa.ca
-trantor		usa.ca
-tut		fin
-ubvax		usa.ca
-unh		usa.nh
-unix		usa.wa
-usafa		[usa.co] winfree, [usa.fl] gould, [usa.nh] trixie
-valhalla	[usa.mi] edsr
-vax2		[usa.md] elsie
-vector		usa.tx
-vice		[usa.or] enky, budda, loop
-video		[att]
-vilya		[att]
-viper		[usa.mn] bungia, mmm, pwcs, quest
-vista		usa.ca
-vlsi1		[usa.ut] byuopus
-vlsi2		[usa.ut] byuopus
-vlsi3		[usa.ut] byuopus
-volt		usa.ca
-voodoo		usa.wa
-wang		usa.ma
-wayback		[att]
-wombat		usa.ca
-wotan		usa.ca
-xyzzy		usa.nc
-yoda		usa.co (UCARNET)
-yogi		[usa.nj] bellcore-micom, pyrnj
-z		usa.ca
-zap		can.qc
-zaphod		can.sk
-zeta		[usa.md] cp1
-zeus		can.bc
-zip		usa.oh
-zorac		can.on
//GO.SYSIN DD arpa-privates
echo make.honey 1>&2
sed 's/^-//' >make.honey <<'//GO.SYSIN DD make.honey'
-#!/bin/make -f
-# pathalias -- by steve bellovin, as told to peter honeyman
-
-### configuration section
-###
-# if you can't or don't intend to use dbm files,
-# don't bother with DBM or makedb
-DBM = -ldbm
-# or if you roll your own ...
-# DBM = dbm.o
-###
-# where is getopt (if not in the c library)?
-# GETOPT = -lgetopt
-### end of configuration section 
-
-CC = cc -g
-CFLAGS =  -DDEBUG
-LDFLAGS =
-YFLAGS = -dD
-YYDEBUG=0
-
-OBJ = addlink.o addnode.o local.o main.o mapit.o mapaux.o mem.o parse.o printit.o
-OFILES = addlink.O addnode.O local.O main.O mapit.O mapaux.O mem.O parse.O printit.O
-HDRS = def.h config.h
-CSRC = addlink.c addnode.c local.c main.c mapit.c mapaux.c mem.c printit.c
-LSRC = $(CSRC) parse.c
-SRC = $(CSRC) parse.y makedb.c arpatxt.c
-
-pathalias: & $(OBJ)
-	$(CC) $(OBJ) $(LDFLAGS) -o pathalias
-
-all: pathalias makedb arpatxt
-
-$(OBJ):	$(HDRS)
-
-parse.c: parse.y $(HDRS)
-	$(YACC) $(YFLAGS) parse.y
-	echo '#define YYDEBUG' > parse.c
-	sed -e '/^# line/d' -e 's/yydebug = 0/yydebug = $(YYDEBUG)/' y.tab.c >> parse.c
-
-makedb: makedb.o
-	$(CC) makedb.o $(LDFLAGS) $(DBM) -o makedb
-
-makedb.o: config.h
-
-arpatxt: arpatxt.o
-	$(CC) arpatxt.o $(LDFLAGS) -o arpatxt
-
-clean:
-	rm -f *.o y.tab.? parse.c
-
-tags: $(SRC) $(HDRS)
-	ctags -w $(SRC) $(HDRS)
-
-bundle: README CHANGES pathalias.8 Makefile ${HDRS} ${SRC} arpa-privates make.honey
-	@bundle README CHANGES pathalias.8 Makefile ${HDRS} ${SRC} arpa-privates make.honey
-
-bundle1: README CHANGES pathalias.8 Makefile ${HDRS}
-	@bundle README CHANGES pathalias.8 Makefile ${HDRS}
-
-bundle2: addlink.c addnode.c local.c main.c
-	@bundle addlink.c addnode.c local.c main.c
-
-bundle3: mapit.c mapaux.c
-	@bundle mapit.c mapaux.c
-
-bundle4: mem.c printit.c parse.y
-	@bundle mem.c printit.c parse.y makedb.c
-
-bundle5: makedb.c arpatxt.c arpa-privates make.honey
-	@bundle  makedb.c arpatxt.c arpa-privates make.honey
-
-ftp:
-	@make -s bundle | compress > /usr/ftp/pub/honey/pathalias.Z
-
-make.honey: makefile
-	@cp makefile make.honey
-
-lint:	$(LSRC)
-	lint -hbu $(CFLAGS) $(LSRC)
-	lint makedb.c
-
-
-# the remainder is site specific.
-
-LOCAL = paths/citi paths/internet
-FILES = pp/* $(LOCAL)
-
-paths/internet: hosts.txt arpa-privates local.hosts arpatxt
-	arpatxt -vfi -g citi -g umix -g mailrus -p arpa-privates local.hosts hosts.txt > paths/internet
-
-AVOID =
-
-# map output (input, really) to lower case; verbose; terminal domains
-ARGS = -iD
-
-PARGS=$(ARGS) $(AVOID) $(FILES)
-# desperation debugging -- examine the costs.
-costs:
-	pathalias -icvvD ${PARGS} 2>error.costs | awk '{printf("%s\t%s\t%s\n", $$2, $$1, $$3)}' | sort -o pa.costs 
-
-# make one BIG file.  a BIG bad idea.
-cat:
-	for i in $(FILES); do echo "file {$$i}"; cat $$i; echo 'private {}'; done > CAT
-
-# make a pathparse database.  -g is undocumented.
-edges:
-	pathalias -g edges $(PARGS) 2>ERRORS > edges.hosts
-#	makedb edges pa
-
-# kill bogus domains with mr. grep, then sort
-POSTPROC = egrep -v '(\.(com|edu|mil|gov|net|org|arpa|[a-z][a-z])	.*!.*!)|(.\.(com|edu|mil|gov|net|org|arpa|[a-z][a-z])	)' | sort
-
-# round up the usual suspects
-citi dwon umix mailrus:	$(LOCAL)
-	pathalias -l $@ $(PARGS) | $(POSTPROC) > $@
//GO.SYSIN DD make.honey
exit