[alt.sources] HDB UUCP Utilities

scs@lokkur.dexter.mi.us (Steve Simmons) (11/12/90)

Appended below is a package of 3 utilities for managing HDB uucp.  One was
written by Bill Davidson and just recently posted here as `pending'; this
version is changed to have consistant naming and switches with other
standard HDB UUCP utilities.  Another was written by Lenny Tropiano and
released long ago to unix-pc.sources; this version is changed for consistant
naming only.  The third is a useful little shell script for telling you
about connectivity status.  The man pages all reference each other, so you
should be careful to modify them if you don't install all 3.

My advance apologies to Bill and Lenny for re-posting their modified code;
hopefully alt.sources is a loose enough framework that they won't be
offended.

Enjoy!

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  ReadMe Files uupend uureroute uust uupend/Makefile
#   uupend/uupend.8 uupend/uupend.c uureroute/Makefile
#   uureroute/README uureroute/config.h uureroute/uureroute.8
#   uureroute/uureroute.c uust/Makefile uust/uust uust/uust.8
# Wrapped by scs@lokkur.dexter.mi.us on Mon Nov 12 00:04:08 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ReadMe' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ReadMe'\"
else
echo shar: Extracting \"'ReadMe'\" \(3693 characters\)
sed "s/^X//" >'ReadMe' <<'END_OF_FILE'
XThis is a package of little helping utilities which I use with HDB uucp
Xat a number of different sites.  They run under Ultrix, SunOS 3.5, and
XSunOS 4.1.  Some are original, some are modified by me to make them a
X'better fit' for other uucp utilities.  The utilities are:
X
Xuust:	A simple but bulletproof shell script to prints a description
X	of currect connectivity status.  Converts some of those mysterious
X	numbers in /{usr,var}/spool/uucp/.Status/* into human-readable
X	data.  You will need to adjust the manpage and the script to reflect
X	the location of your spool directory.  This script requires the Cnews
X	utility 'ctime'.  You will probably need to adjust the script to
X	reflect the location of ctime on your system.  Written by me,
X	freely redistributable.
X
Xuureroute: Take a spooled uucp job and reroute it to another site.  This
X	is particularly useful if you have a number of uucp connections
X	and know one is down for a fairly long time.  You can reroute
X	around the dead site, delivering mail properly.  A real lifesaver
X	sometimes.  Originally written by Lenny Tropiano of ICUS systems
X	for the UNIX-PC.  I made minimal changes to remove some UNIX-PC
X	specific stuff and renamed it from `reroute' to `uureroute' in
X	keeping with standard uucp utility nomenclature.  You may want
X	to adjust the uucp spool partition location, but aside from that
X	this has worked pretty much without modification on all HDB systems
X	I've tried.  Only the man page has changed to reflect the name
X	and location change.  The makefile is new.
X
XHere is Lenny's original README:
X
X:This has been something I've always needed on my machine.  For quite a long
X:time I was for "FORCED" rerouting of mail.  Then I noticed that the
X:maps sometimes weren't up-to-date, and it was hard for me locally to 
X:send mail without having to go through several incantations to do it.  
X:This program basically is an utility for HoneyDanBer UUCP (HDB) 
X:[but can be changed to support non-HDB uucp fairly easily, I think] 
X:to take a rmail job already queued for a machine, and requeue it for 
X:another machine.   
X:
X:Sometimes I've found that I do have several ways to get to one site, in
X:my mind they are "almost" all equal in costs.  So if for some reason
X:the pathalias sends it one way, and then the machine goes down before
X:it's delivered off my machine, I have an "out" now and I can reroute
X:it via the alternative path.
X:
X:See the manual page for more detail on how reroute can be utililized.
X:Any changes to this program, patches or otherwise should kindly be sent
X:my way (so my copy is up-to-date!)
X:
X:After reading over the manual page, edit config.h to your liking, Makefile,
X:and just "make install" as root.
X
Xuupend:	Examine one or more systems to see what jobs have been delivered
X	but are still pending execution.  Originally written by Bill
X	Davidson; my version is considerably modified and somewhat
X	extended.  Davidson called it `pending', I renamed it to `uupend'
X	in keeping with standard uucp utility nomenclature.  The makefile
X	is new.
X
XHere are the original comments from Bill Davidson on uupend, which
Xhe posted as 'pending':
X
X:From: local@crdos1.crd.ge.COM (local software)
X:Newsgroups: alt.sources
X:Subject: Show pending jobs in HDB uucp
X:Message-ID: <2801@crdos1.crd.ge.COM>
X:Date: 29 Oct 90 21:58:30 GMT
X:Reply-To: davidsen@crdos1.crd.ge.com (bill davidsen)
X:Distribution: alt
X:
X:  After a job comes in via uucp, and before it is run via uuxqt, it is
X:in a state I call "pending." When debugging a system, or just looking
X:around, I like to see what's there. Here's my program to do that. Also
X:useful when tuning the system to determine how often to run uuxqt from
X:cron.
X
XEnjoy!
END_OF_FILE
if test 3693 -ne `wc -c <'ReadMe'`; then
    echo shar: \"'ReadMe'\" unpacked with wrong size!
fi
# end of 'ReadMe'
fi
if test -f 'Files' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Files'\"
else
echo shar: Extracting \"'Files'\" \(781 characters\)
sed "s/^X//" >'Files' <<'END_OF_FILE'
X-r--r--r--  1 scs           781 Nov 11 23:55 Files
X-r--r--r--  1 scs          3693 Nov 11 23:50 ReadMe
X-r--r--r--  1 scs          2322 Nov 11 23:50 uupend/Makefile
X-r--r--r--  1 scs          2191 Nov 11 23:52 uupend/uupend.8
X-r--r--r--  1 scs         13708 Nov 11 23:52 uupend/uupend.c
X-r--r--r--  1 scs          1473 Nov 11 23:50 uureroute/Makefile
X-r--r--r--  1 scs          1109 Nov 11 23:50 uureroute/README
X-r--r--r--  1 scs           795 Nov 11 23:50 uureroute/config.h
X-r--r--r--  1 scs          2504 Nov 11 23:50 uureroute/uureroute.8
X-r--r--r--  1 scs         10303 Nov 11 23:50 uureroute/uureroute.c
X-r--r--r--  1 scs           820 Nov 11 23:50 uust/Makefile
X-r-xr-xr-x  1 scs          1708 Nov 11 23:50 uust/uust
X-r--r--r--  1 scs          1368 Nov 11 23:50 uust/uust.8
END_OF_FILE
if test 781 -ne `wc -c <'Files'`; then
    echo shar: \"'Files'\" unpacked with wrong size!
fi
# end of 'Files'
fi
if test ! -d 'uupend' ; then
    echo shar: Creating directory \"'uupend'\"
    mkdir 'uupend'
fi
if test ! -d 'uureroute' ; then
    echo shar: Creating directory \"'uureroute'\"
    mkdir 'uureroute'
fi
if test ! -d 'uust' ; then
    echo shar: Creating directory \"'uust'\"
    mkdir 'uust'
fi
if test -f 'uupend/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uupend/Makefile'\"
else
echo shar: Extracting \"'uupend/Makefile'\" \(2322 characters\)
sed "s/^X//" >'uupend/Makefile' <<'END_OF_FILE'
X# Makefile for uupend command
X#
X# $RCSfile: Makefile,v $	$Revision: 1.3 $
X#
X# $Author: scs $	$Date: 90/11/10 11:57:01 $
X#
X# $State: Exp $	$Locker:  $
X#
X# $Log:	Makefile,v $
X# Revision 1.3  90/11/10  11:57:01  scs
X# Completed basic ansi-fication -- testing needed.
X# 
X# Revision 1.2  90/11/10  10:25:25  scs
X# Complete rewrite.  Sheesh...
X# 
X
X# Fill in with what is being made
XTARGET	= uupend
X
X# Choose your archive method
X#ARCHIVE = $(TARGET).zoo.Z
XARCHIVE = $(TARGET).tar.Z
X
X# Default places and ownerships
XMANSEC	= 1
XMAN	= /usr/man/man$(MANSEC)
XBIN	= /usr/local/bin
XLIB	= /usr/local/lib
XOWNER	= uucp
XGROUP	= bin
X
XCC	= gcc
X
XDEFS	= -I./
XDEBUG	= -O
X# Add other CFLAG definitions as needed
XCFLAGS	= $(DEBUG) $(DEFS)
X
X# The first of these two is for RCS, the second for SCCS
XPATTERN = RCS/%,v
X#PATTERN = s.%
X
XSRCS	= $(sort $(patsubst $(PATTERN),%,$(wildcard RCS/*.c,v)) $(wildcard *.c))
XOBJS	= $(subst .c,.o,$(SRCS))
XCLUDES	= $(sort $(patsubst $(PATTERN),%,$(wildcard RCS/*.h,v)) $(wildcard *.h))
XLIBS	=
X
X$(TARGET): $(OBJS)
X	$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X$(OBJS):	$(CLUDES)
X
Xall:	$(TARGET).man lint tags $(TARGET)
X
X$(TARGET).man:	$(TARGET).$(MANSEC)
X	nroff -man $(TARGET).$(MANSEC) > $(TARGET).man
X
XManifest:	$(SRCS) Makefile
X	touch Manifest
X	ls -ls $(SRCS) Makefile > Manifest
X
Xclean:
X	rm -f $(OBJS) core lint tags TAGS $(TARGET).man *~ #*#
X
Xclobber:	clean
X	rm -f $(TARGET) Make.Log $(TARGET) $(ARCHIVE)
X
Xlint:	$(SRCS)
X	lint -D lint $(DEFS) $(SRCS) > lint
X
Xtags:	$(SRCS)
X	ctags $(SRCS)
X
XTAGS:	$(SRCS) $(CLUDES)
X	etags $(SRCS) $(CLUDES)
X
Xinstall:	install.man install.$(TARGET)
X
Xinstall.man:	$(TARGET).$(MANSEC)
X	install -m 444 -o $(OWNER) -g $(GROUP) -c $(TARGET).$(MANSEC) $(MAN)
X
Xinstall.$(TARGET):	$(TARGET)
X	install -m 4511 -o $(OWNER) -g $(GROUP) -s -c $(TARGET) $(BIN)
X
X#  These rules are from the original author, with some mods to make it
X#  easy to flip between RCS and SCCS.
X#
X# magic makerule for SCCS
X.c~.c:
X	get $<
X
XZARCHIVE = s.uupend.c Makefile uupend.c
XTARCHIVE = RCS/uupend.c,v RCS/uupend.1,v RCS/Makefile,v
XSHARLIST = uupend.1 Makefile uupend.c
X
Xarchive:	$(ARCHIVE)
X
Xshar:	uupend.shar
X
Xuupend.shar:	$(SHARLIST)
X	shar $? > uupend.shar
X
Xuupend.zoo:	$(ZARCHIVE)
X	zoo aunM uupend.zoo $?
X
Xuupend.tar.Z:	uupend.tar
X	@rm -f uupend.tar.Z
X	compress uupend.tar
X
Xuupend.tar:	$(TARCHIVE)
X	tar cvf $@ $?
END_OF_FILE
if test 2322 -ne `wc -c <'uupend/Makefile'`; then
    echo shar: \"'uupend/Makefile'\" unpacked with wrong size!
fi
# end of 'uupend/Makefile'
fi
if test -f 'uupend/uupend.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uupend/uupend.8'\"
else
echo shar: Extracting \"'uupend/uupend.8'\" \(2191 characters\)
sed "s/^X//" >'uupend/uupend.8' <<'END_OF_FILE'
X.\" Manual page for command uupend
X.\"
X.\" $RCSfile: uupend.8,v $	$Revision: 1.2 $
X.\"
X.\" $Author: scs $	$Date: 90/11/11 23:40:27 $
X.\"
X.\" $State: Exp $	$Locker:  $
X.\"
X.\" $Log:	uupend.8,v $
XRevision 1.2  90/11/11  23:40:27  scs
XUpdated to document new switches, change to section 8.
X
X.TH uupend 8 "November 12, 1990" "Local"
X.SH NAME
Xuupend \- list uucp actions pending for remote site(s)
X.SH SYNOPSIS
Xuupend [ -h ] [ -v ] [ -l site1 ] [ -l site2 ] ...
X.SH DESCRIPTION
XThe \fBuupend\fP command shows jobs received from a remote site which
Xhave not yet been processed by
X.I uuxqt.
XThere are jobs which will be executed locally at some future time.
X.SH OPTIONS
X.TI -v
XThe
X.I -v
Xswitch will cause
X.B uupend
Xto print out version and copyright information.
X.TI -h
XThe
X.I -h
Xswitch will cause
X.B uupend
Xto print out a help message.
X.TI -s
XThe
X.I -s
Xswitch is used to indicate which systems
Xyou wish to check.
XYou must indicate at least one system.
X.SH EXAMPLES
X.li
X  $ uupend -s maxxwell -s phred
X
X     Job             User            Input File      Task
X    crdgw1X0T9Q     root crdgw1     D.crdgw1b0T9S   rmail stugr02!bob
X    No pending actions for `phred'.
X.lo
X.SH FILES
X/usr/spool/uucp/site/*
X.SH "SEE ALSO"
Xuustat(8), uust(8), uureroute(8)
X.SH DIAGNOSTICS
XCan't get working dir - invalid site name of no directory for this site.
X.br
XCan't start ls - too many processes or /bin/ls missing.
X.br
XCan't open info file - sync error, uuxqt running, or access denied.
X.SS INSTALLATION
XThis program will only run from the uucp user (unless you security is
X\fIvery\fP lax), but may be installed setuid to uucp.
X.SH BUGS
XPlease report them to Steve Simmons.
XSee
X.B AUTHORS
X.SH LIMITATIONS
XOnly works for HDB uucp.
X.SH AUTHORS
XBill Davidsen, davidsen@crdos1.crd.ge.com.
XSteve Simmons, scs@lokkur.dexter.mi.us.
X.SH COPYRIGHT
XCopyright (c) 1988,1990 by Bill Davidsen, All rights reserved. This
Xprogram and documentation may be freely distributed and used providing
Xthe copyright notices are kept intact.
XChanges copyright 1990, Steven C. Simmons.
XAll rights reserved.
XThe changes to this program and documentation may be freely
Xdistributed and used providing both copyright notices are kept intact.
END_OF_FILE
if test 2191 -ne `wc -c <'uupend/uupend.8'`; then
    echo shar: \"'uupend/uupend.8'\" unpacked with wrong size!
fi
# end of 'uupend/uupend.8'
fi
if test -f 'uupend/uupend.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uupend/uupend.c'\"
else
echo shar: Extracting \"'uupend/uupend.c'\" \(13708 characters\)
sed "s/^X//" >'uupend/uupend.c' <<'END_OF_FILE'
X/*
X * Program to display pending uucp actions.  Assume HDB uucp.  Originally
X * written by Bill Davidson of General Electric, davidsen@@crdos1.crd.ge.com.
X * Taken from pending.c v1.2, 10/29/90.  Bill's copyright:
X * 
X * Copyright 1988 by Bill Davidsen, all rights reserved
X * May be freely distributed and used providing copyright
X * notices are kept intact.
X *
X * Changes Copyright 1990 Steven C. Simmons (scs@lokkur.dexter.mi.us)
X * All rights reserved.  May be freely distributed and used providing
X * copyright notices are kept intact.
X *
X * $RCSfile: uupend.c,v $	$Revision: 1.4 $
X *
X * $Author: scs $	$Date: 90/11/11 18:25:10 $
X *
X * $State: Exp $	$Locker:  $
X *
X * $Log:	uupend.c,v $
X * Revision 1.4  90/11/11  18:25:10  scs
X * Added full switch processing, -v and -h switch, multiple simultaneous
X * system checks, a number of modules from the Inland Sea library, and
X * lots of general robustness.  Error messages are improved.  Full ANSI
X * and non-ANSI compilation tested.
X * 
X * Revision 1.3  90/11/10  11:56:44  scs
X * Completed basic ansi-fication -- testing needed.
X */
X
X
Xstatic char	rcsid[] = "$Id: uupend.c,v 1.4 90/11/11 18:25:10 scs Exp $" ;
X
X# include	<stdio.h>
X# include	<ctype.h>
X
X
X#define EOS	'\0'
X
X#ifndef	SPOOLDIR
X# define	SPOOLDIR	"/var/spool/uucp"
X#endif
X
X#ifndef	MAXPATHLEN
X# define	MAXPATHLEN	1024
X#endif
X
X#ifndef	MAXNAMELEN
X# define	MAXNAMELEN	64
X#endif
X
X#ifndef	BUFSIZ
X# define	BUFSIZE	256
X#endif
X
X#ifdef	__STDC__
Xextern FILE	*popen( char *c, char *t ) ;
Xextern FILE	*fopen( char *s, char *m ) ;
Xextern void	exit( int ) ;
Xextern int	chdir( char *s ) ;
Xextern int	perror( char *s ) ;
Xextern char	*fgets( char *string, int len, FILE *f ) ;
Xextern int	strlen( char *string ) ;
Xextern int	fclose( FILE *f ) ;
Xextern int	pclose( FILE *f ) ;
Xextern int	fprintf( FILE *f, char *s, ... ) ;
Xextern int	printf( char *s, ... ) ;
Xextern char	*sprintf( char *s, char *f, ... ) ;
Xextern int	sscanf( char *str, char *pat, ... ) ;
Xextern int	fputs( char *s, FILE *f ) ; 
Xextern int	strncmp( char *str1, char *str2, int len ) ;
Xextern void	*malloc( int len ) ;
Xextern char	*strcpy( char *target, char *source ) ;
Xextern int	strlen( char *string ) ;
Xextern char	*strchr(char *string, char c ) ;
X
X#else
Xextern FILE	*popen() ;
Xextern FILE	*fopen() ;
Xextern void	exit() ;
Xextern int	chdir() ;
Xextern int	perror() ;
Xextern char	*fgets() ;
Xextern int	strlen() ;
Xextern int	sscanf() ;
Xextern int	strncmp() ;
Xextern int	fclose() ;
Xextern int	pclose() ;
Xextern int	fputs() ;
Xextern int	getopt() ;
Xextern char	*malloc() ;
Xextern char	*strcpy() ;
Xextern int	strlen() ;
Xextern char*	strchr() ;
X#endif
X
X
Xtypedef	int	bool ;
X
X# define	TRUE	(1)
X# define	FALSE	(0)
X
Xextern int	errno ;
X
Xstatic bool	version_flag = FALSE ;
Xstatic bool	help_flag = FALSE ;
X
Xstatic char	*SystemList[ BUFSIZ ] ;
X
Xstatic char	*ProgName ;
X
Xstatic char	*IDent[] =
X{
X	"@( # )pending.c v1.2, 10/29/90",
X	rcsid,
X	"Copyright 1988 by Bill Davidsen, all rights reserved.  May be freely",
X	"distributed and used providing copyright notices are kept intact.",
X	"Changes Copyright 1990 by Steven C. Simmons, same terms.",
X	NULL
X} ;
X
X
X/*
X *  Library function to create new copies of strings.  Creates
X *  exactly the same size offered.  General scheme:
X *
X *  Create a new string.  Return a pointer to it.  Return null
X *  if malloc fails, or if the incoming string is a null pointer.
X *  A zero-length string (ie, '\0' only) is a valid string, so
X *  we'll duplicate it.
X *
X *  History -- this function was once part of SCS standard library.
X *  It has been moved here rather than carry the whole library along.
X */
X
X
X#ifdef	__STDC__
Xchar	*NewString( char* string )
X#else
Xchar	*NewString( string )
Xregister char	*string ;
X#endif
X{
X	register unsigned	len ;
X	register char*		new_string ;
X
X	if ( string == NULL )
X		return NULL ;
X	len = strlen( string ) ;
X	if ( NULL == ( new_string = malloc( len + 1 ) ) )
X		return NULL ;
X	(void) strcpy( new_string, string ) ;
X	return new_string ;
X}
X
X
X/*	Module-wide variables for OptionParse	*/
X
Xstatic int	argnum = 1 ;	/* current location in argv */
Xstatic int	argchar = 1 ;	/* which character in arg we're looking at */
Xstatic char	swflag = '-' ;	/* what character delimits a switch */
Xstatic char	extarg = ':' ;	/* flag for extended argument wanted */
Xstatic char	errflg = '?' ;	/* what to return on a non-existant switch */
Xstatic char	dummy[ 2 ] ;	/* buffer to build error returns */
X
X/*	Global variables for OptionParse	*/
X
Xchar*	OptionSwitch = NULL ;	/* pointer to return an extended arguement */
X
X
X/*
X *  OptionParse -- scan the arg list and return next arguement
X *
X *  parameters
X *	argc -- maximum number of arguements
X *	argv -- array of argc pointers to arguements
X *	opts -- list of valid switches
X *
X *  return value (int)
X *	null character if no switch is on the arguement, and
X *		OptionSwitch points to the arg;
X *	valid character if found behind switch, and OptionSwitch
X *		points to extended if requested (NULL if not or
X *		if there is none);
X *	errflg if illegal character found behind switch and
X *		OptionSwitch points to illegal character;
X *	EOF if no args to process.
X *
X *  This function scans the arguement list passed in, starting
X *  from an internal pointer into the list.  Each time it is
X *  called, the internal pointer is reset so the next call will
X *  scan the next arg.
X *
X *  An arguement is first checked to see if it begins with the
X *  switch character.  If it does not, it is assumed to be a
X *  non-switched arguement (eg, a file name).  A pointer to is
X *  is copied into OptionSwitch, and we return a null character.
X *
X *  If it is a switched arg, we return check the first character
X *  following the switch against the opts list.  If invalid, we
X *  set OptionSwitch to point to it and return errflag.
X *
X *  If valid, we then check to see if there should be an extended
X *  arguement.  If there should not be, we set OptionSwitch to NULL
X *  and return the switch character.
X *
X *  If there should be an extended arg, we check for it in two
X *  places: first, following the switch character in the same
X *  arguement.  If not found there, we look for the next arg.  If
X *  not found, set OptionSwitch NULL.  Return the switch character.
X *
X *	Format of valid switches string -- all of the valid switches
X *	lumped together into a single string.  Switches which have
X *	extended arguements must be followed by the extended arg
X *	flag, ':' for default.  Thus "abc:d" would mean the switches
X *	-a, -b, -c, and -d are all legal.  In addition, the -c
X *	switch may have some sort of trailing parameter.
X *
X *  History -- this function was once part of SCS standard library.
X *  It has been moved here rather than carry the whole library along.
X *  There are more functions relating to this, but they have been
X *  removed as irrelevant to this implementation.
X */
X
X#ifdef __STDC__
Xint	OptionParse( int argc, char *argv[], char *opts )
X#else
Xint	OptionParse( argc, argv, opts )
Xint	argc ;
Xchar	*argv[] ;
Xchar	*opts ;
X#endif
X{
X	register char	c ;	/* General char holder */
X	register char*	cp ;	/* Pointer into options list for this switch */
X
X	OptionSwitch = NULL ;
X
X	/*
X	 * If we're just starting to look at this list ( argchar == 1 )
X	 * we just check two things -- end of arg list, and switch presence
X	 */
X	
X	if ( argchar == 1 )
X	{
X		if ( argnum >= argc )	/* At end of arg list? */
X			return EOF ;
X		if ( argv[ argnum ][ 0 ] != swflag )
X		{
X			/* No switch flag on arg */
X			OptionSwitch = argv[ argnum++ ] ;
X			return '\0' ;
X		}
X		else if ( argv[ argnum ][ 1 ] == '\0' )
X		{	/* No arg following switch char */
X			/* Return switch as arg, not switch */
X			dummy[ 0 ] = argv[ argnum++ ][ 0 ] ;
X			OptionSwitch = (char*) dummy ;
X			return '\0' ;
X		}
X	}
X
X	/*
X	 * When we're past the first character, it means we are
X	 * seeing multiple characters under a single switch, eg, '-TagP'.
X	 * This is the equivalent of '-T -a -g -P', unless of course
X	 * extended processing is desired.  Thus, if 'T' was a solo
X	 * switch but 'a' required extended processing, '-TagP' would
X	 * be equivalent to '-T -a gP', where 'gP' is the extended arg
X	 * of 'a'.
X	 */
X	
X	c = argv[ argnum ][ argchar ] ;
X	/* Check to see if this is a good switch */
X	if ( ( cp = strchr( opts, c ) ) == NULL )
X	{
X		/* Bad switch. */
X		if ( argv[ argnum ][ ++argchar ] == '\0' )
X		{	/* If end of arg, reset to look at next arg */
X			argnum++ ;
X			argchar = 1 ;
X		}
X		/* Build the error return and return it */
X		dummy[ 0 ] = c ;
X		OptionSwitch = (char*) dummy ;
X		return errflg ;
X	}
X
X	/*
X	 * Check for extended arg with this switch.  Check both
X	 * formats, either '-S extarg' (two args) or '-Sextarg' (one arg)
X	 */
X	
X	if ( *++cp == extarg )
X	{
X		if ( argv[ argnum ][ argchar + 1 ] != '\0' )
X			OptionSwitch = &argv[ argnum++ ][ argchar + 1 ] ;
X		else if ( ++argnum < argc )	/* Found extended */
X			OptionSwitch = argv[ argnum++ ] ;
X		argchar = 1 ;	/* Start at beginning of next arg */
X	}
X	else if ( argv[ argnum ][ ++argchar ] == '\0' )
X	{
X		/* Arg complete -- reset for next arg */
X		argchar = 1 ;
X		argnum++ ;
X	}
X	return c ;
X}
X
X
X
X/*
X * Print a usage message.  If the specified value is non-negative, exit
X * with that value.
X */
X
X#ifdef	__STDC__
Xstatic void	usage( int exitval )
X#else
Xstatic void	usage( exitval )
Xint	exitval ;
X#endif
X{
X	(void) fprintf( stderr, "Usage: %s [ -v ] [ -h ] [ -s system ]\n", ProgName ) ;
X	(void) fprintf( stderr, "\tThe `-v' flag will print version information.\n" ) ;
X	(void) fprintf( stderr, "\tThe `-h' flag will print this information and quit.\n" ) ;
X	(void) fprintf( stderr, "\tThe `-s' flag will select a system to examine.\n" ) ;
X	if ( exitval >= 0 )
X		exit( exitval ) ;
X	return ;
X}
X
X
X/*
X * Do the report for a given system
X */
X
X#ifdef	__STDC__
Xvoid	examine_pending( char *name )
X#else
Xvoid	examine_pending( name )
Xchar	*name ;
X#endif
X{
X	int	first1 = 1 ;	/* flag for 1st time thru */
X	FILE	*lsout ;
X	FILE	*xfile ;
X	char	filename[ MAXNAMELEN + 1 ] ;
X	char	xfilename[ MAXNAMELEN + 1 ] ;
X	char	dataline[ BUFSIZ + 1 ] ;
X	char	errbuf[ BUFSIZ ] ;
X	int	slen ;		/* string length */
X
X	/*
X	 *  This gives us a prealphabetized list of the pending
X	 *  execution files.  It beats the heck out of writing code
X	 *  to open, read, and sort a directory.
X	 */
X	lsout = popen( "ls X.* 2>&1", "r" ) ;
X	if ( lsout == NULL )
X	{
X		(void) perror( "Can't start ls" ) ;
X		exit( 1 ) ;
X	}
X
X	filename[ MAXNAMELEN ] = EOS ;
X	/* loop checking files */
X	while ( fgets( filename,  MAXNAMELEN, lsout ) )
X	{
X		if ( strlen( filename ) > MAXNAMELEN )
X		{
X			(void) fprintf( stderr, "The filename `%s' is too long, skipping.\n, filename" ) ;
X			break ;
X		}
X
X		/* see if there's a file found */
X		(void) sscanf( filename, "%s", xfilename ) ;
X		if ( strncmp( xfilename, "X.*", 3 ) == 0 )
X		{
X			(void) printf( "No actions pending for `%s'.\n", name ) ;
X			break ;
X		}
X
X		/* open the file for reading */
X		xfile = fopen( xfilename, "r" ) ;
X		if ( xfile == NULL )
X		{
X			(void) sprintf( errbuf, "Can't open info file `%s' for system `%s'.\n", xfilename, name ) ;
X			(void) perror( errbuf ) ;
X			break ;
X		}
X
X		/* check for header needed */
X		if ( first1 )
X		{
X			first1 = 0 ;
X			(void) printf( "\n %-15s %-15s %-15s %s\n",
X				"Job", "User", "Input File", "Task" ) ;
X		}
X
X		/* scan the file for various things */
X		(void) printf( "%-15s ", xfilename + 2 ) ;
X		dataline[ MAXNAMELEN ] = EOS ;
X		while ( fgets( dataline,  MAXNAMELEN, xfile ) )
X		{
X			if ( ( slen = strlen( dataline ) ) > ( MAXNAMELEN -1 ) )
X			{
X				/* line too long */
X				while ( getc( xfile ) != '\n' ) ;
X			}
X			dataline[slen - 1] = EOS ;
X
X			switch ( dataline[0] )
X			{
X			case 'U':	/* originating user */
X				(void) printf( "%-15s ", dataline + 2 ) ;
X				break ;
X			case 'C':	/* command */
X				(void) printf( "%s\n", dataline + 2 ) ;
X				break ;
X			case 'I':	/* input file */
X				(void) printf( "%-15s ", dataline + 2 ) ;
X				break ;
X			}
X		}
X
X		/* clean up */
X		(void) fclose( xfile ) ;
X	}
X	(void) pclose( lsout ) ;
X}
X
X
X#ifdef	__STDC__
Xint	main( int argc, char *argv[] )
X#else
Xmain( argc, argv )
Xint	argc ;
Xchar	*argv[] ;
X#endif
X{
X	int	switchchar ;
X	int	list_index = 0 ;
X	char	**system ;
X
X	/* test input */
X
X	ProgName = argv[ 0 ] ;
X	if ( argc < 2 )
X		usage( 1 ) ;
X        if ( argc < 2 )
X	{
X		(void) fprintf( stderr, "%s: You must specify something to do!\n", ProgName ) ;
X		usage( 1 ) ;
X	}
X	while ( EOF != ( switchchar = OptionParse( argc, argv, "hvs:" ) ) )
X	{
X		switch( switchchar )
X		{
X		  case 's':
X			if ( list_index == BUFSIZ )
X			{
X				(void) fprintf( stderr, "%s: Sorry, you cannot specify more than %d systems.\n", ProgName, BUFSIZ ) ;
X				exit( 1 ) ;
X			}
X			SystemList[ list_index++ ] = NewString( OptionSwitch ) ;
X			break ;
X		  case 'v':
X			version_flag = TRUE ;
X			break ;
X		  case 'h':
X			help_flag = TRUE ;
X			break ;
X		  default:
X			(void) fprintf( stderr, "%s: No such switch as `-%c'.\n", ProgName, *OptionSwitch ) ;
X			usage( 1 ) ;
X			break ;
X		}
X	}
X	SystemList[ list_index ] = NULL ;
X
X	if ( version_flag )
X	{
X		char	**msgptr ;
X		for ( msgptr = IDent ; *msgptr != NULL ; msgptr++ )
X			(void) printf( "%s\n", *msgptr ) ;
X	}
X	if ( help_flag )
X	{
X		usage( -1 ) ;
X	}
X	/*
X	 * There was at least one valid switch, but did they ask for
X	 * a system?  If not, exit quietly
X	 */
X	if ( list_index == 0 )
X		exit( 0 ) ;
X	
X	if ( 0 != chdir( SPOOLDIR ) )
X	{
X		(void) fprintf( stderr, "%s: could not access spool directory `%s'.\n", ProgName, SPOOLDIR ) ;
X		exit( 1 ) ;
X	}
X	for ( system = SystemList ; *system != NULL ; system++ )
X	{
X		if ( 0 != chdir( *system ) )
X			(void) fprintf( stderr, "%s: no such system as `%s'.\n", ProgName, *system ) ;
X		else
X		{
X			examine_pending( *system ) ;
X			(void) chdir( ".." ) ;
X		}
X	}
X	exit( 0 ) ;
X	/* next two lines are to silence lint and gcc -Wall */
X	/* NOTREACHED */
X	return 0 ;
X}
END_OF_FILE
if test 13708 -ne `wc -c <'uupend/uupend.c'`; then
    echo shar: \"'uupend/uupend.c'\" unpacked with wrong size!
fi
# end of 'uupend/uupend.c'
fi
if test -f 'uureroute/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uureroute/Makefile'\"
else
echo shar: Extracting \"'uureroute/Makefile'\" \(1473 characters\)
sed "s/^X//" >'uureroute/Makefile' <<'END_OF_FILE'
X# Makefile for uureroute
X#
X# $RCSfile: Makefile,v $	$Revision: 1.3 $
X#
X# $Author: scs $	$Date: 90/11/11 22:52:40 $
X#
X# $State: Exp $	$Locker:  $
X#
X# $Log:	Makefile,v $
X# Revision 1.3  90/11/11  22:52:40  scs
X# Converted to general makefile.
X# 
X
X# Fill in with what is being made
XTARGET	= uureroute
X
X# Default places and ownerships
XMANSEC	= 8
XMAN	= /usr/man/man$(MANSEC)
XBIN	= /usr/local/bin
XLIB	= /usr/local/lib
XOWNER	= bin
XGROUP	= bin
X
XCC	= gcc
XDEFS	= -I./
XDEBUG	= -O
XCFLAGS	= $(DEBUG) $(DEFS)
XPATTERN = RCS/%,v
XSRCS	= $(sort $(patsubst $(PATTERN),%,$(wildcard RCS/*.c,v)) $(wildcard *.c))
XOBJS	= $(subst .c,.o,$(SRCS))
XCLUDES	= $(sort $(patsubst $(PATTERN),%,$(wildcard RCS/*.h,v)) $(wildcard *.h))
XLIBS	=
X
X$(TARGET): $(OBJS)
X	$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X$(OBJS):	$(CLUDES)
X
Xall:	$(TARGET).man lint tags $(TARGET)
X
X$(TARGET).man:	$(TARGET).$(MANSEC)
X	nroff -man $(TARGET).$(MANSEC) > $(TARGET).man
X
XManifest:	$(SRCS) Makefile
X	touch Manifest
X	ls -ls $(SRCS) Makefile > Manifest
X
Xclean:
X	rm -f $(OBJS) core lint tags TAGS $(TARGET).man *~ #*#
X
Xclobber:	clean
X	rm -f $(TARGET) Make.Log
X
Xlint:	$(SRCS)
X	lint -D lint $(DEFS) $(SRCS) > lint
X
Xtags:	$(SRCS)
X	ctags $(SRCS)
X
XTAGS:	$(SRCS) $(CLUDES)
X	etags $(SRCS) $(CLUDES)
X
Xinstall:	install.$(TARGET) install.man
X
Xinstall.man:	$(TARGET).$(MANSEC)
X	install -m 444 -o $(OWNER) -g $(GROUP) -c $(TARGET).$(MANSEC) $(MAN)
X
Xinstall.$(TARGET):	$(TARGET)
X	install -m 511 -o $(OWNER) -g $(GROUP) -s -c $(TARGET) $(BIN)
END_OF_FILE
if test 1473 -ne `wc -c <'uureroute/Makefile'`; then
    echo shar: \"'uureroute/Makefile'\" unpacked with wrong size!
fi
# end of 'uureroute/Makefile'
fi
if test -f 'uureroute/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uureroute/README'\"
else
echo shar: Extracting \"'uureroute/README'\" \(1109 characters\)
sed "s/^X//" >'uureroute/README' <<'END_OF_FILE'
XThis has been something I've always needed on my machine.  For quite a long
Xtime I was for "FORCED" rerouting of mail.  Then I noticed that the
Xmaps sometimes weren't up-to-date, and it was hard for me locally to 
Xsend mail without having to go through several incantations to do it.  
XThis program basically is an utility for HoneyDanBer UUCP (HDB) 
X[but can be changed to support non-HDB uucp fairly easily, I think] 
Xto take a rmail job already queued for a machine, and requeue it for 
Xanother machine.   
X
XSometimes I've found that I do have several ways to get to one site, in
Xmy mind they are "almost" all equal in costs.  So if for some reason
Xthe pathalias sends it one way, and then the machine goes down before
Xit's delivered off my machine, I have an "out" now and I can reroute
Xit via the alternative path.
X
XSee the manual page for more detail on how reroute can be utililized.
XAny changes to this program, patches or otherwise should kindly be sent
Xmy way (so my copy is up-to-date!)
X
XAfter reading over the manual page, edit config.h to your liking, Makefile,
Xand just "make install" as root.
X
END_OF_FILE
if test 1109 -ne `wc -c <'uureroute/README'`; then
    echo shar: \"'uureroute/README'\" unpacked with wrong size!
fi
# end of 'uureroute/README'
fi
if test -f 'uureroute/config.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uureroute/config.h'\"
else
echo shar: Extracting \"'uureroute/config.h'\" \(795 characters\)
sed "s/^X//" >'uureroute/config.h' <<'END_OF_FILE'
X/* 
X * Header file for: reroute.c [Version 1.0]
X * by:  Lenny Tropiano
X *      ICUS Software Systems (c) 1989
X *      lenny@icus.islp.ny.us -or- icus!lenny
X */
X
X#define	PRIV_UID		1000
X#define	PRIV_GID		10
X
X/* Declare your default grade for rmail transmissions */
X
X#define	DEFAULT_RMAIL_GRADE	'M'
X
X/* Root uucp spool directory to start searching for uucp jobs */
X
X#define	UUCP_SPOOL		"/var/spool/uucp"
X
X/* Executables (their full paths) needed to run this program */
X
X#define	UUX			"/usr/bin/uux"
X#define	UUNAME			"/usr/bin/uuname"
X
X/* Some system constants */
X
X#define	SYSLEN			10
X#define	FILELEN			20
X
X/* UUX Command to execute the new rmail command */
X
X#define UUX_CMD(cmd, grade, retaddr, flags, sys, path) \
X	"%s -g%c -a%s %s - \"%s!rmail \(%s\)\"", \
X	cmd, grade, retaddr, flags, sys, path
END_OF_FILE
if test 795 -ne `wc -c <'uureroute/config.h'`; then
    echo shar: \"'uureroute/config.h'\" unpacked with wrong size!
fi
# end of 'uureroute/config.h'
fi
if test -f 'uureroute/uureroute.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uureroute/uureroute.8'\"
else
echo shar: Extracting \"'uureroute/uureroute.8'\" \(2504 characters\)
sed "s/^X//" >'uureroute/uureroute.8' <<'END_OF_FILE'
X.TH HDBREROUTE 1L LOCAL
X.SH NAME
Xuureroute \- HDB UUCP rmail job rerouter
X.SH SYNOPSIS
X.B uureroute
X[-vrC] [-g grade] [-a address] [-j job] [-p path]
X.SH DESCRIPTION
X.B uureroute
Xwill take an already queued rmail job, and reroute it using the given
Xpath (-p).  It takes the job (if you are unable to reach the queued machine)
Xand queues it to the new machine using the given path.
X.RE
X.SH OPTIONS
Xuureroute can be run with the following options.
X.TP
X-v
Xverbose flag, tells you it's doing something.  (Default: be quiet)
X.TP
X-r
Xqueue the job to the new path, but don't start the uucico (eg. uux -r)
X.TP
X-C
Xcopy the mail message to the new path, but leave the old one still queued
X.TP
X-g grade
XSet the grade of the mail job to "grade".  (Default = "M", as defined in
Xconfig.h)
X.TP
X-a return address
XSet the return address notification to a specified mail path (Default =
Xcurrent set mail path of the job queued)
X.TP
X-j jobid
Xroute job "jobid"
X.TP
X-p path
Xroute job to new bang-path (must have at least one "!" and the first 
Xmachine in front of the "!" must be known by local machine, uuname(1).
X.SH EXAMPLES
X.B 
XHere are some examples for using uureroute.
X.nf
X
Xuureroute -j machM6bff -p nodea!nodeb!nodec!user
X			# Reroute job machM6bff to 
X			  nodea!nodeb!nodec!user and remove the old 
X			  job, start uucico immediately to nodea
X
Xuureroute -a root -j machM6bff -p nodea!nodeb!nodec!user
X			# Reroute job machM6bff to 
X			  nodea!nodeb!nodec!user and remove the old 
X			  job, start uucico immediately to nodea, if the
X			  fails, the return path is to "root"
X
Xuureroute -v -gX -j machM6bff -p nodea!nodeb!nodec!user
X			# Reroute job machM6bff to 
X			  nodea!nodeb!nodec!user and remove the old 
X			  job, set the grade to "X" and be a little 
X			  verbose about it, start uucico immediately 
X			  to nodea
X
Xuureroute -rC -a nodeZ!root -gZ -j machM6bff -p nodea!nodeb!nodec!user
X			# Reroute job machM6bff to 
X			  nodea!nodeb!nodec!user and save the old 
X			  job, set the grade to "Z" and be quiet 
X			  about the entire thing, don't start
X			  uucico until uusched time, if return 
X			  notification of needs to be sent, send it to
X			  nodeZ!root
X
Xuureroute -rC -gZ 
XJob id  : machM6bff 
XNew path: nodea!nodeb!nodec!user
X			# Same as above, just the -j and -p options 
X			  weren't on the command line
X.fi
X
X.RE
X.SH FILES
X.nf
X/usr/spool/uucp			Root directory for uucp spool jobs
X.fi
X.SH SEE ALSO
Xuuname(1), uux(1)
X.SH AUTHOR
X.RS
X.PP
XLenny Tropiano, ICUS Software Systems (lenny@icus.islp.ny.us)
X.RE
END_OF_FILE
if test 2504 -ne `wc -c <'uureroute/uureroute.8'`; then
    echo shar: \"'uureroute/uureroute.8'\" unpacked with wrong size!
fi
# end of 'uureroute/uureroute.8'
fi
if test -f 'uureroute/uureroute.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uureroute/uureroute.c'\"
else
echo shar: Extracting \"'uureroute/uureroute.c'\" \(10303 characters\)
sed "s/^X//" >'uureroute/uureroute.c' <<'END_OF_FILE'
X/************************************************************************\
X**                                                                      **
X** Program name:    reroute.c (Reroute rmail uux jobs to another node)  **
X** Programmer:      Lenny Tropiano                                      **
X** E-Mail address:  ...!icus!lenny -or- lenny@icus.islp.ny.us           **
X** Organization:    ICUS Software Systems     (c)1989                   **
X** Date:            November 5, 1989  [Version 1.0]                     **
X** Patchlevel:      November 6, 1989  [Version 1.1]                     **
X** Patchlevel:      November 7, 1989  [Version 1.2]: bug fix where it   **
X**                  wasn't stat()'ing the full path of the directory,   **
X**                  in find_path().                                     **
X**                  Reported by Lee Ziegenhals (lcz@sat.datapoint.com)  **
X**                                                                      **
X**************************************************************************
X**                                                                      **
X** Program use:  This program will take a queued "rmail" job for one    **
X**               system, and move (or reroute) the job to another node. **
X**               Sometimes a job will be queued to a system, then the   **
X**               system goes down, you (as an administrator) notices    **
X**               this, and wants to reroute the mail (your mail, most   **
X**               likely) to another site and path to get it off your    **
X**               machine before uucleanup cancels it.                   **
X**               (See manual page: reroute.1 for more information)      **
X**                                                                      **
X**************************************************************************
X**                                                                      **
X** Disclaimer:   Use of this program can be hazardous to queued mail    **
X**               if not used properly.  I take no responsibility for    **
X**               anything this program does ...                         **
X**                                                                      **
X**************************************************************************
X** Permission is granted to distribute this program by any means as     **
X** long as credit is given for my work.     I would also like to see    **
X** any modifications or enhancements to this program.                   **
X\************************************************************************/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <dirent.h>
X
X#include "config.h"
X
Xchar	*progname,			/* program name (argv[0])	*/
X	*uuxflags = "",			/* uuxflags, like -r		*/
X	buffer[BUFSIZ],			/* temporary storage buffer	*/
X	return_address[BUFSIZ],		/* return mail address buffer	*/
X	grade = DEFAULT_RMAIL_GRADE;	/* default grade for rmail	*/
Xint	verbose = 0, 			/* verbose flag?		*/
X	newaddr = 0, 			/* new return address flag?	*/
X	copyonly = 0;			/* only copy, leave original	*/
X
Xmain(argc, argv)
Xint   argc;
Xchar *argv[];
X{
X	extern	int	optind;		/* needed for getopt(3C)	*/
X	extern	char	*optarg;
X	int	c, 
X		badpath = 0,		/* bad -p option		*/
X		error_flg = 0;		/* some error on argv		*/
X	char	*jobid,			/* job id to be rerouted	*/
X		*newpath,		/* new path to be reroute to	*/
X		*strchr(),
X		qsystem[SYSLEN];	/* system name for uux		*/
X	void	reroute(),
X		digest_path();
X	int	getuid(), getgid(),
X		uid, gid;		/* user id, and group id	*/
X
X	progname = argv[0];
X
X	/* 
X	 * do a little security validation, either root, or PRIV_UID or
X	 * PRIV_GID (see config.h)
X	 */
X	uid = getuid();
X	gid = getgid();
X	if (uid != 0 && uid != PRIV_UID && gid != PRIV_GID) {
X		printf("%s: Permission denied.\n", progname);
X		exit(1);
X	}
X
X	while ((c = getopt(argc, argv, "?vrCj:p:g:a:")) != EOF) {
X		switch (c) {
X		case 'v':
X			verbose = 1;
X			break;
X		case 'C':
X			copyonly = 1;
X			break;
X		case 'r':
X			uuxflags = "-r";
X			break;
X		case 'j':
X			jobid = optarg;
X			break;
X		case 'a':
X			sprintf(return_address, "%s", optarg);
X			newaddr = 1;
X			break;
X		case 'g':
X			grade = optarg[0];
X			break;
X		case 'p':
X			newpath = optarg;
X			if (strchr(newpath,'!') == NULL) {
X				printf("Path must have at least one \"!\"\n");
X				exit(1);
X			} 
X			break;
X		case '?':
X			error_flg = 1;
X			break;
X		}
X	}
X
X	if (error_flg) {
X		fprintf(stderr,
X			"usage: %s [-vrC] [-g grade] [-a new return address] [-j job] [-p path]\n",
X			progname);
X		exit(1);
X	}
X
X	putenv("IFS=\" \n\t\"");	/* prevent any security problems */
X
X	if (jobid == (char *)NULL) {
X		printf("Job id  : ");
X		if (scanf("%s", buffer) == EOF)
X			exit(0);
X		if ((jobid = (char *)malloc(strlen(buffer)+1)) == NULL) {
X			fprintf(stderr,
X				"Cannot allocate memory for job id buffer\n");
X			exit(1);
X		}
X		strncpy(jobid, buffer, strlen(buffer));
X	}
X
X	if (newpath == (char *)NULL) {
X		do {
X			printf("New Path: ");
X			if (scanf("%s", buffer) == EOF)
X				exit(0);
X			if (strchr(buffer,'!') == NULL) {
X				printf("Path must have at least one \"!\"\n");
X				badpath = 1;
X			} else  badpath = 0;
X		} while (badpath);
X		if ((newpath = (char *)malloc(strlen(buffer)+1)) == NULL) {
X			fprintf(stderr,
X				"Cannot allocate memory for path buffer\n");
X			exit(1);
X		}
X		strncpy(newpath, buffer, strlen(buffer));
X	}
X
X	digest_path(newpath, qsystem);
X	reroute(jobid, qsystem, newpath);
X
X	exit(0);
X}
X
Xvoid reroute(jobid, qsystem, newpath)
Xchar *jobid, *qsystem, *newpath;
X{
X	char	jobfile[FILELEN], 
X		Dfile[FILELEN], 
X		Xfile[FILELEN],
X		*find_path(), 
X		*directory;
X	FILE	*fp, *pfp;
X	int	check_rmail();
X	void	copy_to();
X
X	sprintf(jobfile,"C.%s",jobid);
X	if ((directory = find_path(UUCP_SPOOL,jobfile)) == (char *)NULL) {
X		printf("%s: no uucp job with id: %s\n", progname, jobid);
X		exit(0);
X	}
X
X	if (chdir(directory) < 0) {
X		fprintf(stderr,"%s: cannot chdir() to %s\n", progname,
X			directory);
X		perror("chdir()");
X		exit(1);
X	}
X
X	if ((fp = fopen(jobfile, "r")) == NULL) {
X		fprintf(stderr,"%s: Cannot open %s for read\n", progname,
X			jobfile);
X		perror("fopen()");
X		exit(1);
X	}
X
X	if (fscanf(fp,"%*s %s %*s %*s %*s %*s %*s %*s\n", Dfile) == EOF) {
X		fprintf(stderr,"%s: malformed %s file (line 1)\n", progname,
X			jobfile);
X		exit(1);
X	}
X
X	if (fscanf(fp,"%*s %s %*s %*s %*s %*s %*s %*s\n", Xfile) == EOF) {
X		fprintf(stderr,"%s: malformed %s file (line 2)\n", progname,
X			jobfile);
X		exit(1);
X	}
X
X	fclose(fp);
X
X	if (!check_rmail(Xfile)) {
X		printf("%s: Job cannot be rerouted, not a mail job\n", 
X			progname);
X		exit(0);
X	}
X
X	sprintf(buffer,
X		UUX_CMD(UUX,grade,return_address,uuxflags,qsystem,newpath));
X	
X	if ((pfp = popen(buffer,"w")) == NULL) {
X		fprintf(stderr,"%s: cannot open write pipe channel to %s\n", 
X			progname, buffer);
X		perror("popen()");
X		exit(1);
X	}
X
X	copy_to(pfp,Dfile);
X
X	pclose(pfp);
X
X	if (verbose) {
X		printf("%s: New path is: %s!%s\n", progname, qsystem, newpath);
X		if (newaddr)
X			printf("%s: Return mail address: %s\n", progname, 
X				return_address);
X		if (grade != DEFAULT_RMAIL_GRADE)
X			printf("%s: Grade of job queued: %c\n", progname, 
X				grade);
X	}
X
X	if (!copyonly) {
X		/* 
X		 * kill the current job queued up
X		 */
X		if (unlink(jobfile) < 0) {
X			fprintf(stderr,"%s: cannot remove job file: %s",
X				progname, jobfile);
X			perror(progname);
X		}
X		if (unlink(Dfile) < 0) {
X			fprintf(stderr,"%s: cannot remove file: %s",
X				progname, Dfile);
X			perror(progname);
X		}
X		if (unlink(Xfile) < 0) {
X			fprintf(stderr,"%s: cannot remove file: %s",
X				progname, Xfile);
X			perror(progname);
X		}
X		if (verbose)
X			printf("%s: Old job (%s) removed\n",
X				progname, jobid);
X	} else
X		if (verbose)
X			printf("%s: Job (%s) not removed from queue\n",
X				progname, jobid);
X}
X
Xvoid digest_path(path, sys)
Xchar *path, *sys;
X{
X	char	*bangpos, *strchr(), *pos,
X		looksys[SYSLEN], *fgets();
X	FILE	*pfp;
X
X	bangpos = strchr(path,'!');
X	*bangpos = '\0';			/* null terminate string */
X	strcpy(sys, path);			/* copy only system name */
X	strcpy(path, bangpos + 1);		/* rest of path */
X
X	/* search valid uucp names for sys, if not found, abort */
X
X	if ((pfp = popen(UUNAME,"r")) == NULL) {
X		fprintf(stderr,"%s: cannot open read pipe channel to %s\n", 
X			progname, UUNAME);
X		perror("popen()");
X		exit(1);
X	}
X	while (fgets(looksys, SYSLEN, pfp) != NULL) {
X		pos = strchr(looksys,'\n');    /* terminate with null, not nl */
X		*pos = '\0';
X		if (strcmp(sys, looksys) == 0) {
X			pclose(pfp);
X			return;
X		}
X	}
X	pclose(pfp);
X
X	printf("%s: system name \"%s\" is not a valid uucp neighbor\n",
X		progname, sys);
X	exit(1);
X}
X
Xint check_rmail(file)
Xchar *file;
X{
X	FILE	*fp;
X
X	if ((fp = fopen(file, "r")) == NULL) {
X		fprintf(stderr,"%s: cannot open %s for read\n", progname, file);
X		perror("fopen()");
X		exit(1);
X	}
X	while (fgets(buffer, BUFSIZ, fp) != NULL) {
X		/* 
X		 * Save the _R_eturn address of the person 
X		 * who queued this job (either locally or remotely)
X		 */
X		if (!newaddr && (strncmp(buffer, "R ", 2) == 0)) 
X			sscanf(buffer,"%*s %s", return_address);
X
X		/*
X		 * Check to make sure this is actually a rmail message
X		 */
X		if (strncmp(buffer, "C rmail", 7) == 0) {
X			fclose(fp);
X			return 1;
X		}
X	}
X	fclose(fp);
X	return 0;
X
X}
X
Xvoid copy_to(pipefp, file)
XFILE *pipefp;
Xchar *file;
X{
X	int	c, bytes;
X	FILE	*fp;
X
X	if ((fp = fopen(file, "r")) == NULL) {
X		fprintf(stderr,"%s: cannot open %s for read\n", progname, file);
X		perror("fopen()");
X		exit(1);
X	}
X	bytes = 0;
X	while ((c = fgetc(fp)) != EOF) {
X		bytes++;
X		putc(c, pipefp);
X	}
X	fclose(fp);
X
X	if (verbose) {
X		printf("%s: Re-mailing job (%d bytes) ...\n",
X			progname, bytes);
X		fflush(stdout);
X	}
X
X}
X
X
Xchar *find_path(dirname, file)
Xchar *dirname, *file;
X{
X	char	newdir[BUFSIZ],
X		*retdir;
X	DIR	*mdir;
X	struct dirent *dentry;
X	struct stat    statbuf;
X
X	if ((mdir=opendir(dirname)) != NULL) {
X		while ((dentry=readdir(mdir)) != NULL) {
X			sprintf(newdir, "%s/%s", dirname, dentry->d_name);
X			stat(newdir, &statbuf);
X			if (((statbuf.st_mode & S_IFMT) & S_IFDIR) && 
X			    (strcmp(dentry->d_name,".") != 0) &&
X			    (strcmp(dentry->d_name,"..") != 0)) {
X				if ((retdir = find_path(newdir,file)) != 
X					(char *)NULL) 
X					return(retdir);
X			} 
X			if (strcmp(dentry->d_name,file) == 0) 
X				return(dirname);
X		}
X	}
X	closedir(mdir);
X
X	return((char *)NULL);
X
X}
END_OF_FILE
if test 10303 -ne `wc -c <'uureroute/uureroute.c'`; then
    echo shar: \"'uureroute/uureroute.c'\" unpacked with wrong size!
fi
# end of 'uureroute/uureroute.c'
fi
if test -f 'uust/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uust/Makefile'\"
else
echo shar: Extracting \"'uust/Makefile'\" \(820 characters\)
sed "s/^X//" >'uust/Makefile' <<'END_OF_FILE'
X# Makefile for uust.  Does nothing but install.
X#
X# $RCSfile: Makefile,v $	$Revision: 1.1 $
X#
X# $Author: scs $	$Date: 90/11/11 23:36:34 $
X#
X# $State: Exp $	$Locker:  $
X#
X# $Log:	Makefile,v $
X# Revision 1.1  90/11/11  23:36:34  scs
X# Initial revision
X# 
X
X# Fill in with what is being made
XTARGET	= uust
X
X# Default places and ownerships
XMANSEC	= 8
XMAN	= /usr/man/man$(MANSEC)
XBIN	= /usr/local/bin
XLIB	= /usr/local/lib
XOWNER	= bin
XGROUP	= bin
X
Xall:	
X	@echo "uust does not make.  Do 'make install' if you're ready."
X
X$(TARGET).man:	$(TARGET).$(MANSEC)
X	nroff -man $(TARGET).$(MANSEC) > $(TARGET).man
X
Xinstall:	install_uust install_man
X
Xinstall_man:	$(TARGET).$(MANSEC)
X	install -m 444 -o $(OWNER) -g $(GROUP) -c $(TARGET).$(MANSEC) $(MAN)
X
Xinstall_uust:	$(TARGET)
X	install -m 555 -o $(OWNER) -g $(GROUP) -c $(TARGET) $(BIN)
END_OF_FILE
if test 820 -ne `wc -c <'uust/Makefile'`; then
    echo shar: \"'uust/Makefile'\" unpacked with wrong size!
fi
# end of 'uust/Makefile'
fi
if test -f 'uust/uust' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uust/uust'\"
else
echo shar: Extracting \"'uust/uust'\" \(1708 characters\)
sed "s/^X//" >'uust/uust' <<'END_OF_FILE'
X: /bin/sh
X#
X# Script to print to current connection status of
X# uucp contacts.  For HDB uucp, assumes you have cnews
X# binaries installed somewhere.
X#
X# $RCSfile: uust,v $	$Revision: 1.2 $
X#
X# $Author: scs $	$Date: 90/11/11 23:31:24 $
X#
X# $State: Exp $	$Locker:  $
X#
X# $Log:	uust,v $
X# Revision 1.2  90/11/11  23:31:24  scs
X# Added -s switch and -h switch.  Added more error checking.
X# 
X# Revision 1.1  90/07/29  10:50:04  scs
X# Initial revision
X# 
XSCRIPT=`basename $0`
Xif [ ! -d /usr/spool/uucp/.Status ] ; then
X	echo "${SCRIPT}: Can't find the status directory!  Do you really have HDB?"
X	exit
Xfi
Xcd /usr/spool/uucp/.Status
X#
X# Parse the options.  Anything besides '-s' is bogus
X#
XUSAGE="${SCRIPT} usage: ${SCRIPT} [ -h ] [ -s system [ -s system . . . ] ]"
Xif [ $# = 0 ] ; then
X	ARGLIST=*
Xelse
X	while [ "" != "$*" ]
X	do
X		case $1 in
X		  -s)	if [ "$2" != "" ] ; then
X				ARGLIST="$ARGLIST $2"
X				shift ; shift
X			else
X				echo "${SCRIPT}: You must specify a system with -s.  Aborting."
X				exit 1
X			fi
X			;;
X		  -h)	echo "$USAGE"
X			exit 0
X			;;
X		  *)	echo "${SCRIPT}: No such switch as $1.  Aborting."
X			echo "$USAGE"
X			exit 1
X			;;
X		esac
X	done
Xfi
X#
X# Anything to report?
X#
Xif [ "$ARGLIST" = "" ] ; then
X	echo "$SCRIPT: No systems with reportable status."
Xfi
X#
X# OK, do it.
X#
Xecho "System		  Last Attempt		 Next	   System Status"
Xecho "=======	    ========================  	======	===================="
Xfor FILE in $ARGLIST
Xdo
X	if [ ! -r $FILE ] ; then
X		LAST="No available data"
X		NEXT=""
X		STATUS=""
X	else
X		exec < $FILE
X		read DUMMY1 DUMMY2 LAST NEXT STATUS
X		LAST=`/usr/lib/newsbin/ctime $LAST`
X		if [ "$NEXT" = "0" ] ; then
X			NEXT="Sched."
X		fi
X	fi
X	echo "$FILE	    $LAST	$NEXT	$STATUS"
Xdone
END_OF_FILE
if test 1708 -ne `wc -c <'uust/uust'`; then
    echo shar: \"'uust/uust'\" unpacked with wrong size!
fi
chmod +x 'uust/uust'
# end of 'uust/uust'
fi
if test -f 'uust/uust.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uust/uust.8'\"
else
echo shar: Extracting \"'uust/uust.8'\" \(1368 characters\)
sed "s/^X//" >'uust/uust.8' <<'END_OF_FILE'
X.\" Sysadm (8) Manual page for uust
X.\"
X.\" $RCSfile: uust.8,v $	$Revision: 1.1 $
X.\"
X.\" $Author: scs $	$Date: 90/11/11 23:34:10 $
X.\"
X.\" $State: Exp $	$Locker:  $
X.\"
X.\" $Log:	uust.8,v $
XRevision 1.1  90/11/11  23:34:10  scs
XInitial revision
X
X.TH uust 8 "November 11, 1990" "Local"
X.SH NAME
Xuust \- report on uucp connectivity status (hdb only)
X.SH SYNOPSIS
Xuust [ -h ] [ -s system [ -s system ] . . . ]
X.SH DESCRIPTION
X.B uust
Xwill print out the current status of the local uucp connections
Xas recorded in the
X.B .Status
Xdirectory of the uucp spool area.
XIt takes the somewhat obscure data in the status files
Xand prints it in a more readable fashion.
X.PP
XYou may specify systems by listing them with the 
X.I -s
Xswitch.
XIf you do not specify any systems, status of all systems
Xwill be printed.
X.PP
XIf you use the 
X.I -h
Xswitch, a
X.B uust
Xusage message will be printed.
XNo systems will be described.
X.PP
XFor
X.B uust
Xto work, you must have the CNews utility
X.B ctime
Xutility installed on your system.
X.SH FILES
X/var/spool/uucp/.Status
X.SH CAVEAT
XThis utility is intended only for HDB uucp.
X.SH BUGS
XPlease report any bugs to the author.
X.SH AUTHOR
XSteve Simmons, scs@lokkur.dexter.mi.us
X.SH "COPYRIGHT STATUS"
XCopyright 1990, Steven C. Simmons.
XAll rights reserved.
XFreely redistributable provided this notice remains intact.
X.SH "SEE ALSO"
Xuupend(8), uureroute(8)
END_OF_FILE
if test 1368 -ne `wc -c <'uust/uust.8'`; then
    echo shar: \"'uust/uust.8'\" unpacked with wrong size!
fi
# end of 'uust/uust.8'
fi
echo shar: End of shell archive.
exit 0
-- 
" . . . within a nanometer (about a billionth of a yard) . . . "
  Reader's Digest, November 1990, pp. 31