[net.sources] uuhosts: extract and display mod.map.all

jsq@ut-sally.UUCP (John Quarterman) (12/17/84)

: This is a shar archive.  Extract with sh, not csh.
echo x - README
sed -e 's/^X//' > README << '!Funky!Stuff!'
XThis is the source directory for uuhosts, which may be used to
Xautomatically collect map information from mod.map.all and also
Xto display it to the users.
X
XUnlike the version I posted some time back, this one doesn't have
Xsecurity problems with extracting things from mod.map.all, and it
Xcan also display UUCP mail paths and USENET map entries faster.
!Funky!Stuff!
echo x - Makefile
sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
XSHELL=/bin/sh
X
X# nmail.paths is found in this directory
XLIB=/usr/local/lib
X# Most of the news parameter files and mapsh are in this directory.
XNEWS=$(LIB)/news
X# The maps from mod.map.all are under this directory.
XMAPS=$(NEWS)/maps
X
XSOURCES=uuhosts.sh mapsh.c uucp.from.news.sh
XALL=uuhosts mapsh uucp.from.news
X
Xall: $(ALL)
X
Xuuhosts: uuhosts.sh
X	sed -e \
X's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\
X uuhosts.sh > uuhosts
X
Xmapsh: mapsh.c
X	$(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c
X
Xuucp.from.news: uucp.from.news.sh
X	sed -e \
X's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\
X uucp.from.news.sh > uucp.from.news
X
Xinstall: mapsh
X	cp uuhosts /usr/local/uuhosts
X	rm $(NEWS)/mapsh
X	cp mapsh $(NEWS)/mapsh
X	strip $(NEWS)/mapsh
X	chown root $(NEWS)/mapsh
X	chgrp news $(NEWS)/mapsh
X	chmod 4550 $(NEWS)/mapsh
X	ls -lg $(NEWS)/mapsh
X
Xclean:
X	rm -f $(ALL)
X	rm -f *.o
X	rm -f *.shar
X
Xshar:
X	shar README Makefile $(SOURCES) > uuhosts.shar
!Funky!Stuff!
echo x - uuhosts.sh
sed -e 's/^X//' > uuhosts.sh << '!Funky!Stuff!'
X#!/bin/sh
X# '@(#) uuhosts.sh 1.39 84/12/15'
X
X# PATH will have to be adjusted for non-BSD systems.
XPATH=/usr/local:/usr/ucb:/bin:/usr/bin
XLIB=/usr/local/lib
XNEWS=$LIB/news
XMAPS=$NEWS/maps
XNEWSMAPGROUP=mod.map.news
XUUCPMAPGROUP=mod.map.uucp
XNEWSMAP=$NEWSMAPGROUP
XUUCPMAP=$UUCPMAPGROUP
XMAPSH=$NEWS/mapsh
X
X# Routing information produced by pathalias.
Xpaths=$LIB/nmail.paths
X
X# The directories $MAPS/$NEWSMAP and $MAPS/$UUCPMAP contain the map information
X# extracted from the newsgroups mod.map.news (for the USENET news map)
X# and mod.map.uucp (for the UUCP mail map).  The extraction is done by
X# a line in $NEWS/sys like this:
X
X# maps:mod.map.news,mod.map.mail:B:/usr/local/uuhosts -x
X
X# Locally-known USENET news map information should go in $MAPS/$NEWSMAP/Local.
X
X# $MAPSH is needed, to use the chroot(2) system call to limit
X# what can be done when executing a shell with a news article as input.
X# $MAPS, $MAPS/bin and $MAPS/bin/* must be unwritable by anyone:
X
X# $MAPS: total 16
X# dr-xr-xr-x  6 root     news          512 Nov 11 16:42 .
X# drwxrwxr-x 19 news     news         1024 Nov 11 16:45 ..
X# dr-xr-xr-x  2 root     news          512 Nov 11 16:39 bin
X# drwxrwxr-x  2 news     news         2048 Nov 11 16:42 mod.map.news
X# drwxrwxr-x  2 news     news        10240 Nov 11 16:39 mod.map.uucp
X# drwxrwxrwx  2 news     news           24 Nov 11 16:41 tmp
X
X# $MAPS/bin: total 59
X# -r-xr-xr-x  1 root     news        10240 Nov 11 15:29 cat
X# -r-xr-xr-x  1 root     news         4096 Nov 11 16:33 echo
X# -r-xr-xr-x  1 root     news        18432 Nov 11 15:29 sed
X# -r-xr-xr-x  1 root     news        27648 Nov 11 15:29 sh
X
X# Update notices are mailed to postmaster (for UUCP) and usenet (for news),
X# which should be aliases which redistribute to the local mail and news
X# (respectively) administrators.
X
Xcd $NEWS
X
Xcase $1 in
X	-x)
X		# extract a new map piece into a map directory
X		temphead=/tmp/maphead.$$
X		temptext=/tmp/maptext.$$
X		tempcomm=/tmp/mapcomm.$$
X		cp /dev/null $temphead
X		cp /dev/null $temptext
X		echo 'exec /bin/mail usenet' > $tempcomm
X		awk '
XBEGIN	{
X	temphead = "'$temphead'"; tempcomm = "'$tempcomm'";
X	typeset = 0; isnewsmap = 0; isuucpmap = 0;
X	shead = 0; stext = 1; snews = 2; suucp = 3;
X	state = shead;
X}
Xstate == shead && ($1 == "From:" || $1 == "Sender:" \
X    || $1 == "Date:" || $1 == "Message-ID:" || $1 == "Message-Id:") {
X	print "Original-" $0 >> temphead;
X	next;
X}
Xstate == shead && $1 == "Newsgroups:" {	# no cross-postings allowed
X	if ($2 == "'$NEWSMAPGROUP'") {
X		isnewsmap = 1;
X		typeset = 1;
X		print "Reply-To: usenet" >> temphead;
X		print "exec /bin/mail usenet" > tempcomm;
X	} else if ($2 == "'$UUCPMAPGROUP'") {
X		isuucpmap = 1;
X		typeset = 1;
X		print "Reply-To: postmaster" >> temphead;
X		print "exec /bin/mail postmaster" > tempcomm;
X	}
X}
Xstate == shead && $1 == "Subject:" {
X	if ($1 == "Re:" || $1 == "RE:" || $1 == "re:"\
X	|| !typeset) {	# this requires Newsgroups: before Subject:
X		print "Subject:  not a map update" >> temphead;
X		print "Original-" $0 >> temphead;
X	} else
X		print $0 >> temphead;
X	next;
X}
Xstate == shead && /^$/	{
X	if (isnewsmap != 0) {
X		print "cd '$NEWSMAP'" | "uuhosts -n";
X		state = snews;
X	} else if (isuucpmap != 0) {
X		print "cd '$UUCPMAP'" | "uuhosts -u";
X		state = suucp;
X	} else
X		state = stext;
X}
Xstate == shead {
X		print $0 >> temphead;
X}
Xstate == snews	{
X	print | "uuhosts -n";
X}
Xstate == suucp	{
X	print | "uuhosts -u";
X}
Xstate == stext	{
X	print;
X}
X' > $temptext 2>&1
X		cat $temphead $temptext | sh $tempcomm
X		rm -f $temphead $temptext $tempcomm
X		exit 0
X	;;
X
X	-u)
X		# extract a UUCP map piece
X		$MAPSH
X		cd $MAPS/$UUCPMAP
X		for f in *.a *.ar
X		do
X			ar xv $f
X			rm $f
X		done
X		exit 0
X	;;
X
X	-n)
X		# extract a USENET map piece
X		$MAPSH
X		exec uuhosts -i
X		exit 0
X	;;
X
X	-i)
X		# make an index for the USENET map
X		cd $MAPS/$NEWSMAP
X		awk '$1 == "Name:" { 
X			printf ("%s\t%s\n", $2, FILENAME);
X		}' Local [a-z]* | sort -f > Index.$$
X		mv Index.$$ Index
X		exit 0
X	;;
X
X	-g)
X		# by geographical region
X		cd $MAPS/$NEWSMAP
X		shift
X		if test $# -eq 0
X		then
X			exec ls
X			exit 1
X		fi
X		exec cat $*
X		exit 1
X	;;
X
X	-k)
X		# by keyword
X		cd $MAPS/$NEWSMAP
X		shift
X		exec awk '
XBEGIN		{ inside = 1; outside = 0; state = outside; }
X/^Name:/	{ state = inside; count = 0; useit = 0; }
Xstate == inside	{ block[count++] = $0; }
X/'"$*"'/	{ useit = 1; }
X/^$/ && state == inside	{
X	if (useit == 1) {
X		for (i = 0; i < count; i++) {
X			print block[i];
X		}
X	}
X	state = outside;
X}
X' *
X		exit 1
X	;;
X
X	-*)
X		# unknown option
X	;;
X
X	"")
X		# no arguments
X	;;
X
X	*)
X		# by site name
X		if [ -x /usr/bin/look ]; then
X			look=/usr/bin/look
X			lookopt="-f "
X		else
X			look=grep
X			lookopt="^"
X		fi
X		for arg in $*
X		do
X			echo 'UUCP mail path:'
X			$look $lookopt$arg $paths
X			echo '
XUUCP mail host information:'
X			cd $MAPS/$UUCPMAP
X			sed -e '
Xs/^#N/#Name		/
Xs/^#S/#System-CPU-OS	/
Xs/^#O/#Organization	/
Xs/^#C/#Contact	/
Xs/^#E/#Electronic-Address/
Xs/^#T/#Telephone	/
Xs/^#P/#Postal-Address	/
Xs/^#L/#Latitude-Longitude/
Xs/^#R/#Remarks	/
Xs/^#W/#Written-by	/' ${arg}*
X			cd $MAPS/$NEWSMAP
X			echo '
XUSENET news host information:'
X			sed -n -e "/^Name:[ 	]*${arg}/,/^$/p" \
X				`$look $lookopt$arg Index | awk '{print $2}'`
X		done
X		exit 0
X	;;
Xesac
X
Xecho 'Usage:	'uuhosts' hostname ...
Xfor information about a particular UUCP or USENET host or hosts, or
X
X	'uuhosts' -g geographical-region
Xfor information about USENET news sites in a geographical region, or
X
X	'uuhosts' -g
Xfor a list of known USENET geographical-regions.
X
XSee uuhosts(1) for further details and more obscure options.
X'
Xexit 1
!Funky!Stuff!
echo x - mapsh.c
sed -e 's/^X//' > mapsh.c << '!Funky!Stuff!'
X#include <stdio.h>
X
X#ifndef MAPS
X#define MAPS "/usr/local/lib/news/maps"
X#endif
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X	char *rootdir = MAPS;
X	char *command = "/bin/sh";
X
X	if (geteuid() != 0) {
X		fprintf (stderr, "mapsh must be setuid to root\n");
X		exit(1);
X	}
X	if (chroot(rootdir) == -1) {
X		fprintf (stderr, "mapsh:  chroot(%s) failed\n", rootdir);
X		perror ("");
X		exit(1);
X	}
X	if (setuid(getuid()) == -1) {
X		perror ("mapsh:  setuid(getuid()) failed");
X		exit(1);
X	}
X	if (chdir("/") == -1) {
X		fprintf (stderr, "mapsh:  chdir(%s) failed\n", "/");
X		perror ("");
X		exit(1);
X	}
X	execvp (command, argv);
X	fprintf (stderr, "mapsh:  %s not found\n", command);
X	perror ("mapsh:  execvp(2) failed");
X	exit(1);
X}
!Funky!Stuff!
echo x - uucp.from.news.sh
sed -e 's/^X//' > uucp.from.news.sh << '!Funky!Stuff!'
X#!/bin/sh
X#
X#	This command, uucp.from.news, is a stopgap measure for use until
X#	the UUCP map is complete.  It extracts mail information from the
X#	USENET news map and uses it to fill in gaps in the UUCP mail map.
X#
X#	It should be called from the news map directory, $MAPS/$NEWSMAP,
X#	with a list of news map files as arguments, i.e.:
X#		cd $MAPS/$NEWSMAP
X#		uucp.from.news *
X#	It looks through the news map entries for ones with mail information,
X#	extracts those into individual files in $DIR by host name, and later
X#	copies all those for which there are not already host entries in
X#	the mail map directory to the mail map directory,  $MAPS/UUCPMAP.
X#	The new mail map files all have '-' appended so they can be easily
X#	distinguished.  If uucp.from.news is run again, such
X#	$MAPS/UUCPMAP/*- entries will be overwritten.
X#
X#	The temporary directory $DIR is removed after the command is done.
X#
XPATH=/usr/local:/usr/ucb:/bin:/usr/bin
Xumask 0002
X
XLIB=/usr/local/lib
XNEWS=$LIB/news
XMAPS=$NEWS/maps
XNEWSMAPGROUP=mod.map.news
XUUCPMAPGROUP=mod.map.uucp
XNEWSMAP=$NEWSMAPGROUP
XUUCPMAP=$UUCPMAPGROUP
X
XDIR=uucptmp
Xmkdir $DIR
X
Xawk '
XBEGIN {
X	sbetween = 0; sinside = 1; state = sbetween;
X	Date = "'"`date`"'";
X	split (Date, date, " ");
X	Mark = "uucp.from.news " date[3] " " date[2] " " date[6];
X	dir = "'$DIR'";
X}
Xstate == sbetween && $1 == "Name:" {
X	state = sinside;
X	last = "";
X	Name = "";
X	System = "";
X	Organization = "";
X	Contact = "";
X	Telephone = "";
X	Postal = "";
X	Address = "";
X	News = "";
X	Mail = "";
X	Latlong = "";
X	Remarks = "";
X	Written = "";
X	Comments = "";
X}
Xstate != sinside {
X	next;
X}
X# { print $0; }
X$1 == "Name:"		{ Name = $2;		next; }
X$1 == "Organization:"	{
X	Organization = $2;
X	for (x = 3; x <= NF; x++)
X		Organization = Organization " " $x;
X	last = $1;
X	next;
X}
X$1 == "Contact:"	{
X	Contact = $2;
X	for (x = 3; x <= NF; x++)
X		Contact = Contact " " $x;
X	last = $1;
X	next;
X}
X$1 == "Phone:"		{
X	Telephone = $2;
X	for (x = 3; x <= NF; x++)
X		Telephone = Telephone " " $x;
X	last = $1;
X	next;
X}
X$1 == "Postal-Address:"	{
X	Postal = $2;
X	for (x = 3; x <= NF; x++)
X		Postal = Postal " " $x;
X	last = $1;
X	next;
X}
X$1 == "Electronic-Address:" {
X	Address = $2;
X	for (x = 3; x <= NF; x++)
X		Address = Address " " $x;
X	last = $1;
X	next;
X}
X$1 == "News:"		{
X	News = $2;
X	for (x = 3; x <= NF; x++)
X		News = News " " $x;
X	last = $1;
X	next;
X}
X/^	/ && last == "News:" {
X	for (x = 2; x <= NF; x++)
X		News = News " " $x;
X	next;
X}
X$1 == "Mail:"		{
X	Mail = $2;
X	for (x = 3; x <= NF; x++)
X		Mail = Mail " " $x;
X	last = $1;
X	next;
X}
X/^	/ && last == "Mail:" {
X	for (x = 1; x <= NF; x++)
X		Mail = Mail " " $x;
X	next;
X}
X$1 == "Comments:"	{
X	last = $1;
X	if ($2 == "last" && $3 == "edited") {
X		Written = $4;
X		for (x = 5; x <= NF; x++)
X			Written = Written " " $x;
X		next;
X	}
X	Comments = $2;
X	for (x = 3; x <= NF; x++)
X		Comments = Comments " " $x;
X	next;
X}
X/^$/ {
X	state = sbetween;
X	if (Mail == "")
X		next;
X	output = dir "/" Name;
X	printf ("echo x - %s\n", output);
X	printf ("cat > %s << '\''End-of-%s'\''\n", output, output);
X	printf ("#N\t%s\n", Name);
X	printf ("#S\t%s\n", System);
X	printf ("#O\t%s\n", Organization);
X	printf ("#C\t%s\n", Contact);
X	printf ("#E\t%s\n", Address);
X	printf ("#T\t%s\n", Telephone);
X	printf ("#P\t%s\n", Postal);
X	printf ("#L\t%s\n", Latlong);
X	printf ("#R\t%s\n", Mark);
X#	split (News, news, "");
X#	printf ("#R\tNews:  %s", news[1]);
X#	for (x = 2; news[x] != ""; x++) {
X#		if ((x % 8) == 0)
X#			printf ("\n\t");
X#		else
X#			printf (", ");
X#		printf ("%s", news[x]);
X#	}
X#	printf ("\n");
X	printf ("#W\t%s\n", Written);
X	printf ("#\n");
X	split (Mail, mail, " ");
X	printf ("%s\t%s", Name, mail[1]);
X	for (x = 2; mail[x] != ""; x++) {
X		if ((x % 8) == 0)
X			printf ("\n\t");
X		else
X			printf (", ");
X		printf ("%s", mail[x]);
X	}
X	printf ("\n");
X	if (Comments != "") {
X		printf ("#\n");
X		printf ("#%s\n", Comments);
X	}
X	printf ("\n");
X	printf ("End-of-%s\n", output);
X	next;
X}
X' $* | sh
X
Xcd $DIR
Xfor f in *
Xdo
X	there=$MAPS/$UUCPMAP/$f
X	if [ -r ${there} ]; then
X		echo ${there}
X		continue
X	fi
X	if [ -r ${there}. ]; then
X		echo ${there}.
X		continue
X	fi
X	if [ -r ${there}% ]; then
X		echo ${there}%
X		continue
X	fi
X#	if [ -r ${there}- ]; then
X#		echo ${there}-
X#		continue
X#	fi
X	echo new ${there}-
X	mv $f ${there}-
Xdone
Xcd ..
Xrm -rf $DIR
!Funky!Stuff!
exit
-- 

John Quarterman, CS Dept., University of Texas, Austin, Texas 78712 USA
jsq@ut-sally.ARPA, jsq@ut-sally.UUCP, {ihnp4,seismo,ctvax}!ut-sally!jsq

bill@caribou.UUCP (Bill's area) (12/26/84)

> 
> : This is a shar archive.  Extract with sh, not csh.
> echo x - README
> sed -e 's/^X//' > README << '!Funky!Stuff!'
> XThis is the source directory for uuhosts, which may be used to
> Xautomatically collect map information from mod.map.all and also
> Xto display it to the users.
> X
> XUnlike the version I posted some time back, this one doesn't have
> Xsecurity problems with extracting things from mod.map.all, and it
> Xcan also display UUCP mail paths and USENET map entries faster.
> !Funky!Stuff!
> echo x - Makefile
> sed -e 's/^X//' > Makefile << '!Funky!Stuff!'
> XSHELL=/bin/sh
> X
> X# nmail.paths is found in this directory
> XLIB=/usr/local/lib
> X# Most of the news parameter files and mapsh are in this directory.
> XNEWS=$(LIB)/news
> X# The maps from mod.map.all are under this directory.
> XMAPS=$(NEWS)/maps
> X
> XSOURCES=uuhosts.sh mapsh.c uucp.from.news.sh
> XALL=uuhosts mapsh uucp.from.news
> X
> Xall: $(ALL)
> X
> Xuuhosts: uuhosts.sh
> X	sed -e \
> X's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\
> X uuhosts.sh > uuhosts
> X
> Xmapsh: mapsh.c
> X	$(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c
> X
> Xuucp.from.news: uucp.from.news.sh
> X	sed -e \
> X's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\
> X uucp.from.news.sh > uucp.from.news
> X
> Xinstall: mapsh
> X	cp uuhosts /usr/local/uuhosts
> X	rm $(NEWS)/mapsh
> X	cp mapsh $(NEWS)/mapsh
> X	strip $(NEWS)/mapsh
> X	chown root $(NEWS)/mapsh
> X	chgrp news $(NEWS)/mapsh
> X	chmod 4550 $(NEWS)/mapsh
> X	ls -lg $(NEWS)/mapsh
> X
> Xclean:
> X	rm -f $(ALL)
> X	rm -f *.o
> X	rm -f *.shar
> X
> Xshar:
> X	shar README Makefile $(SOURCES) > uuhosts.shar
> !Funky!Stuff!
> echo x - uuhosts.sh
> sed -e 's/^X//' > uuhosts.sh << '!Funky!Stuff!'
> X#!/bin/sh
> X# '@(#) uuhosts.sh 1.39 84/12/15'
> X
> X# PATH will have to be adjusted for non-BSD systems.
> XPATH=/usr/local:/usr/ucb:/bin:/usr/bin
> XLIB=/usr/local/lib
> XNEWS=$LIB/news
> XMAPS=$NEWS/maps
> XNEWSMAPGROUP=mod.map.news
> XUUCPMAPGROUP=mod.map.uucp
> XNEWSMAP=$NEWSMAPGROUP
> XUUCPMAP=$UUCPMAPGROUP
> XMAPSH=$NEWS/mapsh
> X
> X# Routing information produced by pathalias.
> Xpaths=$LIB/nmail.paths
> X
> X# The directories $MAPS/$NEWSMAP and $MAPS/$UUCPMAP contain the map information
> X# extracted from the newsgroups mod.map.news (for the USENET news map)
> X# and mod.map.uucp (for the UUCP mail map).  The extraction is done by
> X# a line in $NEWS/sys like this:
> X
> X# maps:mod.map.news,mod.map.mail:B:/usr/local/uuhosts -x
> X
> X# Locally-known USENET news map information should go in $MAPS/$NEWSMAP/Local.
> X
> X# $MAPSH is needed, to use the chroot(2) system call to limit
> X# what can be done when executing a shell with a news article as input.
> X# $MAPS, $MAPS/bin and $MAPS/bin/* must be unwritable by anyone:
> X
> X# $MAPS: total 16
> X# dr-xr-xr-x  6 root     news          512 Nov 11 16:42 .
> X# drwxrwxr-x 19 news     news         1024 Nov 11 16:45 ..
> X# dr-xr-xr-x  2 root     news          512 Nov 11 16:39 bin
> X# drwxrwxr-x  2 news     news         2048 Nov 11 16:42 mod.map.news
> X# drwxrwxr-x  2 news     news        10240 Nov 11 16:39 mod.map.uucp
> X# drwxrwxrwx  2 news     news           24 Nov 11 16:41 tmp
> X
> X# $MAPS/bin: total 59
> X# -r-xr-xr-x  1 root     news        10240 Nov 11 15:29 cat
> X# -r-xr-xr-x  1 root     news         4096 Nov 11 16:33 echo
> X# -r-xr-xr-x  1 root     news        18432 Nov 11 15:29 sed
> X# -r-xr-xr-x  1 root     news        27648 Nov 11 15:29 sh
> X
> X# Update notices are mailed to postmaster (for UUCP) and usenet (for news),
> X# which should be aliases which redistribute to the local mail and news
> X# (respectively) administrators.
> X
> Xcd $NEWS
> X
> Xcase $1 in
> X	-x)
> X		# extract a new map piece into a map directory
> X		temphead=/tmp/maphead.$$
> X		temptext=/tmp/maptext.$$
> X		tempcomm=/tmp/mapcomm.$$
> X		cp /dev/null $temphead
> X		cp /dev/null $temptext
> X		echo 'exec /bin/mail usenet' > $tempcomm
> X		awk '
> XBEGIN	{
> X	temphead = "'$temphead'"; tempcomm = "'$tempcomm'";
> X	typeset = 0; isnewsmap = 0; isuucpmap = 0;
> X	shead = 0; stext = 1; snews = 2; suucp = 3;
> X	state = shead;
> X}
> Xstate == shead && ($1 == "From:" || $1 == "Sender:" \
> X    || $1 == "Date:" || $1 == "Message-ID:" || $1 == "Message-Id:") {
> X	print "Original-" $0 >> temphead;
> X	next;
> X}
> Xstate == shead && $1 == "Newsgroups:" {	# no cross-postings allowed
> X	if ($2 == "'$NEWSMAPGROUP'") {
> X		isnewsmap = 1;
> X		typeset = 1;
> X		print "Reply-To: usenet" >> temphead;
> X		print "exec /bin/mail usenet" > tempcomm;
> X	} else if ($2 == "'$UUCPMAPGROUP'") {
> X		isuucpmap = 1;
> X		typeset = 1;
> X		print "Reply-To: postmaster" >> temphead;
> X		print "exec /bin/mail postmaster" > tempcomm;
> X	}
> X}
> Xstate == shead && $1 == "Subject:" {
> X	if ($1 == "Re:" || $1 == "RE:" || $1 == "re:"\
> X	|| !typeset) {	# this requires Newsgroups: before Subject:
> X		print "Subject:  not a map update" >> temphead;
> X		print "Original-" $0 >> temphead;
> X	} else
> X		print $0 >> temphead;
> X	next;
> X}
> Xstate == shead && /^$/	{
> X	if (isnewsmap != 0) {
> X		print "cd '$NEWSMAP'" | "uuhosts -n";
> X		state = snews;
> X	} else if (isuucpmap != 0) {
> X		print "cd '$UUCPMAP'" | "uuhosts -u";
> X		state = suucp;
> X	} else
> X		state = stext;
> X}
> Xstate == shead {
> X		print $0 >> temphead;
> X}
> Xstate == snews	{
> X	print | "uuhosts -n";
> X}
> Xstate == suucp	{
> X	print | "uuhosts -u";
> X}
> Xstate == stext	{
> X	print;
> X}
> X' > $temptext 2>&1
> X		cat $temphead $temptext | sh $tempcomm
> X		rm -f $temphead $temptext $tempcomm
> X		exit 0
> X	;;
> X
> X	-u)
> X		# extract a UUCP map piece
> X		$MAPSH
> X		cd $MAPS/$UUCPMAP
> X		for f in *.a *.ar
> X		do
> X			ar xv $f
> X			rm $f
> X		done
> X		exit 0
> X	;;
> X
> X	-n)
> X		# extract a USENET map piece
> X		$MAPSH
> X		exec uuhosts -i
> X		exit 0
> X	;;
> X
> X	-i)
> X		# make an index for the USENET map
> X		cd $MAPS/$NEWSMAP
> X		awk '$1 == "Name:" { 
> X			printf ("%s\t%s\n", $2, FILENAME);
> X		}' Local [a-z]* | sort -f > Index.$$
> X		mv Index.$$ Index
> X		exit 0
> X	;;
> X
> X	-g)
> X		# by geographical region
> X		cd $MAPS/$NEWSMAP
> X		shift
> X		if test $# -eq 0
> X		then
> X			exec ls
> X			exit 1
> X		fi
> X		exec cat $*
> X		exit 1
> X	;;
> X
> X	-k)
> X		# by keyword
> X		cd $MAPS/$NEWSMAP
> X		shift
> X		exec awk '
> XBEGIN		{ inside = 1; outside = 0; state = outside; }
> X/^Name:/	{ state = inside; count = 0; useit = 0; }
> Xstate == inside	{ block[count++] = $0; }
> X/'"$*"'/	{ useit = 1; }
> X/^$/ && state == inside	{
> X	if (useit == 1) {
> X		for (i = 0; i < count; i++) {
> X			print block[i];
> X		}
> X	}
> X	state = outside;
> X}
> X' *
> X		exit 1
> X	;;
> X
> X	-*)
> X		# unknown option
> X	;;
> X
> X	"")
> X		# no arguments
> X	;;
> X
> X	*)
> X		# by site name
> X		if [ -x /usr/bin/look ]; then
> X			look=/usr/bin/look
> X			lookopt="-f "
> X		else
> X			look=grep
> X			lookopt="^"
> X		fi
> X		for arg in $*
> X		do
> X			echo 'UUCP mail path:'
> X			$look $lookopt$arg $paths
> X			echo '
> XUUCP mail host information:'
> X			cd $MAPS/$UUCPMAP
> X			sed -e '
> Xs/^#N/#Name		/
> Xs/^#S/#System-CPU-OS	/
> Xs/^#O/#Organization	/
> Xs/^#C/#Contact	/
> Xs/^#E/#Electronic-Address/
> Xs/^#T/#Telephone	/
> Xs/^#P/#Postal-Address	/
> Xs/^#L/#Latitude-Longitude/
> Xs/^#R/#Remarks	/
> Xs/^#W/#Written-by	/' ${arg}*
> X			cd $MAPS/$NEWSMAP
> X			echo '
> XUSENET news host information:'
> X			sed -n -e "/^Name:[ 	]*${arg}/,/^$/p" \
> X				`$look $lookopt$arg Index | awk '{print $2}'`
> X		done
> X		exit 0
> X	;;
> Xesac
> X
> Xecho 'Usage:	'uuhosts' hostname ...
> Xfor information about a particular UUCP or USENET host or hosts, or
> X
> X	'uuhosts' -g geographical-region
> Xfor information about USENET news sites in a geographical region, or
> X
> X	'uuhosts' -g
> Xfor a list of known USENET geographical-regions.
> X
> XSee uuhosts(1) for further details and more obscure options.
> X'
> Xexit 1
> !Funky!Stuff!
> echo x - mapsh.c
> sed -e 's/^X//' > mapsh.c << '!Funky!Stuff!'
> X#include <stdio.h>
> X
> X#ifndef MAPS
> X#define MAPS "/usr/local/lib/news/maps"
> X#endif
> X
> Xmain(argc,argv)
> Xint argc;
> Xchar **argv;
> X{
> X	char *rootdir = MAPS;
> X	char *command = "/bin/sh";
> X
> X	if (geteuid() != 0) {
> X		fprintf (stderr, "mapsh must be setuid to root\n");
> X		exit(1);
> X	}
> X	if (chroot(rootdir) == -1) {
> X		fprintf (stderr, "mapsh:  chroot(%s) failed\n", rootdir);
> X		perror ("");
> X		exit(1);
> X	}
> X	if (setuid(getuid()) == -1) {
> X		perror ("mapsh:  setuid(getuid()) failed");
> X		exit(1);
> X	}
> X	if (chdir("/") == -1) {
> X		fprintf (stderr, "mapsh:  chdir(%s) failed\n", "/");
> X		perror ("");
> X		exit(1);
> X	}
> X	execvp (command, argv);
> X	fprintf (stderr, "mapsh:  %s not found\n", command);
> X	perror ("mapsh:  execvp(2) failed");
> X	exit(1);
> X}
> !Funky!Stuff!
> echo x - uucp.from.news.sh
> sed -e 's/^X//' > uucp.from.news.sh << '!Funky!Stuff!'
> X#!/bin/sh
> X#
> X#	This command, uucp.from.news, is a stopgap measure for use until
> X#	the UUCP map is complete.  It extracts mail information from the
> X#	USENET news map and uses it to fill in gaps in the UUCP mail map.
> X#
> X#	It should be called from the news map directory, $MAPS/$NEWSMAP,
> X#	with a list of news map files as arguments, i.e.:
> X#		cd $MAPS/$NEWSMAP
> X#		uucp.from.news *
> X#	It looks through the news map entries for ones with mail information,
> X#	extracts those into individual files in $DIR by host name, and later
> X#	copies all those for which there are not already host entries in
> X#	the mail map directory to the mail map directory,  $MAPS/UUCPMAP.
> X#	The new mail map files all have '-' appended so they can be easily
> X#	distinguished.  If uucp.from.news is run again, such
> X#	$MAPS/UUCPMAP/*- entries will be overwritten.
> X#
> X#	The temporary directory $DIR is removed after the command is done.
> X#
> XPATH=/usr/local:/usr/ucb:/bin:/usr/bin
> Xumask 0002
> X
> XLIB=/usr/local/lib
> XNEWS=$LIB/news
> XMAPS=$NEWS/maps
> XNEWSMAPGROUP=mod.map.news
> XUUCPMAPGROUP=mod.map.uucp
> XNEWSMAP=$NEWSMAPGROUP
> XUUCPMAP=$UUCPMAPGROUP
> X
> XDIR=uucptmp
> Xmkdir $DIR
> X
> Xawk '
> XBEGIN {
> X	sbetween = 0; sinside = 1; state = sbetween;
> X	Date = "'"`date`"'";
> X	split (Date, date, " ");
> X	Mark = "uucp.from.news " date[3] " " date[2] " " date[6];
> X	dir = "'$DIR'";
> X}
> Xstate == sbetween && $1 == "Name:" {
> X	state = sinside;
> X	last = "";
> X	Name = "";
> X	System = "";
> X	Organization = "";
> X	Contact = "";
> X	Telephone = "";
> X	Postal = "";
> X	Address = "";
> X	News = "";
> X	Mail = "";
> X	Latlong = "";
> X	Remarks = "";
> X	Written = "";
> X	Comments = "";
> X}
> Xstate != sinside {
> X	next;
> X}
> X# { print $0; }
> X$1 == "Name:"		{ Name = $2;		next; }
> X$1 == "Organization:"	{
> X	Organization = $2;
> X	for (x = 3; x <= NF; x++)
> X		Organization = Organization " " $x;
> X	last = $1;
> X	next;
> X}
> X$1 == "Contact:"	{
> X	Contact = $2;
> X	for (x = 3; x <= NF; x++)
> X		Contact = Contact " " $x;
> X	last = $1;
> X	next;
> X}
> X$1 == "Phone:"		{
> X	Telephone = $2;
> X	for (x = 3; x <= NF; x++)
> X		Telephone = Telephone " " $x;
> X	last = $1;
> X	next;
> X}
> X$1 == "Postal-Address:"	{
> X	Postal = $2;
> X	for (x = 3; x <= NF; x++)
> X		Postal = Postal " " $x;
> X	last = $1;
> X	next;
> X}
> X$1 == "Electronic-Address:" {
> X	Address = $2;
> X	for (x = 3; x <= NF; x++)
> X		Address = Address " " $x;
> X	last = $1;
> X	next;
> X}
> X$1 == "News:"		{
> X	News = $2;
> X	for (x = 3; x <= NF; x++)
> X		News = News " " $x;
> X	last = $1;
> X	next;
> X}
> X/^	/ && last == "News:" {
> X	for (x = 2; x <= NF; x++)
> X		News = News " " $x;
> X	next;
> X}
> X$1 == "Mail:"		{
> X	Mail = $2;
> X	for (x = 3; x <= NF; x++)
> X		Mail = Mail " " $x;
> X	last = $1;
> X	next;
> X}
> X/^	/ && last == "Mail:" {
> X	for (x = 1; x <= NF; x++)
> X		Mail = Mail " " $x;
> X	next;
> X}
> X$1 == "Comments:"	{
> X	last = $1;
> X	if ($2 == "last" && $3 == "edited") {
> X		Written = $4;
> X		for (x = 5; x <= NF; x++)
> X			Written = Written " " $x;
> X		next;
> X	}
> X	Comments = $2;
> X	for (x = 3; x <= NF; x++)
> X		Comments = Comments " " $x;
> X	next;
> X}
> X/^$/ {
> X	state = sbetween;
> X	if (Mail == "")
> X		next;
> X	output = dir "/" Name;
> X	printf ("echo x - %s\n", output);
> X	printf ("cat > %s << '\''End-of-%s'\''\n", output, output);
> X	printf ("#N\t%s\n", Name);
> X	printf ("#S\t%s\n", System);
> X	printf ("#O\t%s\n", Organization);
> X	printf ("#C\t%s\n", Contact);
> X	printf ("#E\t%s\n", Address);
> X	printf ("#T\t%s\n", Telephone);
> X	printf ("#P\t%s\n", Postal);
> X	printf ("#L\t%s\n", Latlong);
> X	printf ("#R\t%s\n", Mark);
> X#	split (News, news, "");
> X#	printf ("#R\tNews:  %s", news[1]);
> X#	for (x = 2; news[x] != ""; x++) {
> X#		if ((x % 8) == 0)
> X#			printf ("\n\t");
> X#		else
> X#			printf (", ");
> X#		printf ("%s", news[x]);
> X#	}
> X#	printf ("\n");
> X	printf ("#W\t%s\n", Written);
> X	printf ("#\n");
> X	split (Mail, mail, " ");
> X	printf ("%s\t%s", Name, mail[1]);
> X	for (x = 2; mail[x] != ""; x++) {
> X		if ((x % 8) == 0)
> X			printf ("\n\t");
> X		else
> X			printf (", ");
> X		printf ("%s", mail[x]);
> X	}
> X	printf ("\n");
> X	if (Comments != "") {
> X		printf ("#\n");
> X		printf ("#%s\n", Comments);
> X	}
> X	printf ("\n");
> X	printf ("End-of-%s\n", output);
> X	next;
> X}
> X' $* | sh
> X
> Xcd $DIR
> Xfor f in *
> Xdo
> X	there=$MAPS/$UUCPMAP/$f
> X	if [ -r ${there} ]; then
> X		echo ${there}
> X		continue
> X	fi
> X	if [ -r ${there}. ]; then
> X		echo ${there}.
> X		continue
> X	fi
> X	if [ -r ${there}% ]; then
> X		echo ${there}%
> X		continue
> X	fi
> X#	if [ -r ${there}- ]; then
> X#		echo ${there}-
> X#		continue
> X#	fi
> X	echo new ${there}-
> X	mv $f ${there}-
> Xdone
> Xcd ..
> Xrm -rf $DIR
> !Funky!Stuff!
> exit
> -- 
> 
> John Quarterman, CS Dept., University of Texas, Austin, Texas 78712 USA
> jsq@ut-sally.ARPA, jsq@ut-sally.UUCP, {ihnp4,seismo,ctvax}!ut-sally!jsq

*** REPLACE THIS LINE WITH YOUR MESSAGE ***

lee@unmvax.UUCP (12/29/84)

> > X
> > XUnlike the version I posted some time back, this one doesn't have
> > Xsecurity problems with extracting things from mod.map.all, and it

What if I don't have a chroot system call? Oh well.. Here, this
one does not use the shell at all... I thought I posted this before?
Gotta have libndir though.

(Don't forget to strip the .signature at the end)


#ifndef	lint
char	*Rcsid = "$Header: getmaps.c,v 1.6 84/12/19 02:59:58 lee Exp $";
#endif

/*
 * getmaps
 *
 * Get the net maps from USENET as published by Karen and Mark Horton, in
 * "shar" format. Because of paranoia the sh is not used but instead a DFA
 * recognizing the appropriate commands.
 *
 * lee Ward		10/13/84
 */

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>

char	*mapgrp = "/usr/spool/news/mod/map/news";
char	*mapdir = "/usr/lib/news/maps";
char	*seqfil = "/usr/lib/news/maps/.seq";
#ifdef	LOG
char	*logfil = "/usr/lib/news/maps/.log";
#endif	LOG

#ifdef	LOG
char	*usestr = "[-l logfil] [-g group] [-s seqfile] [-a archiv-dir]";

FILE	*logsd = NULL;

#else	LOG
char	*usestr = "[-g group] [-s seqfile] [-a archiv-dir]";
#endif	LOG

void	domaps(), myabort(), mkmaps(), getwrd();
#ifdef	LOG
void	log(), logtime();
#endif	LOG

main(argc, argv)
	int	argc;
	char	*argv[];
{
	int	x;
	FILE	*seqsd;
	char	seqbuf[BUFSIZ];

	for (x = 1; x < argc; x++) {
		if (*argv[x]++ != '-') {
			fprintf(stderr, "Bad usage\n");
			fprintf(stderr, "Usage: %s %s\n", argv[0], usestr);
			exit(-1);
		}
		switch (*argv[x]) {

#ifdef	LOG
		case 'l':
			logfil = argv[++x];
			break;
#endif	LOG
		case 'g':
			mapgrp = argv[++x];
			break;
		case 's':
			seqfil = argv[++x];
			break;
		case 'a':
			mapdir = argv[++x];
			break;
		default:
			fprintf(stderr, "Bad switch\n");
			fprintf(stderr, "Usage: %s %s\n", argv[0], usestr);
			exit(-1);
		}
	}

#ifdef	LOG
	logsd = fopen(logfil, "a");

	logtime("Start");
#endif	LOG

	if (chdir(mapdir) != 0)
		myabort("Could not change directory to %s", mapdir);

	seqbuf[0] = NULL;
	if ((seqsd = fopen(seqfil, "r")) != NULL) {
		if ((x = fread(seqbuf, sizeof(char), sizeof(seqbuf),
		    seqsd)) != 0)
			seqbuf[x - 1] = NULL;
		(void )fclose(seqsd);
	}
	if ((seqsd = fopen(seqfil, "a")) == NULL)
		myabort("Could not open seq file for writing");
	(void )fseek(seqsd, 0L, 0);

	domaps(mapgrp, seqbuf, seqsd);
	(void )fclose(seqsd);

#ifdef	LOG
	logtime("End");
#endif	LOG
}

void
domaps(grp, seqbuf, seqsd)
	char	*grp, *seqbuf;
	FILE	*seqsd;
{
	char	nbuf[BUFSIZ], *nptr, *tptr;
	struct direct **filst;
	int	nfils, x;
	struct stat stbuf;
	extern int scandir(), alphasort();
	extern char *strcpy(), *strncat();

	if ((nfils = scandir(grp, &filst, (int (*)())NULL, alphasort)) == -1)
		myabort("scandir failed");

	(void )strcpy(nbuf, grp);
	nptr = nbuf + strlen(nbuf);
	*nptr++ = '/';
	*nptr = NULL;
	nbuf[BUFSIZ] = NULL;

	for (x = 0; x < nfils; x++) {
		if (strcmp(".", filst[x]->d_name) == 0 ||
		    strcmp("..", filst[x]->d_name) == 0)
			continue;
		tptr = filst[x]->d_name;
		while(*tptr && isdigit(*tptr))
			tptr++;
		if (*tptr != NULL)
			continue;
		*nptr = NULL;
		(void )strncat(nptr, filst[x]->d_name,
		    BUFSIZ - (nptr - nbuf) - 1);
		if (stat(nbuf, &stbuf) != 0) {
#ifdef	LOG
			log("Could not stat %s", nbuf);
#endif	LOG
			continue;
		}
		if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
			continue;
		if (atol(seqbuf) >= atol(filst[x]->d_name))
			continue;

		mkmaps(nbuf);
		(void )fseek(seqsd, 0L, 0);
		(void )fwrite(filst[x]->d_name, sizeof(char),
		    strlen(filst[x]->d_name), seqsd);
		(void )fputc('\n', seqsd);
		(void )fflush(seqsd);
	}
}

void
mkmaps(file)
	char	*file;
{
#define	SEARCH		1
#define	INAMAP		2
#define	SKIPPING	3

	char	buf[BUFSIZ], tofil[BUFSIZ], delim[BUFSIZ];
	int	state = SEARCH, sizdel = 0;
	FILE	*isd, *osd;
	extern FILE *fopen();


	if ((isd = fopen(file, "r")) == NULL) {
#ifdef	LOG
		log("Could not open %s. Skipping...", file);
#endif	LOG
		return;
	}

#ifdef	LOG
	log("Unarchive %s", file);
#endif	LOG
	while (fgets(buf, sizeof(buf) - 1, isd) != NULL) {
		buf[sizeof(buf)] = NULL;
		switch (state) {
		case SEARCH:
			if (gotcat(buf, tofil, BUFSIZ, delim, BUFSIZ)) {
				state = INAMAP;
				sizdel = strlen(delim);
				if ((osd = fopen(tofil, "w")) == NULL) {
#ifdef	LOG
					log("Could not open %s", tofil);
#endif	LOG
					state = SKIPPING;
				}
			}
			break;
		case SKIPPING:
		case INAMAP:
			if (strncmp(buf, delim, sizdel) == 0) {
				state = SEARCH;
				if (osd != NULL)
					(void )fclose(osd);
			}
			else if (osd != NULL)
				fputs(buf, osd);
			break;
		}
	}

#ifdef	LOG
	if (state != SEARCH)
		log("Read/sync error on %s", file);
#endif	LOG

	(void )fclose(isd);

#undef	SEARCH
#undef	INAMAP
#undef	SKIPPING
}

/*
 * gotcat
 *
 * Use a DFA to recognize
 *	cat << DELIM > OUT
 * or
 *	cat > OUT << DELIM
 *
 */

/* Transition table for the DFA */
int	ttbl[9][4] = {
		1,-1,-1,-1,
		-1,6,2,-1,
		-1,-1,-1,3,
		-1,4,-1,-1,
		-1,-1,-1,5,
		-1,-1,-1,-1,
		-1,-1,-1,7,
		-1,-1,8,-1,
		-1,-1,-1,5,
	};

gotcat(buf, tofil, tofilln, delim, delimln)
	char	*buf,
		*tofil,
		*delim;
	int	tofilln,
		delimln;
{
	int	state;
	char	*ptr;

	state = 0;			/* Start state */
	while (state != -1 && state != 5) {
		/* Eat up white */
		while (*buf != '\n' && (*buf == ' ' || *buf == '\t'))
			buf++;
		if (*buf == '>') {
			buf++;
			state = ttbl[state][1];
			continue;
		}
		if (*buf == '<' && *(buf + 1) == '<') {
			buf += 2;
			state = ttbl[state][2];
			continue;
		}
		if (*buf == 'c' && *(buf + 1) == 'a' && *(buf + 2) == 't') {
			buf += 3;
			state = ttbl[state][0];
			continue;
		}
		ptr = buf;
		while (*buf != '\n' && *buf != ' ' && *buf != '\t')
			buf++;
		if (state == 2 || state == 8)
			getwrd(ptr, buf, delim, delimln);
		else if (state == 6 || state == 4)
			getwrd(ptr, buf, tofil, tofilln);
		state = ttbl[state][3];
	}

	if (state == 5)
		return(1);
	return(0);
}

void
getwrd(fc, lc, buf, maxlen)
	char	*fc,
		*lc,
		*buf;
	int	maxlen;
{
	char	*ptr, *t1ptr, *t2ptr;

	maxlen--;
	maxlen = lc - fc > maxlen ? maxlen : lc - fc;
	ptr = buf;
	t1ptr = fc;
	while (maxlen-- != 0)
		*ptr++ = *t1ptr++;
	*ptr = NULL;

	/* Strip quotes */
	ptr = buf;
	while (*ptr != NULL) {
		if (*ptr == '\\' && (*(ptr + 1) == '\'' || *(ptr + 1) == '"'))
			ptr += 2;
		else if (*ptr == '\'' || *ptr == '"') {
			t1ptr = ptr;
			t2ptr = ptr + 1;
			while ((*t1ptr++ = *t2ptr++) != NULL)
				;
		} else
			ptr++;
	}
}
/*VARARGS1*/
void
myabort(s, a, b, c, d, e, f, g, h, i, j, k, l)
	char	*s;
{

#ifdef	LOG
	if (logsd != NULL) {
		fputs("ABORT - ", logsd);
		fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l);
		(void )fputc('\n', logsd);
		logtime("End");
	}
#endif	LOG
	exit(-1);
}

#ifdef	LOG
/*VARARGS1*/
void
log(s, a, b, c, d, e, f, g, h, i, j, k, l)
	char	*s;
{

	if (logsd == NULL)
		return;
	fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l);
	(void )fputc('\n', logsd);
	(void )fflush(logsd);
}

void
logtime(s)
	char	*s;
{
	time_t	clock;
	extern char *ctime();

	if (logsd == NULL)
		return;
	(void )time(&clock);
	fprintf(logsd, "%s %s", s, ctime(&clock));
	(void )fflush(logsd);
}
#endif	LOG
-- 
			--Lee (Ward)
			{ucbvax,convex,gatech,pur-ee}!unmvax!lee

jsq@ut-sally.UUCP (John Quarterman) (01/06/85)

> > > X
> > > XUnlike the version I posted some time back, this one doesn't have
> > > Xsecurity problems with extracting things from mod.map.all, and it
> 
> What if I don't have a chroot system call? Oh well.. Here, this
> one does not use the shell at all... I thought I posted this before?
> Gotta have libndir though.
> 

Can't say as I've run across many UNIX systems that don't have chroot.
You seem to be running 4.2BSD, so your system has it.  System V also has it.
It was introduced in Version 7, if I recall correctly.

Yes, you posted your program before.  And I posted mine before.  I claim
it's a lot easier to see that mine's more or less correct, as far as security,
since it depends only on chroot.  Also, mine not only extracts both the
UUCP and USENET maps, but (its main function) can be used to display them
to the user so that it is easy to discover information about a given host.
For example:

sally% uuhosts unmvax
UUCP mail path:
unmvax	gatech!unmvax!%s

UUCP mail host information:
#Name			unmvax
#System-CPU-OS		VAX 11/780 4.2BSD
#Organization		University of New Mexico, College of Engineering
#Contact		Lee Ward
#Electronic-Address	ucbvax!unmvax!lee
#Telephone		(505) 277-3112
#Postal-Address		Farris Engineering Center, Albuquerque, NM 87131
#Latitude-Longitude	N 35 deg. 4' 55"; W 106 deg. 37' 46"
#Remarks		
#Written-by		mccallum 7/6/84
#
unmvax	anl-mcs(DAILY), csu-cs(DAILY), gatech(DAILY), genix(HOURLY),
	nmtvax(DAILY), convex(DAILY), ucbvax(DAILY/3), unm-la(DAILY),
	losa(DAILY), csu-cs(DAILY), lanl-a(DAILY), pur-ee(DAILY),
	unm-cvax(DAILY), unm-zia(HOURLY)
#
#	alternate name
#
unmvax = unm-rvax

USENET news host information:
Name: unmvax
Organization: University of New Mexico, College of Engineering
Contact:  Lee Ward
Phone: (505) 277-3112
Postal-Address: Farris Engineering Center, Albuquerque, NM 87131
Electronic-Address: ucbvax!unmvax!lee
News: genix
Mail: gatech genix convex anl-mcs unm-la csu-cs nmtvax ucbvax avax cvax
	ivax cc70 cs ece psych
Comments: gatech genix convex anl-mcs unm-la csu-cs nmtvax ucbvax are reached
	via UUCP, avax cvax ivax cc70 cs ece psych are reached via Berknet.
	last edited 12/1/84


Doubtless people can make up their own minds as to which program to use.
If there is any continuation of this discussion, let's move it to
net.sources.bugs (or direct mail).
-- 

John Quarterman, CS Dept., University of Texas, Austin, Texas 78712 USA
jsq@ut-sally.ARPA, jsq@ut-sally.UUCP, {ihnp4,seismo,ctvax}!ut-sally!jsq