[comp.sources.misc] v09i101: UX-Maze Mail Based File Server

acliu%skat.usc.edu@usc.edu (Alex C. Liu) (01/06/90)

Posting-number: Volume 9, Issue 101
Submitted-by: acliu%skat.usc.edu@usc.edu (Alex C. Liu)
Archive-name: ux-maze

/* I Send This to Comp.sources.unix, a month Ago, and haven't seen
   anything yet, so I am posting it to Comp.sources.misc 	   */

The UX-Maze Server is a program that allows the average Joe has his
very OWN mail file server. You only need a C compiler and decent
implementations of Unix and Sendmail.  Not only that, but the program
is smart enough to detect what kind of program you are trying to send.
And uncompress it (if needed), uuencode it (or btoa encode it, if that
is what the user wants, or use a very portable Hex format), and if the
file is bigger than an user defined limit, it will "split" the file
first!

NOTE:
  READ ALL the sources, and be VERY sure what you are doing before
installing this software!

This distribution for the server contains the sources for:
 m-ser         Main C file server program
 M_SER.sh      Shell script driver for m-ser. (Called by sendmail's
               forward)
 auto-stat     C program that prints out Systems statistics.
 auto-stat.sh  AT script that will do System statistics periodically.
 viewstat.sh   Shell script driver for auto-stat to display
               statistics.

Also, in the file doc.shar I have the documentation files I use in my
"help" directory.

Read the README file for instructions on how to set up the whole
thing...

The following package is Copyrighted 1989 by Alejandro Liu.  All
rights reserved.  You are given permission to freely copy and
distribute unmodified versions of this program.

----cut here----cut here----cut here----cut here----cut here----cut here----
#! /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 Makefile MK_WORLD.proto M_SER.proto auto-stat.proto
#   viewstat.proto bencode.h cmds.h m_buf_type.h m_buffer.h mazesym.h
#   server_strs.h auto-stat.c bencode.c m-ser.c m_buffer.c msgs.c
#   parse.c sendfile.c strcase.c TODO
# Wrapped by acliu@skat.usc.edu on Fri Jan  5 15:45:02 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(4099 characters\)
sed "s/^X//" >README <<'END_OF_README'
X
XThe following package is Copyrighted 1989 by Alejandro Liu.  All
Xrights reserved.  You are given permission to freely copy and
Xdistribute unmodified versions of this program.
X
X			 UX-Maze Mail Server
X			 ===================
X
XThe UX-Maze Mail Server is a program that allows the average Joe has
Xhis very OWN mail file server. You  only need a C compiler and decent
Ximplementations of Unix and Sendmail.
X
XNOTE:
X  READ ALL the sources, and be VERY sure what you are doing before
Xinstalling this software!
X
XThis distribution for the server contains the sources for:
X m-ser         Main C file server program
X M_SER.sh      Shell script driver for m-ser. (Called by sendmail's
X               forward)
X auto-stat     C program that prints out Systems statistics.
X auto-stat.sh  AT script that will do System statistics periodically.
X viewstat.sh   Shell script driver for auto-stat to display
X               statistics.
X
XAlso, in the file doc.shar I have the documentation files I use in my
X"help" directory.
X
XHow to get the server working
X=============================
X
XThe server basicly runs as a hook to sendmail called by the .forward
Xfile.  To install it first:
X o Go Through M_SER.proto and modify what ever is necessary.
X   (For example, the Sed'd message that you receive in case of a fatal
X    error. (Lines beginning with X))
X     Any other mail processing commands that you want to add go at the
X     second stage
X o Look at the server_strs.h and modify any strings you want.  (The
X   comments should be pretty straight foward)
X o Look in msgs.c and modify the mail messages as you see appropiate.
X o Change whatever is appropiate from the auto-stat.proto if you plan
X   to use it.
X o Look at MK_WORLD.proto and change whatever you thing is necessary.
X o Look at the other files and fix any bugs you see (Bugs in my
X   program?  Nah!  Just undocumented features!)
X o Go and modify the Makefile.  (VERY important)
X o Type "make world"  This will compile the whole thing, and create
X   the volumes that you want as well as any necessary data files...
X o If you are using the auto-stat.sh script, do:
X	at -sm midnight auto-stat.sh
X o Add a line to your ".forward" file that has the following:
X	"|/user/john_doe/bin/M_SER.sh"
X   Make world will do this for you...
XIf everything went OK, (and if I didn't forget anything you may have a
Xworking mail server)  You can send mail and try it out.
XSee the files in "doc.shar" for instructions on how to use the server.
X
XNotes:
XSome systems don't have a "Return-Path" line, for such situations you
Xcan modify the cmds.h and parse.c files so you will use a different
Xstring or add an alternte string for Mail return path generation.
X
XWith some effort the program will be able to run in batch mode.
X
XIf you have any questions/troubles, send mail to acliu@skat.usc.edu.
X
XDiscussions of special files in the ARCHIVE directory structure
X===============================================================
XThe Server considers the following files/directories special.  (Note,
Xyou may be able to change this by modifying the program)
X
Xhelp (directory)
XThis is the default Directory used by the SEND command.  Also, it is
Xhere where all the files send out by the HELP command are saved.
X
Xhelp/intro
XThis is the default HELP file.  Whenever a person uses the HELP
Xcommand with no arguments, this file will be send.
X
Xcontents
XThis file is sent whenever a person sends a command with no
Xargumments.  Usually, it lists all the available volumes/directories
Xin the server.
X
X(directory)/contents
XThis is the default file sent by the SEND command when the user
Xdoesn't specify any filename.  Also, is the file sent by the
X"contents" command.  It usually lists all the available files in the
Xcurrent volume.
X
XAny other file/directory is considered a normal, archived file or
Xvolume.
X
XNOTE, that the file can be in any format, i.e. binary, compressed or
Xbe very large, the server will automatically detect the file type,
Xuncompress the file, and if it is binary will encode the program with
Xa user selected encoding method.  It will also split the file if it is
Xnecessary.
X
X
END_OF_README
if test 4099 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(3472 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# Simple Make file for m-arc
X#
X# You MUST change the following:
X# Home directory of the user that owns the server
XHOME = /usr/johndoe
X# Where the executables for the software live...
XBIN = $(HOME)/Archive.bin
X# Command search path to whatever is appropiate in your system...
XPATH = :/usr/ucb:/bin:/usr/bin:$(BIN)
X# Full path to the file that is the m-ser execuable
XMSER = $(BIN)/m-ser
X# Where do you want your mail saved...
XSYSBOX = /usr/spool/mail/johndoe
X# Top Directory for you Archive
XARCHIVE = $(HOME)/Archive
X# Directory where you want to create some of the tmp files
XTMPDIR = /usr/tmp
X# Name of the Volumes that you will have in your server.
X#   You must at least have the help volume, that is where the server
X# finds all its documentation.
XVOLUMES = help empty volume
X# How often you plan to run the auto-stat.sh script (If you plan to
X# use it)
XFREQ = 30 days
X# Mail address to mail the summaries.  (If you are using auto-stat.sh)
XSYSLOG = tom@sad.stories.com
X# Name of the Data sink
XDEVNULL = /dev/null
X#####################################################################
XCC = cc
XCFLAGS = -O -c
XLFLAGS = -O -s
XPROTOS = MK_WORLD.proto M_SER.proto auto-stat.proto viewstat.proto
XSHELLS = MK_WORLD.sh M_SER.sh auto-stat.sh viewstat.sh
XOBJS = bencode.o m_buffer.o sendfile.o m-ser.o parse.o strcase.o \
X	msgs.o
XSRCS = bencode.c m_buffer.c sendfile.c m-ser.c parse.c strcase.c \
X	msgs.c auto-stat.c
XHDRS = bencode.h m_buf_type.h m_buffer.h server_strs.h mazesym.h cmds.h
XPRINTER = p-sal125
XBINS = m-ser auto-stat
X
Xm-ser: $(OBJS)
X	$(CC) $(LFLAGS) $(OBJS) -o m-ser
X
Xall: m-ser maintain M_SER.sh
X
Xworld: install everything 
X
Xeverything: MK_WORLD.sh
X	MK_WORLD.sh
X
Xinstall: all 
X	cp  m-ser M_SER.sh auto-stat.sh auto-stat viewstat.sh $(BIN)
X	chmod 755 $(BIN)/M_SER.sh $(BIN)/auto-stat.sh $(BIN)/viewstat.sh
X
XM_SER.sh: M_SER.proto
X	sed -e "s!_PATH_!$(PATH)!" \
X	    -e "s!_MSER_!$(MSER)!" \
X	    -e "s!_ARCHIVE_!$(ARCHIVE)!" \
X	    -e "s!_MBOX_!$(SYSBOX)!" \
X	    -e "s!_TMPDIR_!$(TMPDIR)!" < M_SER.proto > M_SER.sh
X
XMK_WORLD.sh: MK_WORLD.proto
X	sed -e "s!_ARCDIR_!$(ARCHIVE)!" \
X	    -e "s!_VOLUMES_!$(VOLUMES)!" \
X	    -e "s!_BIN_!$(BIN)!" \
X	    -e "s!_DEVNULL_!$(DEVNULL)!" \
X	    -e "s!_HOME_!$(HOME)!" \
X	    < MK_WORLD.proto > MK_WORLD.sh
X	chmod 755 MK_WORLD.sh
X
Xbencode.o: bencode.c bencode.h mazesym.h
X	$(CC) $(CFLAGS) bencode.c
X
Xm_buffer.o: m_buffer.c m_buf_type.h
X	$(CC) $(CFLAGS) m_buffer.c
X
Xsendfile.o: mazesym.h server_strs.h sendfile.c
X	$(CC) $(CFLAGS) sendfile.c
X
Xm-ser.o: m-ser.c m_buffer.h mazesym.h server_strs.h
X	$(CC) $(CFLAGS) m-ser.c
X
Xparse.o: parse.c m_buffer.h mazesym.h bencode.h cmds.h server_strs.h
X	$(CC) $(CFLAGS) parse.c
X
Xstrcase.o: strcase.c
X	$(CC) $(CFLAGS) strcase.c
X
Xmsgs.o: msgs.c server_strs.h mazesym.h
X	$(CC) $(CFLAGS) msgs.c
X
Xmaintain: auto-stat auto-stat.sh viewstat.sh
X
Xauto-stat: auto-stat.c mazesym.h
X	$(CC) $(LFLAGS) -o auto-stat auto-stat.c
X
Xviewstat.sh: viewstat.proto
X	sed -e "s!BIN!$(BIN)!" \
X	    -e "s!DEVNULL!$(DEVNULL)!" \
X	    -e "s!DIR!$(ARCHIVE)!" \
X	    < viewstat.proto > viewstat.sh
X
Xauto-stat.sh: auto-stat.proto
X	sed -e "s!_TMPDIR_!$(TMPDIR)!" \
X	    -e "s!_ARCDIR_!$(ARCHIVE)!" \
X	    -e "s!_BIN_!$(BIN)!" \
X	    -e "s!_SYSLOG_!$(SYSLOG)!" \
X	    -e "s!_INTERVAL_!$(FREQ)!" \
X	       < auto-stat.proto > auto-stat.sh
X
Xlove:
X	@echo not war?
X
Xwar:
X	@echo Yeah! Fight on!
X
Xlint:
X	lint $(SRCS)
X
Xprint: 
X	pr -f -l64 $(PROTOS) $(SRCS) $(HDRS) | lpr -P$(PRINTER)
X
Xclean:
X	rm -f $(SHELLS) $(OBJS) $(BINS)
X	rm -f *~
END_OF_Makefile
if test 3472 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MK_WORLD.proto -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MK_WORLD.proto\"
else
echo shar: Extracting \"MK_WORLD.proto\" \(1613 characters\)
sed "s/^X//" >MK_WORLD.proto <<'END_OF_MK_WORLD.proto'
X#!/bin/sh
X# The following is modified by Makefile.
XSYSDIR=_ARCDIR_
XVOLUMES="_VOLUMES_"
XBIN=_BIN_
XTOP=_HOME_
XDEVNULL=_DEVNULL_
Xumask 022
X# You can change this if you don't like it...
X#
X# Creating the Archive directory
X#
Xif (test ! -d $SYSDIR) then
X    echo Creating the ARCHIVEs directory: $SYSDIR
X    if (mkdir $SYSDIR) then
X       echo Done.
X    else
X       echo Error! Aborting!
X       exit 1
X    fi
Xfi
Xecho Entering Archive directory
Xcd $SYSDIR
Xecho Creating Archive volumes...
Xfor VOL in $VOLUMES
Xdo
X   if (test -d $VOL) then
X      echo $VOL already exits.  Skiping...
X   else
X      echo Creating $VOL directory
X      mkdir $VOL
X      echo Creating Contents File...
X      sed "s/^X//"  > $VOL/contents <<END_OF_CONTENTS
XX
XXThis Volume is currently empty
XX
XEND_OF_CONTENTS
X      if (test $VOL = help -a ! -f $VOL/intro) then
X         sed "s/^X//" > $VOL/intro <<END_OF_INTRO
XX
XX Sorry, no documentation is yet available
XX
XEND_OF_INTRO
X      fi
X    fi
Xdone
Xecho Creating Main Contents file
Xif (test ! -f contents) then
X     sed "s/^X//" > contents  <<END_OF_ROOT
XX
XX This archive contains the following volumes:
XX
XX _VOLUMES_
XX
XEND_OF_ROOT
Xfi
Xecho Creating new Log file
X$BIN/auto-stat $DEVNULL Logfile > $DEVNULL <<DUMMY_HEADER
X%SL STARTED LOG 0 Havent even started operations...
XDUMMY_HEADER
Xecho Done with making the world...
Xif (test -f $TOP/.forward) then
X   if (test `grep "$BIN/M_SER.sh" $TOP| wc -l` != 1) then
X       echo Modifying your ".foward" file
X       echo \"!$BIN/M_SER.sh\" >> $TOP/.forward
X   fi
Xelse
X   echo Creating a .forward file
X   echo \"!$BIN/M_SER.sh\" > $TOP/.forward
Xfi
Xecho DONE...
END_OF_MK_WORLD.proto
if test 1613 -ne `wc -c <MK_WORLD.proto`; then
    echo shar: \"MK_WORLD.proto\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f M_SER.proto -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"M_SER.proto\"
else
echo shar: Extracting \"M_SER.proto\" \(1384 characters\)
sed "s/^X//" >M_SER.proto <<'END_OF_M_SER.proto'
X#!/bin/sh
X#   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :
X#----------------------------------------------------------------------
X# This is the Shell script driver for the UX-Maze Server.  It is in charge
X# of saving the messages into a temporary file, and pass it to the server.
X# it also it is in charge of saving the message if necessary.  (Or pass it
X# to any other Mail processing program if necessary)  The reason why I chose
X# to do this in Shell instead of in the C program was because that I migh want
X# to add other things latter.  (Like an autobounce mail program)
X#
Xexport PATH; PATH=_PATH_
XMSER=_MSER_
XMSerPath=_ARCHIVE_
XSYSBOX=_MBOX_
XMsgTmp=_TMPDIR_/tmpmail.$$
Xumask 022
X#
X# Check if somebody is using our tmp filename, is somebody is, we just save
X# the mail (The benefit of the doubt?)
Xif (test -f $MsgTmp) then
X   sed -e "s/^X//" >> $SYSBOX <<END_NOTICE
XX
XXFrom UX-MaZe Mail Notification system
XXReturn-Path: No where
XXFrom: UX-Maze_server `date`
XXSubject: $MsgTmp file is busy
XX
XXUnparsed message follows....
XX
XEND_NOTICE
X   cat >> $SYSBOX
X   exit
Xfi
X#
X# Save message in MsgTmp for the momemnt
Xecho '' > $MsgTmp
Xcat >> $MsgTmp
X#
X# First Stage.  Pass message through UX-Maze server
Xif ($MSER $MSerPath < $MsgTmp) then
X# secnond stage.  Pass message throuh any program you want
X   cat $MsgTmp >> $SYSBOX
Xfi
X# Clean up our mess
Xrm $MsgTmp
END_OF_M_SER.proto
if test 1384 -ne `wc -c <M_SER.proto`; then
    echo shar: \"M_SER.proto\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f auto-stat.proto -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"auto-stat.proto\"
else
echo shar: Extracting \"auto-stat.proto\" \(939 characters\)
sed "s/^X//" >auto-stat.proto <<'END_OF_auto-stat.proto'
X#!/bin/sh
X# at script that sumarizes the Log file
X#
Xumask 022
Xcd _ARCDIR_
Xdate
Xtmpf00=_TMPDIR_/log.$$
Xtmpf01=_TMPDIR_/sum.$$
Xtmpf02=_TMPDIR_/rpt.$$
Xecho Starting Statistics report generator
Xecho ""
Xecho Uncompressing Old-Log file
Xif (test -f Old-Log.Z) then
X    zcat Old-Log > $tmpf01
Xelse
X    if (test -f Old-Log) then
X        cp Old-Log $tmpf01
X    else
X        touch $tmpf01
X    fi
Xfi
Xcp Logfile $tmpf00
Xif (_BIN_/auto-stat $tmpf01 Logfile < $tmpf00 > $tmpf02) then
X    echo Completed Without Errors, updating Files
X    mv $tmpf01 Old-Log
X    if (test -f Old-Log.Z) then
X        rm Old-Log.Z
X    fi
X    compress -v Old-Log
X    mail -s "Archiver LogFile" _SYSLOG_ < $tmpf00
X    mail -s "Archiver Summary" _SYSLOG_ < $tmpf02
X    rm $tmpf00 $tmpf02
Xelse
X    echo Error Detected.  Restoring files!
X    mv $tmpf00 Logfile
X    compress -v Old-Log
X    rm $tmpf01 $tmpf02
Xfi
Xecho Done at `date`
Xat -sm midnight + _INTERVAL_ _BIN_/auto-stat.sh
X
END_OF_auto-stat.proto
if test 939 -ne `wc -c <auto-stat.proto`; then
    echo shar: \"auto-stat.proto\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f viewstat.proto -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"viewstat.proto\"
else
echo shar: Extracting \"viewstat.proto\" \(100 characters\)
sed "s/^X//" >viewstat.proto <<'END_OF_viewstat.proto'
X#!/bin/sh
X#Display Statistics, but no File updating!
XBIN/auto-stat DEVNULL \
X DEVNULL < DIR/Logfile
END_OF_viewstat.proto
if test 100 -ne `wc -c <viewstat.proto`; then
    echo shar: \"viewstat.proto\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bencode.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bencode.h\"
else
echo shar: Extracting \"bencode.h\" \(429 characters\)
sed "s/^X//" >bencode.h <<'END_OF_bencode.h'
X/*
X * file: bencode.h
X *    Symbol definitions for the different Encoding methods available
X */
X
X/* Internal constants to indentify the encoding method */
X#define UUENCODE	0	/* Default Encoder */
X#define BTOA		1	/* Very Good (nice) encoder, prefered */
X#define HEX		2	/* Very dumb, but sure fire method */
X
X/* Strings that define the Encoder commands */
X#define N_UUENCODE	"uuencode"
X#define N_BTOA		"btoa"
X#define N_HEX		"hex"
X
END_OF_bencode.h
if test 429 -ne `wc -c <bencode.h`; then
    echo shar: \"bencode.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cmds.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cmds.h\"
else
echo shar: Extracting \"cmds.h\" \(751 characters\)
sed "s/^X//" >cmds.h <<'END_OF_cmds.h'
X/*
X * file: cmds.h
X *    List of commands
X */
X
X#define NCMDS		10		/* Number of Commands */
X
X#define BENCODE		1		/* Token definitions */
X#define MAXSIZE		2
X#define PATH		4
X#define END		3
X#define CONTENTS	17		/* If the number is > 15 then the */
X#define HELP		18		/* Command can't be used until a */
X#define SEND		19		/* Path is set */
X#define	RECEIVE		20
X#define INDEX		21
X
Xstatic char *cmdlist[] = {		/* Command strings */
X  "Return-Path:",		/* PATH Command */
X  "path",   "contents",  "help",    "send",  "receive",
X  "index",  "bencode",   "maxsize", "end",   NULL
X};
X
Xstatic int tokens[] = {			/* Token values */
X  PATH,				/* Return-Path */
X  PATH,	    CONTENTS,	 HELP,	    SEND,     RECEIVE,
X  INDEX,    BENCODE,     MAXSIZE,   END,      NULL
X};
END_OF_cmds.h
if test 751 -ne `wc -c <cmds.h`; then
    echo shar: \"cmds.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f m_buf_type.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"m_buf_type.h\"
else
echo shar: Extracting \"m_buf_type.h\" \(165 characters\)
sed "s/^X//" >m_buf_type.h <<'END_OF_m_buf_type.h'
X/*
X * File: m_buf_type.h
X *   Define Data types for m_buffer.c routines
X */
X
Xstruct MBline {
X  struct MBline *next;
X  char *line;
X};
X
Xtypedef struct MBline msgbuf;
X
END_OF_m_buf_type.h
if test 165 -ne `wc -c <m_buf_type.h`; then
    echo shar: \"m_buf_type.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f m_buffer.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"m_buffer.h\"
else
echo shar: Extracting \"m_buffer.h\" \(118 characters\)
sed "s/^X//" >m_buffer.h <<'END_OF_m_buffer.h'
X/*
X * File: m_buffer.h
X *   Include file for msg loader
X */
X
X#include "m_buf_type.h"
Xextern struct MBline *readmsg();
END_OF_m_buffer.h
if test 118 -ne `wc -c <m_buffer.h`; then
    echo shar: \"m_buffer.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mazesym.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mazesym.h\"
else
echo shar: Extracting \"mazesym.h\" \(173 characters\)
sed "s/^X//" >mazesym.h <<'END_OF_mazesym.h'
X/*
X * File: mazesym.h
X *   Defined Constants For Different things
X */
X
X#define YES	1
X#define NO	0
X#define L_TSTR  1024
X#define TSTR	128
X#define ERROR   -1
X#define NOERROR 0
END_OF_mazesym.h
if test 173 -ne `wc -c <mazesym.h`; then
    echo shar: \"mazesym.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f server_strs.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"server_strs.h\"
else
echo shar: Extracting \"server_strs.h\" \(1362 characters\)
sed "s/^X//" >server_strs.h <<'END_OF_server_strs.h'
X/*
X * file: sever_strs.h
X *  Customizing strings for server 
X *
X */
X
X/* Nice msg strings */
X#define SBJ_SENDACK	"Mail server request for"
X#define SBJ_SENDSACK	"Mail splitted file"
X#define SBJ_INDXACK	"Mail index request for"
X#define SBJ_RECVACK	"Mail acknoledges receive file"
X#define SBJ_RECNOT	"Mail file received file"
X#define SBJ_WRN		"Mail send request for directory"
X#define PREFIX		"Mail Error:"
X
X/* Magic Strings! */
X#define SUBJLEN		9
X#define SUBJECT		"Subject: %s"
X#define SUBJLINE	"Mail-Archive-Request"
X
X/* Moderator's mail addresses */
X#define MODERATOR	"Thomas-Jefferson@independance.hall.usa JohnDoe@wizards.dec.com"
X
X/* Standard Filenames */
X#define LOGFILE		"Logfile"
X#define INCOMING	"incoming"
X
X/* Default filenames */
X#define HELPD		"help"
X#define CONTENTSF	"contents"
X#define INTROF		"intro"
X#define VOLF		"none"
X#define FILEF		"none"
X#define DINDEX		"."
X#define DENCODE		UUENCODE
X#define DSIZE		0
X#define ROOTD		"."
X
X/* Command prototypes */
X#define MAILSENDF	"mail -s '%s %s' '%s' < '%s'"
X#define MAILSENDS	"mail -s '%s %s' '%s' < '%s'"
X#define MAILLS		"ls -l '%s' | mail -s '%s %s' '%s'"
X#define MAILTHX		"fmt < %s | mail -s '%s %s %s' '%s'"
X#define RECNOTE		"fmt < %s | mail -s '%s %s/%s' '%s'"
X#define ZCATCMD		"zcat '%s' > '%s'"
X#define MAILERR		"echo '%s %s' | mail -s '%s %s' '%s'"
X#define SENDWRN		"fmt < %s | mail -s '%s %s' '%s'"
END_OF_server_strs.h
if test 1362 -ne `wc -c <server_strs.h`; then
    echo shar: \"server_strs.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f auto-stat.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"auto-stat.c\"
else
echo shar: Extracting \"auto-stat.c\" \(11910 characters\)
sed "s/^X//" >auto-stat.c <<'END_OF_auto-stat.c'
X/***********                            *
X * File: auto-stat.c                    *
X * Creates Summary files from Logfiles  *
X *                             **********/
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/timeb.h>
X#include <time.h>
X#include <ctype.h>
X#include "mazesym.h"
X
Xtypedef struct treenode {               /* Structure for counting:  */
X  char *name;                           /*     Popular files */
X  unsigned short count;                 /*     Top users */
X  struct treenode *left, *right;        /*     Common Errors */
X} nodetree;
X
XFILE *out;                              /* File Pointer for Old-Log file */
Xchar inbuf[TSTR],                       /* Line Buffer for input and scanf */
X     userName[TSTR],                    /* Stores request's user name */
X     tfname[TSTR];                      /* Temp file name storage */
X
Xlong requestCount = 0,                  /* Number of request processed */
X     contentsCount = 0,                 /* Number of Count Requests */
X     indexCount = 0,                    /* Number of Index requests */
X     helpCount = 0,                     /* Number of Help Requests */
X     sendCount = 0,                     /* Number of Send Requests */
X     sendfCount = 0,                    /* Actual number of Files Sent */
X     receiveCount = 0,                  /* Number of Receive Requests */
X     totalRuntime = 0,                  /* Total Run time in seconds */
X     errorCount = 0,                    /* Number of Errors */
X     lineCount = 0,                     /* Number of lines and bytes read */
X     byteCount = 0;
X
Xnodetree *users = 0,                    /* Root node for user's tree */
X         *files = 0,                    /* Root node for file's tree */
X         *errors = 0;                   /* Root node for error tree */
X
X/*
X * Main Function for auto-stat
X *   Usage: cd systemdir ; auto-stat Old-Logfile < Logfile > report
X * Creates or updates Logfile.sum
X */
X
Xmain(argc, argv)
X     int argc;
X     char *argv[];
X{
X  nodetree *Psort(), *tree(), *tmp;     /* Tree Updating subroutine */
X  time_t beginDate, endDate,            /* Clock variables */
X         runtime;                       /* Current entry runtime */
X  unsigned short rank;                  /* For system updating */
X
X  if (out = fopen(argv[2], "w")) {	/* Create empty Log File */
X    endDate = time((time_t *)NULL);
X    fprintf(out, "%%SL STARTED LOG %ld %s", endDate, ctime(&endDate));
X    fclose(out);
X  }
X  else {
X    fprintf(stderr, "%s: Can't create Empty Log file\n", argv[0]);
X    exit(1);
X  }
X  if (out = fopen(argv[1], "a")) {      /* Open the summary file */
X    do
X      if (!reads(inbuf)) {              /* Find the beginning of Log file */
X        fprintf(stderr,"%s: Corrupted Log file?\n", argv[0]);
X        exit(1);
X      }
X    while (strncmp(inbuf,"%SL STARTED LOG ",12));
X    sscanf(inbuf,"%%SL STARTED LOG %ld",&beginDate);/* Get the Log strttime */
X    endDate = time((time_t *)NULL);
X    fprintf( out, "@BP %ld \n", beginDate);     /* Print Heading */
X    printf("\fUX-Maze Archive server Statistics report\n");
X    printf("========================================\n\n");
X    printf("Accounting Period from %s", ctime(&beginDate));
X    printf("                    to %s", ctime(&endDate));
X    printf("(Period Length: ");
X    {
X      long total;
X      unsigned short seconds, minutes, hours, days;
X      seconds = minutes = days = 0;
X      total = endDate - beginDate;
X      seconds = total % 60;             /* Calculate seconds */
X      minutes = (total / 60) % 60;      /* Minutes */
X      hours = (total / 3600) % 24;      /* Hours */
X      days = total / 86400;             /* Days */
X      if (days)                         /* And print them out! */
X        printf(" %d days,", days);
X      if (hours)
X        printf(" %d hours,", hours);
X      if (minutes)
X        printf(" %d minutes,", minutes);
X      if (seconds)
X        printf(" %d seconds.", seconds);
X      fprintf(out,"@PL %ld\n", total);
X    }
X    printf(")\n\n");
X 
X    /* Begin reading Entries */
X    while (reads(inbuf))                        /* Look for a Start entry indicator */
X      if (!strncmp(inbuf, ">MS M-Server started: ", 18)) {
X        strcpy(userName, "ghostRider v1.0"); /* Reset User Name */
X        requestCount++;                 /* Update Request count */
X        do
X          if (reads(inbuf))             /* Examine entries */
X            processLine();          
X          else                  /* If premature EOF, simulate EOR */
X            strcpy(inbuf, "<ME M-Server end.  Run time = 10 seconds");
X        while (strncmp(inbuf, "<ME M-Server end.",10));
X        fixuser(userName);              /* Make Username "beautiful" */
X        users = tree(users, userName);
X        sscanf(inbuf, "<ME M-Server end.  Run time = %d ", &runtime);
X        totalRuntime += runtime;
X      }
X
X    /* Sort users, files and errors by popularity */
X    users = Psort(users);
X    errors = Psort(errors);
X    files = Psort(files);
X
X    /* Print out the Results */
X    printf("Number of Bytes Processed: %ld ( %ld Lines)\n\n",
X           byteCount, lineCount);
X    fprintf(out, "@PD %ld %ld\n",byteCount, lineCount);
X    printf("Total Number of Requests:   %12ld\n", requestCount);
X    fprintf(out, "@NR %ld\n", requestCount);
X    printf("Number of Contents Commands:%12ld\n", contentsCount);
X    printf("Number of Index Commands:   %12ld\n", indexCount);
X    printf("Number of Help Commands:    %12ld\n", helpCount);
X    printf("Number of Send Commands:    %12ld\n", sendCount);
X    fprintf(out, "@CT %ld %ld %ld %ld\n",
X	    contentsCount, indexCount, helpCount, sendCount);
X    printf("Total Files Sent:           %12ld\n", sendfCount);
X    printf("Number of Files Received:   %12ld\n\n", receiveCount);
X    printf("Total Number of Errors:     %12ld\n\n", errorCount);
X    if (requestCount) 
X      printf("Total Runtime: %ld\t\tAverage Run time = %ld\n",
X	     totalRuntime, totalRuntime / requestCount);
X    else
X      printf("Total Runtime: %ld\t\tAverage Run time = NA\n",
X	     totalRuntime);
X    fprintf(out, "@ST %ld %ld %ld %ld\n",
X	    sendfCount, receiveCount, errorCount, totalRuntime);
X    printf("\f\n==============================================================\
X============\n");
X    printf("System's Top Users:\n");
X    printf("Rank NoRqs %%Rqs  MailAddress\n");
X    printf("==== ===== ====  ====================\n");
X    rank = 0;
X    tmp = users;
X    fprintf(out, "@BU\n");
X    while (tmp) {
X      if (requestCount)
X	printf("%4d %5d %4d  %s\n", ++rank, tmp->count,
X	       (100 * tmp->count + 50) / requestCount, tmp->name);
X      else
X	printf("No Requests!!!!!!\n");
X      fprintf(out, "@UR %d %s\n", tmp->count, tmp->name);
X      tmp = tmp->right;
X    }
X    printf("     =====\n");
X    printf("     %5d\n", requestCount);
X    printf("\f\n==============================================================\
X============\n");
X    printf("System's Most Popular Files\n");
X    printf("Rank NDLS %%DLS  File name\n");
X    printf("==== ==== ====  ======================\n");
X    rank = 0;
X    tmp = files;
X    fprintf(out, "@BF\n");
X    while (tmp) {
X      if (sendfCount) 
X	printf("%4d %4d %4d  %s\n", ++rank, tmp->count,
X	       (100 * tmp->count + 50) / sendfCount, tmp->name);
X      else
X	printf("No Downloads!!!!\n");
X      fprintf(out, "@PF %d %s\n", tmp->count, tmp->name);
X      tmp = tmp->right;
X    }
X    printf("     ====\n");
X    printf("     %4d\n", sendfCount);
X    printf("\f\n==============================================================\
X============\n");
X    printf("System's Most Common Errors\n");
X    printf("Rank NTMS %%TMS  Error Code       Rank NTMS %%TMS  Error Code\n");
X    printf("==== ==== ====  ===========      ==== ==== ====  ===========\n");
X    rank = 0;
X    tmp = errors;
X    fprintf(out, "@BE\n");
X    while (tmp) {
X      if (errorCount)
X	printf("%4d %4d %4d  %8s", ++rank, tmp->count,
X	       (100 * tmp->count + 50) / errorCount, tmp->name);
X      else
X	printf("* * * * None * * * *\n");
X      if (rank % 2)
X        printf("         ");
X      else
X        printf("\n");
X      fprintf(out, "@EL %d %s\n", tmp->count, tmp->name);
X      tmp = tmp->right;
X    }
X    if (rank % 2)
X      printf("\n");
X    fprintf(out, "@ER %ld\n", endDate);
X    fclose(out);
X    printf("\n==============================================================\
X============\n");
X    printf("Note: The percentages may not add up to 100 due to rounding \
Xerrors\n");
X  }
X  else {
X    fprintf(stderr, "%s: Can't open Output (%s) file!\n", argv[0], argv[1]);
X    exit(1);
X  }
X}
X
X
XprocessLine()
X{
X  nodetree *tree();                     /* Tree Updating subroutine */
X  if (inbuf[0] == '$') {                 /* Update Error Count */
X    errorCount++;
X    inbuf[3] = '\000';
X    errors = tree(errors, &inbuf[1]);
X  }
X  else if (!strncmp(inbuf, "&SR ", 4))
X    sendCount++;                /* Update the Send Request Count */
X  else if (!strncmp(inbuf, "&IR ", 4))
X    indexCount++;
X  else if (!strncmp(inbuf, "&CN ", 4)) {
X    contentsCount++;
X    do
X      if (reads(inbuf)) {
X        if (inbuf[0] == '$' || inbuf[0] == '&') 
X          processLine();
X      }
X      else
X        strcpy(inbuf, "<ME M-Server end.  Run time = 10 seconds");
X    while (inbuf[0] == '#');
X  }
X  else if (!strncmp(inbuf, "&RR ", 4)) 
X    receiveCount++;
X  else if (!strncmp(inbuf, "&HL ", 4))
X    helpCount++;
X  else if (!strncmp(inbuf, "#SF ", 4) || !strncmp(inbuf, "#PS ", 4)) {
X    sendfCount++;
X    if (inbuf[1] == 'S') 
X      sscanf(inbuf, "#SF Sending file %s", tfname);
X    else
X      sscanf(inbuf, "#PS Prepare Split Send of %s", tfname);
X    files = tree(files, tfname);
X  }
X  else if (!strncmp(inbuf, "&SP ", 4))
X    sscanf(inbuf, "&SP Path Set to %s", userName);
X}
X
Xnodetree *tree(p, w)
X     nodetree *p;
X     char *w;
X{
X  char *strsave(), *malloc();
X  int cond;
X
X  if (p == NULL) {
X    p = (nodetree *) malloc( sizeof(nodetree));
X    p->name = strsave(w);
X    p->count = 1;
X    p->left = p->right = NULL;
X  }
X  else if (!(cond=strcmp(w, p->name)))
X    p->count++;
X  else if (cond < 0)
X    p->left = tree(p->left, w);
X  else
X    p->right = tree(p->right, w);
X  return(p);
X}
X
Xchar *strsave(s)
X     char *s;
X{
X  char *p, *malloc();
X  p  = malloc(strlen(s) + 1);
X  strcpy(p,s);
X  return(p);
X}
X
X
Xnodetree *Psort(p)
X     nodetree *p;
X{
X  nodetree *walktree();
X  nodetree *root;
X  root = NULL;
X  root = walktree(p, root);
X  return(root);
X}
X
Xnodetree *walktree(p, root)
X     nodetree *p, *root;
X{
X  nodetree *walktree();
X  if (p != NULL) {
X    root = walktree(p->left, root);
X    if (root) {
X      nodetree *a, *b;
X      a = root;
X      for (;;)
X	if (p->count > a->count) {
X	  b = (nodetree *)malloc(sizeof(nodetree));
X	  b->right = a;
X	  if (!(b->left = a->left))
X	    root = b;
X	  b->name = strsave(p->name);
X	  b->count = p->count;
X	  a->left = b;
X	  if (a = b->left)
X	    a->right = b;
X	  break;
X	}
X	else
X	  if (a->right)
X	    a = a->right;
X	  else {
X	    b = (nodetree *) malloc(sizeof(nodetree));
X	    b->right = NULL;
X	    b->left = a;
X	    b->name = strsave(p->name);
X	    b->count = p->count;
X	    a->right = b;
X	    break;
X	  }
X    }
X    else {
X      root = (nodetree *)malloc(sizeof(nodetree));
X      root->left = root->right = NULL;
X      root->name = strsave(p->name);
X      root->count = p->count;
X    }
X    root = walktree(p->right, root);
X  }
X  return(root);
X}
X
Xfixuser(p)                      /* Beautify user name */
X     char *p;
X{
X  unsigned short i, j;
X  if (*p == '<') {              /* Strip the leading and trailing angle */
X    j = strlen(p);              /* angle brackets */
X    for (i = 1; i <= j; i++)
X      p[i-1]=p[i];
X  }
X  if (p[j = (strlen(p) - 1)] == '>')
X    p[j] = '\000';
X  j = strlen(p);
X  for (i = 0; i < j ; i++)      /* Make the User name lower case */
X    if (isupper(p[i]))
X      p[i] = tolower(p[i]);
X}
X
Xreads(s)
X     char *s;
X{
X  int x;
X  x = (int)gets(s);
X  lineCount++;
X  byteCount += strlen(s);
X  return(x);
X}
END_OF_auto-stat.c
if test 11910 -ne `wc -c <auto-stat.c`; then
    echo shar: \"auto-stat.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bencode.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bencode.c\"
else
echo shar: Extracting \"bencode.c\" \(5983 characters\)
sed "s/^X//" >bencode.c <<'END_OF_bencode.c'
X/********            				       *
X * Implements several Binary to Ascii encoding methods.*
X *	                                         *******/
X#include <strings.h>
X#include <stdio.h>
X#include "bencode.h"
X#include "mazesym.h"
X
X/*
X * int bencode(char *fnme, char bcode, char *nicnme)
X *  Encodes a file.
X *     fnme points to the filename.
X *     bcode contains the encoding method (see bencode.h)
X *     nicnme points to a name to save the file under
X *  returns NON-ZERO on error, ZERO for success
X *  fnme will contain the filename of the encoded file and the old file
X *  will be destroyed
X */
X
Xbencode(fnme, bcode, nicnme)
X     char *fnme,			/* Name of file to encode */
X          *nicnme,			/* Nice name used to save file under */
X           bcode;			/* Method for encoding */
X{
X  char tname[L_tmpnam];			/* Used to keep the input */
X  FILE *in, *out;			/* File Pointers */
X
X  strcpy(tname, fnme);			/* Make a copy of the input filename*/
X  tmpnam(fnme);				/* Create an output filename */
X
X  if (!(in = fopen(tname, "r")))	/* Do some common things */
X    return(ERROR);
X  if (!(out = fopen(fnme, "w"))) {
X    fclose(in);
X    return(ERROR);
X  }
X  switch(bcode) {
X    case UUENCODE:			/* Encoding method jump table */
X      uuencode(in, out, nicnme);
X      break;
X    case BTOA:
X      btoa(in, out);
X      break;
X    case HEX:
X      hexf(in,out, nicnme);
X      break;
X    }
X  fclose(out);				/* Clean up the mess */
X  fclose(in);
X  unlink(tname);
X  return(NOERROR);
X}
X
X/*
X * uuencode:  Encodes a file usinge uuencoding.  (From USENET distribution)
X */
X#define UUENC(c)	(((c) & 077) + ' ')
Xuuencode(in, out, name)
X     FILE *in, *out;
X     char *name;
X{
X  char buf[80];
X  int i,n;
X  fprintf(out, "begin 644 %s\n", name);
X  for (;;) {
X    n = UUfr(in, buf, 45);
X    uuputc(n, out);
X    for(i = 0; i<n; i += 3) 
X      UUoutdec(&buf[i], out);
X    putc('\n', out);
X    if (n<=0)
X      break;
X  }
X  fprintf(out, "end\n");
X}
XUUoutdec(p, f)
X     char *p;
X     FILE *f;
X{
X  int c1, c2, c3, c4;
X  c1 = *p >> 2;
X  c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
X  c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 003;
X  c4 = p[2] & 077;
X  uuputc(c1,f);
X  uuputc(c2,f);
X  uuputc(c3,f);
X  uuputc(c4,f);
X}
Xint
XUUfr(fd, buf, cnt)
X     FILE *fd;
X     char *buf;
X     int cnt;
X{
X  int c,i;
X  for (i=0; i<cnt; i++) {
X    c = getc(fd);
X    if (c == EOF)
X      return(i);
X    buf[i] = c;
X  }
X  return(cnt);
X}
Xuuputc(x, f)				/* Patches UUencoding to */
X     int x;				/* To replace spaces with */
X     FILE *f;				/* "`" */
X{
X  x = UUENC(x);
X  if (x == ' ')
X    putc('`', f);
X  else
X    putc(x,f);
X}
X
X/*
X * hexf(in, out, file)
X * Encodes a file in Hex format.  This method is dumb but super portable
X * FORMAT:
X *	hexf filename			     (Beginning of file)
X *      :08238C35128C357C0932
X *       ^^!-----up to----!^^
X *       ||    35 Bytes    || 
X *       ||    in Hex      ++-> (Checksum for this line (not including byte
X *       ||                      count)  It is just a MOD(256) addition of
X *       ||                      all bytes in the line)
X *       ||
X *       ++-> Byte Count.  Number of Bytes in the line (Not including checksum)
X *      end				     (Indicates EOF)
X * (Simple huh?)
X */
Xhexf(in, out, f)
X     FILE *in, *out;			/* I/O buffers */
X     char *f;				/* Filename */
X{
X  unsigned char buf[35];		/* Buffer for Current line */
X  int i, n, chks;
X
X  fprintf(out, "hexf %s\n", f);		/* Display Hex File header */
X  for (;;) {
X    n = UUfr(in, buf, 35);		/* Use UUencode UUfr (like read(2))*/
X    fprintf(out, ":%-02X", n);		/* Print Byte count */
X    chks = 0;
X    for (i=0;i<n;i++) {			/* Encode characters */
X      chks += buf[i];
X      fprintf(out, "%-02X", buf[i]);
X    }
X    fprintf(out, "%-02X\n", chks & 0xff); /* Print Checksum */
X    if (n <= 0)
X      break;
X  }
X  fprintf(out, "end\n");		/* Indicate EOF */
X}
X
X/*
X * btoa(in, out) Of all the encoding methods, this one is the best.
X * Not only makes it printable ascii, but it is also more efficient
X * than uuencode and also compresses things!
X *
X * Taken from btoa version 4.0 by Paul Rutter Joe Orost
X *
X * computes the number of bytes and three kinds of simple checksums
X * incomming bytes are connected into 32 bit words, then printed in
X * base 85 exp(85,5) > exp(2,32)
X * The ASCII characters used are between '!' and 'u'
X * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded
X * data
X *
X */
X#define MAXPERLINE	78
X#define EN(c)		(int)((c)+'!')
Xlong int Ceor, Csum, Crot, ccount, bcount, word;
Xbtoa(in, out)
X     FILE *in, *out;
X{
X  long int n;
X  int c;
X  Ceor = Csum = Crot = ccount = bcount = word = 0;
X  fprintf(out, "xbtoa Begin\n");
X  n  = 0;
X  while ((c = getc(in)) != EOF) {
X    encode(c, out);
X    n += 1;
X  }
X  while (bcount != 0)
X    encode(0, out);
X  if (ccount != 0)
X    putc('\n', out);
X  fprintf(out, "xbtoa End N %ld %lx E %lx S %lx R %lx\n",
X	  n, n, Ceor, Csum, Crot);
X}
Xencode(c, out)
X     int c;
X     FILE *out;
X{
X  Ceor ^= c;
X  Csum += c;
X  Csum += 1;
X  if (Crot & 0x80000000) {
X    Crot <<= 1;
X    Crot += 1;
X  }
X  else
X    Crot <<=1;
X  Crot += c;
X  word <<= 8;
X  word |= c;
X  if (bcount == 3) {
X    wordout(word, out);
X    bcount = 0;
X  }
X  else
X    bcount += 1;
X}
Xwordout(word, out)
X     long int word;
X     FILE *out;
X{
X  if (word) {
X    int tmp = 0;
X    if (word < 0) {		/* Because some don't support unsinged long */
X      tmp = 32;
X      word = word - (long)(85L * 85 * 85 * 85 * 32);
X    }
X    if (word < 0) {
X      tmp = 64;
X      word =  word - (long)(85L * 85 * 85 * 85 * 32);
X    }
X    charout(EN((word / (long)(85L * 85 * 85 * 85)) + tmp),out);
X    word %= (long)(85L * 85 * 85 * 85);
X    charout(EN(word / (85L * 85 * 85)),out);
X    word %= (85L * 85 * 85);
X    charout(EN(word / (85L * 85)),out);
X    word %= (85L * 85);
X    charout(EN(word / (85L)),out);
X    word %= 85;
X    charout(EN(word),out);
X  }
X  else
X    charout('z',out);
X}
X
Xcharout(c,out)
X     int c;
X     FILE *out;
X{
X  putc(c, out);
X  ccount += 1;
X  if (ccount == MAXPERLINE) {
X    putc('\n',out);
X    ccount = 0;
X  }
X}
X
END_OF_bencode.c
if test 5983 -ne `wc -c <bencode.c`; then
    echo shar: \"bencode.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f m-ser.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"m-ser.c\"
else
echo shar: Extracting \"m-ser.c\" \(2386 characters\)
sed "s/^X//" >m-ser.c <<'END_OF_m-ser.c'
X/*************
X * file: m-ser.c
X *
X *   m-ser implements a very simple mail archive.
X     You send message to the server, through .forward mechanism.  The
X     message gets read through stdin.  And the program parses it.
X     First it checks  for a Line that starts with:
X        Subject: Mail-Archive-Request
X     (Note that this can be redefined)
X     if it is not found, the server exits with a Zero status (meaning that
X     it did nothing)
X
X     After the server has identified that this is a Archive request, it
X     reads input for the following strings:
X     	Return-Path <PATH>
X	path <PATH>
X	   Sets the current return path to <PATH>
X	help [file]
X	   Sends a help file.  If no help file is specified the default
X	   is "intro"
X	send volume file
X	   Sends a file in the volume directory.  the defaults are help
X	   and contents respectively
X        contents volume
X	   Sends a file named contents in the volume directory (Default
X	   'help')
X	index volume
X	   Sends the "ls -l" output from the volume directory (Default .)
X	receive volume file
X	   Stops parsing the message and saves the entire thing somewhere. *
X									   *
X     This file contains the main function for the server		   *
X								 ***********/
X#include "m_buffer.h"
X#include "mazesym.h"
X#include <stdio.h>
X#include "server_strs.h"
X
Xchar *workdir;
X
Xmain(argc, argv)
X     int argc;
X     char *argv[];
X{
X  msgbuf *root, *tmp;			/* Message buffer pointers */
X  char isreq = NO,			/* Flag: Is this a request? */
X       dline[TSTR];			/* Temp string for parsing */
X
X  workdir = argv[1];			/* Change to the Server Directory */
X  enterdir();
X
X  tmp = root = readmsg(stdin);		/* Read the msg being piped to us */
X  while (tmp && !isreq) {		/* Check for Magic String */
X    if (!strncmp(tmp->line, SUBJECT, SUBJLEN)) {
X      sscanf(tmp->line, SUBJECT, dline);/* Grab subject line string */
X      if (!strcasecmp(dline, SUBJLINE))
X	isreq = YES;
X    }
X    tmp = tmp->next;
X  }
X  if (isreq) {
X    parse(root);			/* Parse message */
X    exit(1);				/* Tell shell what we did */
X  }
X  else {
X    exit(0);				/* Tell shell we did nothing! */
X  }
X	/* Here we should deallocate data */
X}
X
X/*
X * This routine enters the Server directory.  On error it will immediatly
X * Exit with (0) no matter what.
X * (NO parameters are tranferred)
X */
Xenterdir()
X{
X  if (chdir(workdir)) /* CHDIR, if error, we exit with '0' */
X    exit(0);
X}
END_OF_m-ser.c
if test 2386 -ne `wc -c <m-ser.c`; then
    echo shar: \"m-ser.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f m_buffer.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"m_buffer.c\"
else
echo shar: Extracting \"m_buffer.c\" \(928 characters\)
sed "s/^X//" >m_buffer.c <<'END_OF_m_buffer.c'
X/*
X * File: m_buffer.c
X *
X * Implements a simple buffer for a mail message.
X *
X */
X
X#include "m_buf_type.h"
X#include <stdio.h>
X#define TSTR	1024
X
Xstruct MBline *readmsg(fp)
X     FILE *fp;
X{
X  unsigned char iobuffer[TSTR];
X  int datain, ptr = 0;
X  struct MBline *temp, *root;
X  
X  root = temp = (struct MBline *)malloc(sizeof(struct MBline));
X  for (;;) {
X    datain = getc(fp);
X    if (datain == EOF || datain == '\n' || ptr == TSTR) {
X      iobuffer[ptr++] = '\000';
X      temp->line = (unsigned char *)malloc(ptr);
X      strcpy(temp->line, iobuffer);
X      if (datain == EOF) {
X	temp->next = NULL;
X	return(root);
X      }
X      temp = temp->next = (struct MBline *)malloc(sizeof(struct MBline));
X      ptr = 0;
X    }
X    else
X      iobuffer[ptr++] = datain;
X  }
X}
X
Xwritemsg( start, fp)
X     struct MBline *start;
X     FILE *fp;
X{
X  while (start) {
X    fputs(start->line, fp);
X    putc('\n', fp);
X    start = start->next;
X  }
X}
END_OF_m_buffer.c
if test 928 -ne `wc -c <m_buffer.c`; then
    echo shar: \"m_buffer.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f msgs.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"msgs.c\"
else
echo shar: Extracting \"msgs.c\" \(4265 characters\)
sed "s/^X//" >msgs.c <<'END_OF_msgs.c'
X/************
X * file: msgs.c						*
X *    Prints verbose messages to users			*
X						*********/
X#include <stdio.h>
X#include "mazesym.h"
X#include "server_strs.h"
X
Xchar tmpf[L_tmpnam],			/* Buffer for tmp filenames */
X     auxb[L_TSTR];			/* Buffer for sh commands */
XFILE *fp;				/* File Pointer for tmp file */
X
X/*
X * Message Sent whenever we are sending a directory
X */
Xwritewarn(dirn, mailpath, errP)
X     char *dirn,			/* Directory that will be sent out */
X          *mailpath;			/* Mail address of user */
X     FILE *errP;			/* File Pointer for error logging */
X{
X  tmpnam(tmpf);
X  if (!(fp = fopen(tmpf, "w"))) {
X    fprintf(errP,"$NM Can't create error mail! %s\n", tmpf);
X    return;
X  }
X  fprintf(fp, "Dear Human:\n\n");
X  fprintf(fp, "  The file %s, that you requested, turned out to be a", dirn);
X  fprintf(fp, " directory.  All ");
X  fprintf(fp, "files that were found in that directory will ");
X  fprintf(fp, "shortly arrive after this ");
X  fprintf(fp, "message.\n");
X  fprintf(fp, "  Even though the server supports the request of directories,");
X  fprintf(fp, " please try to limit such request in order to reduce Software");
X  fprintf(fp, " overhead.\n\n");
X  fprintf(fp, "	       			Sincerely, UX-Maze File Server\n\n");
X  fprintf(fp, "Thank your for using the UX-Maze File Server.\n\n");
X  fprintf(fp, "UX-Maze File Server,\n");
X  fprintf(fp, " Copyright 1989 by Alex C. Liu, All rights reserved.\n");
X  fclose(fp);
X  sprintf(auxb, SENDWRN, tmpf, SBJ_WRN, dirn, mailpath);
X  if (system(auxb))
X    fprintf(errP, "$NF Can't fork mail to send Warning: %s\n", dirn);
X  unlink(tmpf);
X}
X
X/*
X * writeRnt()
X * Prints the message send to the moderator(s) whenever there is a mail
X * Submission.
X */
X
XwriteRnt(fname, volume, file, mailpath, tod, errP)
X     char *fname,			/* Archive filename */
X          *volume,			/* Volume for file */
X	  *file,			/* Name for file */
X  	  *mailpath,			/* Mail Address of USER */
X	  *tod;				/* when the message was received */
X     FILE *errP;			/* Error loging pointer */
X{
X  tmpnam(tmpf);
X  if (!(fp = fopen(tmpf, "w"))) {
X    fprintf(errP,"$NM Can't create error mail! %s\n", tmpf);
X    return;
X  }
X  fprintf(fp, "Dear Moderator:\n");
X  fprintf(fp, "   The UX-Maze File Server received a file submission on\n");
X  fprintf(fp, "%s, from %s.  The file was\ncalled '%s' and was ",
X	  tod, mailpath, file);
X  fprintf(fp, "meant to be in '%s'.  Currently the file is stored ",
X	  volume);
X  fprintf(fp, "the '%s' directory and saved as '%s'.\n", INCOMING, fname);
X  fprintf(fp, "				Sincerely, UX-Maze File Server\n\n");
X  fprintf(fp, "UX-Maze File Server,\n");
X  fprintf(fp, " Copyright 1989 by Alex C. Liu, All rights reserved.\n");
X  fclose(fp);
X  sprintf(auxb, RECNOTE, tmpf, SBJ_RECNOT , volume, file, MODERATOR);
X  if (system(auxb))
X    fprintf(errP, "$NF Can't fork mail to send Moderator Note: %s\n", tmpf);
X  unlink(tmpf);
X}
X
X/*
X * writeAck()
X *  This funtions prints out the message that is send to the user whenever
X * he/she submits a file
X */
X
XwriteAck(file, volume, mailpath, errP)
X     char *file,			/* Name of submitted file */
X          *volume,			/* Name of dest volume */
X          *mailpath;			/* Where to send the mail to */
X     FILE *errP;			/* Error Log */
X{
X  tmpnam(tmpf);
X  if (!(fp = fopen(tmpf, "w"))) {
X    fprintf(errP,"$NM Can't create error mail! %s\n", tmpf);
X    return;
X  }
X  fprintf(fp, "Dear Contributor,\n\n");
X  fprintf(fp, "  The UX-Mail Archive Server would like to thank your for\n");
X  fprintf(fp, "your contribution of '%s' to the '%s' volume.  Right\n",
X	  file, volume);
X  fprintf(fp, "now the file has been saved in the '%s' volume and awaits\n",
X	  INCOMING);
X  fprintf(fp, "validation from the Moderator of the group.  If you have any ");
X  fprintf(fp, "questions, feel free to contact any of the addresses bellow.");
X  fprintf(fp, "\n\n			Sincerely, UX-Maze File Server\n\n");
X  fprintf(fp, "Moderators' e-mail addresses:\n");
X  fprintf(fp, "   %s\n\n", MODERATOR);
X  fprintf(fp, "UX-Maze File Server,\n");
X  fprintf(fp, " Copyright 1989 by Alex C. Liu, All rights reserved.\n");
X  fclose(fp);
X  sprintf(auxb, MAILTHX, tmpf, SBJ_RECVACK, volume, file, mailpath);
X  if (system(auxb))
X    fprintf(errP, "$NF Can't fork mail to send Rec Ack: %s\n", tmpf);
X  unlink(tmpf);
X}
END_OF_msgs.c
if test 4265 -ne `wc -c <msgs.c`; then
    echo shar: \"msgs.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f parse.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"parse.c\"
else
echo shar: Extracting \"parse.c\" \(9307 characters\)
sed "s/^X//" >parse.c <<'END_OF_parse.c'
X/***********
X * File: parse.c
X * Heart and soul of the mail server					    *
X   here is the Parsing function and the logging and msg reporting functions *
X								*************/
X/********* This actually ONE BIG Hack!!! **************/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/timeb.h>			/* Needed for time stamping */
X#include <time.h>
X#include <sys/stat.h>			/* Needed to ident Volumes in INDX */
X#include "bencode.h"
X#include "server_strs.h"
X#include "m_buffer.h"
X#include "mazesym.h"
X#include "cmds.h"
X
Xchar mailpath[TSTR],			/* Email Return Path */
X     bcode,				/* Current Encoding method */
X     pathen,				/* Flag to indicate if path is active*/
X     logf[L_tmpnam];			/* Logfile entry */
Xunsigned long maxsize;			/* Maximum message size */
XFILE *errP;				/* FP to Error log */
Xtime_t tod;				/* Current time of day */
Xmsgbuf *root;				/* Stores beginning of message */
X
X/*
X * parse(msgbuf *root)
X *   root points to the beginning of the message buffer.
X * This is almost the heart and soul of this program since it parses and
X * executes commands.
X *
X */
Xparse(msgl)
X     msgbuf *msgl;			/* Message Buffer pointer */
X{
X  char cmd[TSTR],			/* Read in command */
X       arg1[TSTR], arg2[TSTR];		/* Current command argumments */
X  unsigned i, mtc;
X
X  root = msgl;
X  bcode = UUENCODE;			/* Default Encoding method */
X  maxsize = 0;				/* Default message size = infinity */
X  pathen = NO;				/* No current path set yet... */
X
X  tmpnam(logf);				/* Prepare a temp file to log errors */
X  errP = fopen(logf, "w");		/* Open Log file */
X					/* Create a TimeStamp */
X  fprintf(errP, "____________________________\n");
X  tod = time((time_t *)0);		/* Get the time for timestamp */
X  fprintf(errP, ">MS M-Server started: (%ld) %s", tod, ctime(&tod));
X
X  while (msgl) {			/* Extract command & Argumments */
X    cmd[0] = arg1[0] = arg2[0] = NULL;	/* Initialize empty strings */
X    sscanf(msgl->line, "%s %s %s", cmd, arg1, arg2);
X    mtc = 0;				/* No command matched */
X    for (i = 0; i<NCMDS && !mtc; i++)
X      if (!strcasecmp(cmdlist[i], cmd)) /* Command recognized */
X	mtc = tokens[i];
X    if (mtc < 16 || pathen) {		/* Check if allowed command */
X      switch (mtc) {
X        case PATH:
X	  if (!strcmp("<MAILER-DAEMON>", arg1)) { /* Bounced Mail, do a */
X	    if (pathen)		        /* Quick Exit */
X	      fprintf(errP,
X		      "$BM Bounced Mail Detected (%s %s) from %s\n",
X		      cmd, arg1, mailpath);
X	    else
X	      fprintf(errP,
X		      "$BM Bounced Mail Detected (%s %s)\n",
X		      cmd, arg1);
X	    closelog();
X	    exit(0);
X	  }
X	  pathen = YES;			/* Enable Path name */
X	  strcpy(mailpath, arg1);	/* Set the Path */
X	  fprintf(errP,"&SP Path Set to %s\n", arg1);
X	  break;
X	case CONTENTS:
X	  fprintf(errP,"&CN Contents Request for %s\n", arg1);
X	  if (!arg1[0])			/* Default value */
X	    strcpy(arg1, ROOTD);
X	  SendF(arg1, CONTENTSF);	/* Send File arg1/contents */
X	  break;
X	case HELP:
X	  fprintf(errP, "&HL Help Request for %s\n", arg1);
X	  if (!arg1[0])
X	    strcpy(arg1, INTROF);	/*Default value */
X	  SendF("help", arg1);
X	  break;
X	case SEND:
X	  fprintf(errP, "&SR Send Request: %s %s\n", arg1, arg2);
X	  if (!arg1[0]) 		/* Fill Default values */
X	    strcpy(arg1, HELPD);
X	  if (!arg2[0])
X	    strcpy(arg2, CONTENTSF);
X	  SendF(arg1, arg2);
X	  break;
X	case RECEIVE:
X	  fprintf(errP, "&RR *** Receive Request: %s %s\n", arg1, arg2);
X	  if (!arg1[0])			/* Default Values */
X	    strcpy(arg1, VOLF);
X	  if (!arg2[0])
X	    strcpy(arg2, FILEF);
X	  ReceiveF(arg1, arg2, msgl->next);
X	  closelog();
X	  exit(1);			/* Stop Parsing NOW! */
X	case INDEX:
X	  fprintf(errP, "&IR Index Request %s\n", arg1);
X	  if (!arg1[0]) 		/* Default Value */
X	    strcpy(arg1, DINDEX);
X	  if (!chkpath(arg1)) 
X	    sendIndex(arg1);
X	  break;
X	case BENCODE:
X	  fprintf(errP, "&BE Set B-Encoding to %s\n", arg1);
X	  if (!arg1[0])			/* Default Encoder */
X	    bcode = DENCODE;
X	  else
X	    setbcode(arg1);
X	  break;
X	case MAXSIZE:
X	  fprintf(errP, "&MS Set Max Message Size to %s\n",arg1);
X	  if (!arg1[0])			/* Default size */
X	    maxsize = 0;
X	  else				/* Set size */
X	    maxsize = atoi(arg1);
X	  break;
X	case END:
X	  fprintf(errP, "&XX End Parsing\n");
X	  closelog();
X	  exit(1);
X	}
X    }
X    msgl = msgl->next;
X  }
X  closelog();
X}
X
X/*
X * Closes the Logfile and appends it to the "real" log file
X *
X */
Xcloselog()
X{
X  FILE *errP2;
X  int key;				/* Stamp Run time */
X  fprintf(errP, "<ME M-Server end.  Run time = %ld seconds\n",
X	  time((time_t *)0) - tod);
X  fclose(errP);
X  if (!(errP2 = fopen(logf, "r")))	/* Append Log entry */
X    exit(0);
X  if (!(errP = fopen(LOGFILE, "a")))
X    exit(0);
X  while ((key = getc(errP2)) != EOF)   
X    putc(key,errP);
X  fclose(errP);
X  fclose(errP2);
X  unlink(logf);				/* Clean up tmp log entry */
X}
X
X/*
X * SendF(char *volume, char *file)
X *    Wrapper for the send file function
X * (Prepares the way for sendfile)
X */
XSendF(volume, file)
X     char *volume,			/* Directory to send things from */
X          *file;			/* File to send */
X{
X  if (chkpath(volume))			/* Check for weird Volume name */
X    return;				/* File checking done by sendfile */
X  if (chdir(volume)) {			/* Can't access that volume? */
X    fprintf(errP, "$BV Bad Volume %s\n", volume);
X    sendMSG("Cant access volume %s", volume);
X    return;
X  }					/* Log and send file */
X  fprintf(errP, "#TS To Send %s %s\n", volume, file);
X  sendfile(file, mailpath, bcode, maxsize);
X  enterdir();				/* Return to the Home directory */
X}
X
X/*
X * sendIndex(char *volume) Sends the "ls -l" of the volume
X */
XsendIndex(volume)
X     char *volume;			/* Directory we are interested in */
X{
X  char auxb[L_TSTR];			/* SH command */
X  struct stat st_bff;			/* Stat, find if named volume exists */
X
X  if (chkpath(volume)) 			/* Check for strange File Paths */
X    return;
X  if (stat(volume, &st_bff) || !(st_bff.st_mode & S_IFDIR)) {
X					/* Check if directory exists */
X
X    fprintf(errP, "$BV Bad Volume %s\n", volume);
X    sendMSG("Cant access volume %s", volume);
X    return;
X  }
X  sprintf(auxb, MAILLS, volume, SBJ_INDXACK, volume, mailpath);
X  if (system(auxb))
X    fprintf(errP, "$VF Cannot mail ls-l (Can't Fork?)\n");
X}
X
X/*
X * ReceiveF(char *volume, char *file)
X * Receives a file through mail and stores it in the incomming directory
X */
XReceiveF(volume, file)
X     char *volume,			/* Receiving volume */
X          *file;			/* Receiving file */
X{
X  FILE *fp;				/* File Pointer for input file */
X  char fname[TSTR],			/* Receiving storage filename */
X       *p,				/* Used to parse the filename */
X       auxb[L_TSTR];			/* Command buffer */
X  if (chdir(INCOMING)) {		/* Oops with incoming directory */
X    fprintf(errP, "$CI Can't enter incoming directory!!!\n");
X    closelog();				/* Exit NOW! */
X    exit(0);
X  }
X  strcpy(fname, volume);		/* Create the storage filename */
X  strcat(fname, "/");		       
X  strcat(fname, file);
X  p = fname;
X  while (*p) {				/* Convert any "/"s to ":"s */
X    if (*p == '/')
X      *p  = ':';
X    p++;
X  }
X  if (isreadable(fname)) {		/* File of the same name exist */
X    char ftmp[TSTR];			/* Create a numbered version of it */
X    int	genno;
X    genno = 0;
X    do {
X      sprintf(ftmp, "%s.%-02d", fname, genno++);
X    } while (isreadable(ftmp));
X    strcpy(fname,ftmp);
X  }
X  if (!(fp = fopen(fname, "w"))) {
X    fprintf(errP, "$IF Can't open incoming file %s\n", fname);
X    closelog();
X    exit(0);
X  }
X  fprintf(errP, "#RF Receiving file %s %s in %s\n", volume, file, fname);
X  fprintf(fp, "Received from %s at %s", mailpath, ctime(&tod));
X  fprintf(fp, "Program name: %s/%s      Archive Name: %s\n",
X	  volume, file, fname);
X  fprintf(fp, 
X	  "--------Cute Here--------Cute Here---------Cute Here---------\n");
X  writemsg(root, fp);
X/*
X * This function will save the whole file.  The reason is I want to save
X * the whole file for debugging purposes
X */
X
X  fclose(fp);
X  writeAck(file, volume, mailpath, errP);
X  writeRnt(fname, volume, file, mailpath, ctime(&tod), errP);
X  enterdir();					/* Return to Main Directory */
X}
X
X  
X/*
X * n_bcode
X *   List of supported encoding packages
X */
Xstatic char *n_bcode[] = {
X  N_UUENCODE, N_BTOA, N_HEX, NULL
X};
X
X
X/*
X * setbcode(char *type)
X *   Change binary encoding system
X */
X
Xsetbcode(tp)
X     char *tp;
X{
X  char i;
X
X  for (i = 0; n_bcode[i] ; i++)
X    if (!strcasecmp(n_bcode[i], tp))
X      bcode = i;
X}
X
X/*
X * sendMSG(char *frmt, char *errcde)
X *   Sends A Mail message indicating what error was received.
X */
XsendMSG(frmt, errcde)
X     char *frmt,			/* Subject Format Template */
X          *errcde;			/* Error Code used */
X{
X  char auxb[L_TSTR],			/* Buffer for sh commnication */
X       subj[TSTR];			/* Buffer for building the subject) */
X  sprintf(subj, frmt, errcde);
X  sprintf(auxb, MAILERR, PREFIX, subj, PREFIX, subj, mailpath);
X  if (system(auxb)) 
X    fprintf(errP, "$VF Can't mail Error Report '%s' (Vfork failed?)\n", subj);
X}
X
X/*
X * errlog(char *fmt, char *errcde)
X *    Log errors to the log file
X */
Xerrlog(fmt, errcde)
X     char *fmt,				/* Template for generating text */
X          *errcde;			/* Text for error message */
X{
X  fprintf(errP, fmt, errcde);		/* Log Error Message */
X}
X
X/*
X *  sendWRN(char *dirn)
X *    Sends a message indicating that dirn is a directory and the files in
X *  there will be following soon
X */
XsendWRN(dirn)
X     char *dirn;
X{
X  writewarn(dirn, mailpath, errP);
X}
X
END_OF_parse.c
if test 9307 -ne `wc -c <parse.c`; then
    echo shar: \"parse.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sendfile.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sendfile.c\"
else
echo shar: Extracting \"sendfile.c\" \(13323 characters\)
sed "s/^X//" >sendfile.c <<'END_OF_sendfile.c'
X/*******
X * sendfile.c         			       *
X *   Implements an "smart" file mailer.        *
X 					********/
X#include <sys/types.h>			/* For SYSTEM calls */
X#include <sys/stat.h>
X#include <stdio.h>			/* Obvious huh? */
X#include <dirent.h>			/* Directory Functions */
X#include <ctype.h>			/* For Scanning files */
X#include "server_strs.h"		/* Strings to use */
X#include "mazesym.h"			/* Standard symbols */
X/*#include "bencode.h"*/
X
X/*
X * int sendfile(char *fname, char *rpath, char bcode, long size)
X *   Mails a file to an address.
X *  fname points to the full path of the filename (Or the path relative
X *	to the current directory)
X *  rpath points to the mail return path
X *  bcode number representing the preferred binary encoding mechanism
X *  size  is the maximum size in bytes of a single mail message (If size
X *  is zero, the maximum size is taken to be infinity)
X *   FIRST, the stat's for the file are checked, to see
X *	1) Read Permission
X *		If not allowed to read, we give out a message
X *	2) Filetype
X *		If it is a directory we go to a special routine to
X *		handle those cases
X *		If it is a symlink we read the link and try again.
X *   the file is scanned (and copied to /tmp) to see if it
X *   contains binary data.
X *   if the file contains binary data the "bcode" is checked to see what
X *   routine is to be used to encode the binary data.
X *   The file is again checked for size.  If the file exceeds the
X *   limit we use an alternate routine that splits and mail.
X *   We just mail the message.
X */
X
Xsendfile(fname, rpath, bcode, maxsiz)
X     char *fname,	/* Filename to send */
X          *rpath,	/* Where to send the mail to */
X	  bcode;	/* Binary encoding method  (Defined in "bencode.h")*/
X     unsigned long maxsiz; /* Max message size (0 = infinity) */
X{
X  struct stat st_bff;	/* stat buffer */
X  int i;		/* Multi purpose index */
X  FILE *fp, *fb;	/* Pointer to file for filescans and copies */
X  char tname[L_tmpnam], /* Buffer for Temp filename */
X       auxb[L_TSTR],	/* Buffer for Communicating with system shell */
X       isbin = NO;	/* Flag to indicate if it is a binary file */
X
X  if (chkpath(fname))			/* Check for Strange File Paths */
X    return;
X  if (stat(fname, &st_bff)) {		/* Get the file permissions */
X    strcat(fname, ".Z");		/* If couldnt find first time assume */
X    if (stat(fname, &st_bff)) {		/* Compressed filename */
X      errlog("$FN File Not Found %s\n", fname);
X      sendMSG("%s: File Not Found", fname);
X      return;
X    }
X  }
X
X  if (st_bff.st_mode & S_IFDIR) {	/* Check if it is a directory */
X    senddir(fname, rpath, bcode, maxsiz);
X    return;
X  }
X
X  if (!isreadable(fname)) {		/* Check if we have read access */
X    errlog("$NA Can't Access %s\n", fname);
X    sendMSG("Sorry, you dont have access to the file %s", fname);
X    return;
X  }
X
X  tmpnam(tname);			/* Create a temporary file name */
X  if (fname[(i = strlen(fname) -1)] == 'Z' && fname[i - 1] == '.') {
X					/* Check if it is a compressed file */
X    fname[i-1] = '\000'; 		/* Get Rid of .Z suffix */
X    sprintf(auxb, ZCATCMD, fname, tname);
X    if (system(auxb)) {			/* Uncompress file */
X      errlog("$VF Can't vfork %s process\n", "zcat");
X      sendMSG("Cant send file %s for lack of resources. (Try again later)",
X	      fname);
X      return;
X    }
X    if (!(fp = fopen(tname, "r"))) {	/* Non-copy scanfile */
X      errlog("$SE System Error %s\n", fname);
X      sendMSG("System Error Detected, for file: %s, try again later", fname);
X      return;
X    }
X    while ((i = getc(fp)) != EOF && !isbin)
X      if (!isprint(i) && i != '\n' && i != '\t' && i != '\f')
X	isbin = YES;
X    fclose(fp);
X  }
X  else {
X    if (!(fp = fopen(fname, "r"))) {	/* Scan file and copy it to temp */
X      errlog("$NA Can't Access %s\n", fname);
X      sendMSG("Sorry, you dont have access to the file %s", fname);
X      return;
X    }
X    if (!(fb = fopen(tname, "w"))) {
X      errlog("$SE System Error on fopen %s\n", tname);
X      sendMSG("System Error Detected, for file  %s, try again later", fname);
X      fclose(fp);
X      return;
X    }
X    while ((i = getc(fp)) != EOF) {
X      if (!isprint(i) && i != '\n' && i != '\t' && i != '\f')
X	isbin = YES;
X      if (putc(i, fb) == EOF) {
X	errlog("$ND No diskspace? for tfile %s\n", tname);
X	sendMSG("Cant send file %s for lack of diskspace, try again later",
X		fname);
X	fclose(fb);
X	fclose(fp);
X	unlink(tname);
X	return;
X      }
X    }
X    fclose(fb);
X    fclose(fp);
X  }
X
X  if (isbin) 			/* It was binary so we have to encode file */
X    if (bencode(tname, bcode, fname)) {
X      errlog("$BE Bad Binary Encoding for %s\n", tname);
X      sendMSG("Cant send file %s for lack of diskspace, try again later",
X	      fname);
X      return;
X    }
X
X  if (maxsiz) {		       	/* Check for file size */
X    if (stat(tname, &st_bff)) {
X      errlog("$SE System Error %s\n", fname);
X      sendMSG("System Error Detected, for file %s, try again later", fname);
X      unlink(tname);
X      return;
X    }
X    if (st_bff.st_size > maxsiz) {
X				/* Too big, need a different method to send */
X      sendsplit(tname, fname, maxsiz, rpath);
X      return;
X    }
X  }
X  sprintf(auxb, MAILSENDF, SBJ_SENDACK, fname, rpath, tname);
X  errlog("#SF Sending file %s\n", fname);
X  if (system(auxb)) 		/* Mail the file Over */
X    errlog("$ME mail: Can't fork? for %s\n", fname);
X  unlink(tname);		/* Clean up our mess */
X}
X
X/*
X * int senddir(char *dirname, char *mailpath, char bcode, unsigned long maxsiz)
X *  This function is called by sendfile whenever it encounters a directory.
X *  What it does, is, it first opens the directory (thus finding out that it
X *  is readable)  Mails a message
X *  Starts reading the directory.  For eachfile, it will call sendfile
X *  (recursion) to do the actual work.
X */
Xsenddir(dirname, mailpath, bcode, maxsiz)
X     char *dirname,		/* name of the directory */
X          *mailpath,		/* Who will get the mail */
X          bcode;		/* This and maxsiz are passed directly */
X     int  maxsiz;		/* to sendfile */
X{
X  DIR *Dp;			/* Directory pointer */
X  struct dirent *dp;		/* Directory entry */
X  char fname[L_TSTR];		/* Buffer for building filenames */
X
X  if (!(Dp = opendir(dirname))) {	/* Read directory */
X    errlog("$NA No Access to %s\n", dirname);
X    sendMSG("Sorry, you don't have access to that directory %s", dirname);
X    return;
X  }
X  errlog("#OD Opening Directory %s\n", dirname);
X  sendWRN(dirname);
X  for (dp = readdir(Dp); dp != NULL; dp=readdir(Dp))
X    if (strcmp(".",dp->d_name) && strcmp("..",dp->d_name)) { 
X               				/* Don't process "." or ".." */
X      strcpy(fname, dirname);	/* For each file, "sendfile" it! */
X      strcat(fname, "/");
X      strcat(fname, dp->d_name);
X      sendfile(fname, mailpath, bcode, maxsiz);
X    }
X}
X
X/*
X * int sendsplit(char *tname, char *fname, unsigned long maxsiz, char *rpath)
X * This routine will send the file "tname" as "fname" but it will also split
X * it so it will be less than "maxsiz". Upon completion, it will unlink
X * tname and any extra junk files.
X *
X * (NOTE, we assume reasonably sized line lengths)
X */
X 
X/* We use the following template for the sending files 
X#!/bin/sh
X#-------------------Cut Here And "sh file"--------------------------------
XPATH=/bin:/usr/bin:/usr/ucb ; export PATH
Xif test -f XFNAMEX -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"XFNAMEX\"
Xelse
Xecho shar: Extracting \"XFNAMEX\" \(56 characters\)
Xsed "s/^X//" >XFNAMEX <<'END_OF_FILE'
XX
XX I N S E R T    X F N A M E X     I N    H E R E
XX
XEND_OF_FILE
Xif test SIZE -ne `wc -c <XFNAMEX`; then
X    echo shar: \"XFNAMEX\" unpacked with wrong size!
Xfi
Xfi
Xecho shar: End of shell archive.
Xexit 0
X*/
X
Xsendsplit(orgnme, nicenme, maxsize, rpath)
X     char *orgnme,		/* File to send */
X          *nicenme,	        /* Name to put in the subject line */
X          *rpath;	        /* Mail Path to use */
X     unsigned long maxsize;	/* Max message size */
X{
X  char tname[L_tmpnam],		/* Buffer where to store temp name */
X       niceprt[TSTR];		/* String to build part filenames */
X  unsigned short partc = 0;     /* Part count number */
X  unsigned long sizek = 0;	/* Message Size Count */
X  int keyc;			/* Used for file reading */
X  FILE *fin, *fout;		/* Files used for I/O */
X
X  errlog("#PS Prepare Split Send of %s\n", nicenme);
X  tmpnam(tname);		/* Build Temp filename */
X  if (!(fin = fopen(orgnme, "r"))) {
X				/* Open the file to split */
X    errlog("$SE splitsend Can't open org file %s\n", orgnme);
X    sendMSG("System Error Detected, for file %s, try again later", nicenme);
X    unlink(orgnme);
X    return;
X  }
X  while ((keyc = getc(fin)) != EOF) {
X    				/* Create Output files */
X    if (!sizek) {		/* Do we need to open a new output file? */
X      if (!(fout = fopen(tname, "w"))) {
X				/* Couldn't Open it! */
X	errlog("$NO splitsend Can't open out file %s\n", tname);
X	sendMSG("Cant send file %s (lack of diskspace),try again later",
X		nicenme);
X	fclose(fin);
X	unlink(orgnme);
X	return;
X      }				/* Copy the Start of the SHAR file */
X      sprintf(niceprt, "%s.%-02d", nicenme, partc);
X      fprintf(fout,"#!/bin/sh\n");
X      fprintf(fout,
X	      "#---------------Cute here and \"sh file\"------------------\n");
X      fprintf(fout,
X	      "#Wrapping by Alex C. Liu and his very naive and cumbersome\n");
X      fprintf(fout,"#DummySplitShar!\n");
X      fprintf(fout,"PATH=/bin:/usr/bin:/usr/ucb ; export PATH\n");
X      fprintf(fout,"if test -f %s -a \"${1}\" != \"-c\" ; then\n", niceprt);
X      fprintf(fout,
X	      "   echo shar: Will not over-write existing file \\\"%s\\\"\n",
X	      niceprt);
X      fprintf(fout,"else\n");
X      fprintf(fout,"echo shar: Extracting \\\"%s\\\"\n", niceprt);
X      fprintf(fout,"sed \"s/^X//\" > %s <<'END_OF_FILE'\nX", niceprt);
X    }
X    if (putc(keyc, fout) == EOF) {
X				/* Just copy the files */
X      errlog("$ND splitsend Can't write file  %s\n", tname);
X      sendMSG("Cant send file %s (lack of diskspace),try again later",
X	      nicenme);
X      fclose(fin);
X      fclose(fout);
X      unlink(tname);
X      unlink(orgnme);
X      return;
X    }
X    sizek++;
X    if (keyc == '\n') {
X      if (sizek < maxsize)	/* Only check sizes at the end of a line */
X	putc('X',fout);
X      else {
X	endfout(fout, sizek, niceprt, partc, tname, rpath, NO);
X	partc++;
X	sizek=0;
X      }
X    }
X  }
X  sizek++;			/* We append an extra LF just in case */
X  putc('\n', fout);
X  endfout(fout, sizek, niceprt, partc, tname, rpath, YES);
X  fclose(fin);			/* Clean up the mess */
X  unlink(tname);
X  unlink(orgnme);
X}
X
X/*
X * This routine should have been part of the sendsplit routine, it simply
X * outputs the EOF indicator and the size test of the SHAR file
X *
X */
Xendfout(fout, sizek, niceprt, partc, tname, rpath, flast)
X  FILE *fout;				/* Ouput File Pointer */
X  unsigned long sizek;			/* Estimated file size for test */
X  unsigned short partc;			/* Number of part we are ending */
X  char *niceprt,			/* Nice Printable file name for part */
X       *tname,				/* Actual file name */
X       *rpath,				/* Mail Return Path */
X       flast;				/* Flag Last File */
X{
X  char auxb[L_TSTR];			/* Buffer for building sh command */
X  fprintf(fout, "END_OF_FILE\n");	/* Display EOF for shar file */
X  fprintf(fout, "if test %d -ne `wc -c < %s`; then\n", sizek, niceprt);
X  fprintf(fout, "    echo shar: \\\"%s\\\" unpacked with wrong size!\n",
X	  niceprt);
X  fprintf(fout, "fi\nfi\n");
X  if (flast) {
X    fprintf(fout, "echo 'shar: End of Part%-02d (Last Part)'\n", partc);
X    fprintf(fout,
X	    "echo 'shar: Now simply concatenate (cat) the files together!'\n");
X  }
X  else 
X    fprintf(fout, "echo shar: End of shell archive part%-02d\n", partc);
X  fprintf(fout, "exit 0\n");
X  fclose(fout);
X  errlog("#SS Sending Part %s\n", niceprt);
X  sprintf(auxb, MAILSENDS, SBJ_SENDSACK, niceprt, rpath, tname);
X  if (system(auxb)) 		/* Mail the file Over */
X    errlog("$ME mail: Can't fork? for %s\n", niceprt);
X}
X
X/*
X * int isreadable(char *file)
X *   Returns non-zero if the file is readable, otherwise it returns NULL
X * (It simply FOPENS  the file to tell if it is readable or not.
X */
Xisreadable(fx)
X     char *fx;
X{
X  FILE *rv;			/* Store the Return Value from FOPEN */
X  if (rv = fopen(fx, "r"))	/* Try to open the file */
X    fclose(rv);			/* If succeed, we close it */
X  return((int)rv);		/* Return the results of the fopen */
X}
X
X/*
X * int chkpath(char *path)
X *   Checks a filename for funny things going on.  (i.e. security bugs)
X * returns non-zero in case of something bad happend
X * Also logs the stuff into the log file 
X *  It will check for a file beginning with "/" and "../"s inside the
X * filename.
X */
X
Xint chkpath(path)
X     char *path;
X{
X  char *current;
X  current = path;
X  if (*current == '/' || !strncmp(current, "../", 3)) {
X    sendMSG("Your file specification of %s is not a valid filename", path);
X    errlog("$IA ******* Intruder Alert *******  (%s)\n", path);
X    return(ERROR);
X  }
X
X  while (*(++current))
X    if (!strncmp(current, "/../", 4)) {
X      sendMSG("Your file specification of %s is not a valid filename", path);
X      errlog("$IA ******* Intruder Alert *******  (%s)\n", path);
X      return(ERROR);
X    }
X  current = path;
X  while (*current) {			/* Fix Quotes */
X    if (*current == '\'') {
X      errlog("$IA ******* Intruder Alert *******  (%s)\n", path);
X      *current = '.';
X    }
X    current++;
X  }
X  return(NOERROR);
X}
END_OF_sendfile.c
if test 13323 -ne `wc -c <sendfile.c`; then
    echo shar: \"sendfile.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strcase.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strcase.c\"
else
echo shar: Extracting \"strcase.c\" \(641 characters\)
sed "s/^X//" >strcase.c <<'END_OF_strcase.c'
X/**********
X * File: strcase.c
X *   Implements the case insensitive comparison described in the man page  *
X * But for some reason doesn't get linked to the  program.		   *
X 								   *********/
X#include <ctype.h>
X
Xstrcasecmp( s1, s2)
X     char *s1, *s2;
X{
X  char c1, c2;
X  s1--;s2--; 				/* Predecrement pointers */
X  do {
X    if (isupper(c1 = *(++s1))) c1 = tolower(c1); /* Make the uppercase */
X    if (isupper(c2 = *(++s2))) c2 = tolower(c2);
X					/* Lowercase (case insensitive) */
X    if (c1 - c2)			/* Compare characters */
X      return(s1 - s2);			/* They ARE differnet */
X  }  while (c1);
X  return(0);				/* They are the same */
X}
END_OF_strcase.c
if test 641 -ne `wc -c <strcase.c`; then
    echo shar: \"strcase.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f TODO -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"TODO\"
else
echo shar: Extracting \"TODO\" \(333 characters\)
sed "s/^X//" >TODO <<'END_OF_TODO'
XWe should directly tap into "sendmail" rather than use "mail" as a
Xintermediary.
X
XCreate Compile Options for BATCH mode
X
XI should be more careful when MALLOCating memory.  Currently we are not
Xfree'ing any of the stuff.  It is not that important since Unix will
Xdeallocate the memory for us, but I dunno about Xenix or other OS's...
END_OF_TODO
if test 333 -ne `wc -c <TODO`; then
    echo shar: \"TODO\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
#! /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:  doc.shar
# Wrapped by acliu@skat.usc.edu on Fri Jan  5 15:45:22 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f doc.shar -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"doc.shar\"
else
echo shar: Extracting \"doc.shar\" \(14911 characters\)
sed "s/^X//" >doc.shar <<'END_OF_doc.shar'
X#! /bin/sh
X# This is a shell archive.  Remove anything before this line, then unpack
X# it by saving it into a file and typing "sh file".  To overwrite existing
X# files, type "sh file -c".  You can also feed this as standard input via
X# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
X# will see the following message at the end:
X#		"End of shell archive."
X# Contents:  binary.formats commands contents contribution intro
X# Wrapped by acliu@skat.usc.edu on Wed Dec 20 06:14:20 1989
XPATH=/bin:/usr/bin:/usr/ucb ; export PATH
Xif test -f binary.formats -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"binary.formats\"
Xelse
Xecho shar: Extracting \"binary.formats\" \(2370 characters\)
Xsed "s/^X//" >binary.formats <<'END_OF_binary.formats'
XXFILE: help binary.formats
XXLAST CHANGE: Dec 8th, 1989
XXVERSION: UX-Maze Server V2.0c
XX				   
XX		 UX-Maze Encoded Binary File Formats
XX		 ===================================
XX
XXIn order for one to be able to send binary data over 7bit connections
XXsuch as the ones in mail, one must be able to conver the Binary data
XXinto a more printable format and be able to put it back into binary.
XX
XXOne good think about computers, is that all standards aren't standard,
XXso  this server provides 3 different methods for encoding binary
XXinformation:
XX
XXuuencode
XX  This is the USENet's and UNIX's standard for sending binary data
XXover mail connections.  This is method is the default for the server.
XXFile's are expanded by 35% though.  Source code for decodeing
XXuuencoded files is available through this server in the file:
XX	unix-support uuencode
XX
XXbtoa
XX  This is a nice encoding programming originally distributed with the
XXUnix Compress package.  It is like uuencode, but it will expand the
XXfiles only 25%.  And also trys to compress strings of zeros into a
XXsingle character.  The source for this method is in:
XX	unix-support btoa
XX
XXhex
XX  This is a format I made up in order to help people who don't have
XXUnix or uudecoding capablities handy.  It is a very simple encoding
XXmethod, involving Binary->Hex conversion and some extra checksums
XXadded just because I wanted the protocol to look fancy.  Basicly, a
XXencoded file has the following form:
XX	 ________________
XX	|Beginning of file
XX	|Some extra garbage
XX	|
XX	|hexf filename			<- Indicates that a hex file
XX	|:082345677667D87D8BC93            begins (Pretty much like
XXHex en-	|:03449A87C837F874B8374FF          the "begin" line in
XXcoded	|:033045BD311F34559302             uuencoding
XXbinary  |:0300040484993FA884BA6D
XXdata    |:1233BBC3349B33DFF4844
XX	| ^^|<----up to---->|^^
XX          ||    35 bytes     ||
XXNumbers <=++	 in hex      ++=> Checksum
XXof bytes in		Mod256 addition of all
XXline (without)		bytes in the line w/o including
XXincluding the chksum      the byte count
XX	|:082345677667D87D8BC93
XX	|:03449A87C837F874B8374FF
XX	|:033045BD311F34559302
XX        |:0300040484993FA884BA6D
XX        |:1233BBC3349B33DFF4844
XX	|end				<- Indicates the end of the
XX	|Some more trailing garbage        hex file
XX	|________________
XXThis encoding method was design to be simple and at the same time
XXrobust.  So users from almost any o.s. will be able to write a
XXdecoder.
XEND_OF_binary.formats
Xif test 2370 -ne `wc -c <binary.formats`; then
X    echo shar: \"binary.formats\" unpacked with wrong size!
Xfi
X# end of overwriting check
Xfi
Xif test -f commands -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"commands\"
Xelse
Xecho shar: Extracting \"commands\" \(4272 characters\)
Xsed "s/^X//" >commands <<'END_OF_commands'
XXFILE: help commands
XXLAST CHANGE: Oct 29th, 1989
XXVERSION: UX-Maze Server V2.0c
XX
XX	       UX-Maze Archive Server Command Requests
XX	       =======================================
XX
XXThe UX-Maze File Server is a simple hook to the Unix's Sendmail
XXforwarding mechanism.  Mail Messages are piped to the program, and if
XXa Server Request is detected, the program will proceed to service any
XXrequests.  Requests are lines beginning with a keyboard and two or
XXless argumments.  You may put one several request in a message as long
XXas you put only one request per line.  Requests that the program
XXdoesn't understand are silently ignored.  Valid commands/requests are
XXas follows:
XX
XX(A word on notations.  Trough out this help system, Optional
XXparameters are denoted as surroned by [ ]s.  Volumes and directories
XXare treated as the same thing.  Note that Keywords are case
XXinsensitive but Filenames are NOT!)
XX
XXpath <mail path from server to user>
XX  Will set the mail return path to the word following the command.
XXAny other word is follwing the mail path is ignored.  This is used,
XXwhenever the Program is unable to find a suitable return address for
XXthe user.  Usually, you don't need to use this command, and just mail
XXyour request.  If after a reasonably length of time, you haven't get
XXany reply, you should try again, but specifing your path.
XX
XXhelp [topic]
XX  Will send you the help file on the topic that you specify in the
XXcommand line. Put ONE topic per line.  (Send a "help contents" to see a
XXlist of available files)
XX
XXbencode [uuencode|btoa|hex]
XX  Specifie what program to use when encoding binary files on mailing.
XXThey can be
XX   "uuencode"  the default (Unix standard)
XX   "btoa"      a non popular but VERY efficient method for encoding
XX 	       data (Uses btoa v4.0)
XX   "hex"       A Dumb and wasteful method, but very easy to decode.
XX               (Extremely portable!)
XXsee the file "help binary.formats" for more information
XX
XXmaxsize [number]
XX  Some mail connections will not allow messages above certain limit.
XXAs it often happens, there are several files that are way above this
XXlimit.  So in order to be sent, they would need to be splitted first.
XXThis command lets you specify, the ~maximum size for a file.  So when
XXthe file exceeds this limit it will be automatically splitted.  (Note
XXthat in case the maxsize is 0 (zero, the default) no size checking is
XXdone)
XX
XXcontents [volume_name]
XX  Will send a file explaining the contents of the specified volume.
XXIf the volume name is omitted it will send the contents file of the
XXhelp directory.  (Usually a list of all available volumes)
XX
XXindex [volume_name]
XX  Will send the output of a dir or 'ls -l' command.  If the
XXvolume_name is ommited, it will send the dir list  of the Archive's
XXroot directory, listing, the different directories.  This command will
XXprovide a more up-to-date listing of what's in a volume than with the
XXcontents command, with the disadvantage, that it does not contain
XXexplanation of the available files.
XX
XXsend [volume_name] [file_name]
XX  Will send the file 'file_name' in volume 'volume_name'.  If the
XXfile_name is not specified, it will send the contents of the
XX'volume_name'.  If neither is specified, it will send the list of
XXvolumes.  If the [file_name] is a directory, the server will send ALL
XXthe files in that directory.  Use the directory send option with care!
XXIf you wish to request individual files in a directory use as
XXfilename:  "directory/file_name"
XX  Also, the program will check if the file is binary.  If it is binary
XXit will use an encoding method chosen by the user with the "bencode"
XXcommand.  If no encoding method has been specified the server will as
XXa default send the file uuencoded.
XX  The user may also specified the maximum file size with the maxsize
XXcommand.  If the file is biffer than the allowed maximum, the program
XXwill automatically split the files and individually shar the parts for
XXyou.
XX
XXreceive [volume_name] [file_name]
XX  Will make the server to consider what follows after that line as a
XXFile submission.  And the file will be saved in the incomming
XXdirectory as:
XX	volume_name:file_name	or
XX	volume_name:file_name.# (where # is a number to avoid
XX   overwriting files)
XX
XXend
XX  This will stop the server for looking the rest of the message for
XXservice requests.
XX
XEND_OF_commands
Xif test 4272 -ne `wc -c <commands`; then
X    echo shar: \"commands\" unpacked with wrong size!
Xfi
X# end of overwriting check
Xfi
Xif test -f contents -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"contents\"
Xelse
Xecho shar: Extracting \"contents\" \(400 characters\)
Xsed "s/^X//" >contents <<'END_OF_contents'
XXFILE: help contents
XXLAST CHANGE: Dec 20th, 1989
XXVERSION: UX-Maze Server V2.0c
XX				   
XX		      Current list of help files
XX
XXbinary.formats
XX==============
XX  Explanation of the binary encoding methods used by this program.
XX
XXcommands
XX========
XX  Explanation of commands
XX
XXcontribution
XX============
XX  Quick instructions on how to submit files to the server.
XX
XXintro
XX=====
XX  Quick introduction to the server.
XX
XEND_OF_contents
Xif test 400 -ne `wc -c <contents`; then
X    echo shar: \"contents\" unpacked with wrong size!
Xfi
X# end of overwriting check
Xfi
Xif test -f contribution -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"contribution\"
Xelse
Xecho shar: Extracting \"contribution\" \(1143 characters\)
Xsed "s/^X//" >contribution <<'END_OF_contribution'
XXFILE: help contribution
XXLAST CHANGE: Dec 8th, 1989.
XXVERSION: UX-Maze Server V2.0c
XX				   
XX	      Submitting files using the UX-Maze Server
XX	      =========================================
XX
XXAs with any user supported file database, its contents are as good as
XXits submissions by users.  So, if you have anything to share please,
XXdon't hesitate to submit it.
XX
XX	    How to Submit files to the Mail Archive server
XX	    ==============================================
XX
XXThe Mail-Archive-Server has provisions to receive file contributions
XXfrom users all over the net.  To do so, you have to Send mail to me,
XXwith a Subject line of:
XX   Subject: Mail-Archive-Request
XX
XXand at the beginning of your message (that is, BEFORE the file that
XXyou wish to submit) enter the following line:
XX   receive volume file  (VERY Improtant, if you don't put it, the
XXserver will not know what to do with your file and as a default it
XXwill erase it)
XX
XXInmediatly after that, insert the file that you want to submit.
XXPlease try to submit files in UUencoded format or Unix-Shar archives.
XXYou may send Plain ASCII files anytime though.
XX
XX		  FEEL FREE TO SUBMIT STUFF ANYTIME
XX
XEND_OF_contribution
Xif test 1143 -ne `wc -c <contribution`; then
X    echo shar: \"contribution\" unpacked with wrong size!
Xfi
X# end of overwriting check
Xfi
Xif test -f intro -a "${1}" != "-c" ; then 
X  echo shar: Will not over-write existing file \"intro\"
Xelse
Xecho shar: Extracting \"intro\" \(4010 characters\)
Xsed "s/^X//" >intro <<'END_OF_intro'
XXFILE: help intro
XXLAST CHANGE: Dec 8th, 1989.
XXVERSION: UX-Maze Server V2.0c
XX
XX	    Introduction to UX-Maze's Mail Archive Server
XX	    =============================================
XX
XX			      DISCLAIMER
XX			      ----------
XX
XXAll the software in the UX-Maze Mail-Archive is provided AS IS with NO
XXWARRANTY.  I Cannot guarantee that it is good for any particular
XXpurpose, or even that it works.
XX
XXI try to attempt to examine the software submitted to me, but as with
XXall free software written by strangers, MAKE SURE YOU KNOW WHAT YOU'RE
XXINSTALLING BEFORE YOU INSTALL IT!
XX				   
XX			   Server Software
XX                           ---------------
XX
XXThe way the Server is written, it is simply a "hook" to the sendmail
XXforwarding mechanism available in Unix.  The main program is written
XXin C but with some Shell script drivers and shell escapes.  The
XXsoftware is available from here, by requesting file:
XX   send unix-support server
XX
XXHow the Server Works:
XXTo make use of the server you have to send a Mail message to me,
XX<acliu@skat.usc.edu> and have a subject line:
XX   Subject: Mail-Archive-Request
XXTHIS IS VERY IMPORTANT!  If you don't have that line spelled exactly
XXlike that you won't get anything, and I will get a mailbox full of
XXjunk messages.  Somewhere along the header there should be a line
XXsaying:
XX   Return-Path: <your path from me to you>  (This can change from site
XX   to site, consult your local unix-mail guru for more info)
XXUsually, sendmail adds this automagically, but if it were not the
XXcase, you can specify a return path by puting a line in the body of
XXyour message saying:
XX   path <from me to you>
XX
XXIn the body of your message you put the Mail Archive request.  You can
XXput several request in a single message, one request per line.  The
XXfollowing request are honored:  (Send a "help commands" for details)
XX
XX   path <return path from to you>
XX       Forces M-AR to send the file to the mailing address specified
XX       in its argument
XX   help [topic]
XX       Sends help on the topic.  Default is this intro file. Make a
XX          help contents
XX       request for a list of what is available here.
XX   contents [volume]
XX       Sends the contents of the volume.  Defualt will send the list
XX       of available volumes AND the contents of the Help volume.
XX   index [volume]
XX       Sends the directory list of the volume.  Default will send the
XX       directory for help volume
XX   send [volume] [file]
XX       Sends the file on the specified volume.  Default Volume is
XX       help, and default file is contents.
XX   bencode [uuencode|btoa|hex]
XX       Default encoding method to send binary files. Whenever the
XX       server encounters binary data, it will use the latest bencode
XX       command to select what method to use.  (Default: uuencoding)
XX   maxsize [bytesize]
XX       Some mailer gateways will not accept messages larger than
XX       certain limit.  Whenever the file exceeds that limit, the
XX       server will split the file and shar the parts before sending
XX       them.  This command lets you define the max message size in
XX       bytes. (Default 0 = infinty)
XX   receive [volume] [file]
XX       Saves the message as if it were a submitted file.  (use this
XX       command to submit files to the server.)
XX   end
XX       Exits the server. (Optional)
XX
XXThe keywords are case insensitive BUT files are NOT.  So if you see a
XXfile named "gAMe" and you request "GamE".  You will get nothing!
XX
XX			   Submitting files
XX			   ================
XX
XX   The server allows other users to submit files to the server.  To do
XXthis, send a Server request as you would normally do, but instead of
XXsending normal request, you enter the following line:
XX
XX   receive volume file
XX
XXAnd after that, include a UUencoded/shar'ed version of the file you
XXare submitting.
XX
XXFor more info,
XX   help contribution
XX____________________________________________________________________
XXQuestions and suggestions, send them to the same address, but don't
XXput a Mail-Archive-Request subject line.  (Just think of it of yet
XXanother mail message)  
XEND_OF_intro
Xif test 4010 -ne `wc -c <intro`; then
X    echo shar: \"intro\" unpacked with wrong size!
Xfi
X# end of overwriting check
Xfi
Xecho shar: End of shell archive.
Xexit 0
END_OF_doc.shar
if test 14911 -ne `wc -c <doc.shar`; then
    echo shar: \"doc.shar\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

______________________________________________________________________
Alex C. Liu                   | INTERNET: acliu%skat@usc.edu
Voice: (213) 749-2730         | BITNET: acliu%skat@gamera
Q-Link: Alejandro             | UUCP: ...!usc!edu