|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 123665 (0x1e311)
Types: TextFile
Notes: Uncompressed file
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦11cb2e5aa⟧ »EurOpenD3/mail/pathalias.shar.Z«
└─⟦this⟧
# 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