home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-01-31 | 59.5 KB | 2,131 lines |
-
- #! /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 archive 4 (of 11)."
- # Contents: aux/srctoman.sh daemon/DAEMON.ins daemon/Makefile
- # daemon/ms_parse.c main/Implement main/invoke.c main/msd_dir.c
- # main/screen.h main/sendwork.c main/setup.c main/switcher.c
- # main/unalias.c
- # Wrapped by wswietse@tuewsa on Mon Jan 22 17:27:16 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f aux/srctoman.sh -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"aux/srctoman.sh\"
- else
- echo shar: Extracting \"aux/srctoman.sh\" \(4444 characters\)
- sed "s/^X//" >aux/srctoman.sh <<'END_OF_aux/srctoman.sh'
- X: srctoman - see comment below
- X
- X: process arguments
- X
- Xwhile :
- Xdo
- X case $1 in
- X [0-9]) SECT=$1;;
- X -) LANG=$1; B='[#:]';;
- X -awk) LANG=$1; B='#';;
- X -c) LANG=$1; B='\/\*';;
- X -f) LANG=$1; B='[Cc]';;
- X -mk) LANG=$1; B='#';;
- X -n|-t) LANG=$1; B='\\"';;
- X -p) LANG=$1; B='{';;
- X -r) LANG=$1; B='#';;
- X -C) LANG=$1; B=$2; shift;;
- X -*) ERROR="unknown option: $1"; break;;
- X "") ERROR="missing file argument"; break;;
- X *) break;;
- X esac
- X shift
- Xdone
- X
- X: check error status
- X
- Xcase $ERROR in
- X"") ;;
- X *) echo "$0: $ERROR" 1>&2
- X echo "usage: $0 [-|-awk|-c|-f|-mk|-n|-p|-t|-r] [section] file(s)" 1>&2; exit 1;;
- Xesac
- X
- X: set up for file suffix processing
- X
- Xcase $LANG in
- X"") sh='[:#]'; r='#'; rh=$r; awk='#'; mk='#';
- X c='\/\*'; h=$c; y=$c; l=$c;
- X f='[Cc]'; fh=$f; p='{'; ph=$p;
- X ms='\\"'; nr=$ms; mn=$ms; man=$ms;
- Xesac
- X
- X: extract comments
- X
- Xfor i in $*
- Xdo
- X case $LANG in
- X "") eval B\="\$`expr $i : '^.*\.\([^.]*\)$'`"
- X test "$B" || { echo "$0: unknown suffix: $i; assuming c" 1>&2; B=$c; }
- X esac
- X sed '
- X /^'"$B"'++/,/^'"$B"'--/!d
- X /^'"$B"'++/d
- X /^'"$B"'--/d
- X s/[ ]*$//
- X /^'"$B"' \([A-Z]\)/{
- X s//\1/
- X /^NAME/{
- X N
- X s/^.*\n'"$B"'[ ]*//
- X h
- X y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
- X s/^.*$/.TH & '"$SECT"'\
- X.ad\
- X.fi\
- X.SH NAME/
- X p
- X g
- X s/ [0-9]$//
- X a\
- X\\-
- X p
- X d
- X }
- X /^SUMMARY/d
- X /^DESCRIPTION/s//.SH &\
- X.ad\
- X.fi/
- X /^BUGS/s//.SH &\
- X.ad\
- X.fi/
- X /^DIAGNOSTICS/s//.SH &\
- X.ad\
- X.fi/
- X /^[A-Z][A-Z][A-Z][^a-z]*$/s//.SH &\
- X.na\
- X.nf/
- X p
- X d
- X }
- X s/^'"$B"'[ ]*//
- X s/^[ ]*$//
- X' $i
- Xdone
- X
- Xexit
- X
- X:++
- X: NAME
- X: srctoman 1
- X: SUMMARY
- X: extract manual page from source file comment
- X: PACKAGE
- X: source file maintentance tools
- X: SYNOPSIS
- X: srctoman [-|-awk|-c|-f|-mk|-m|-n|-p|-t|-r] [section] file(s)
- X: DESCRIPTION
- X: Srctoman converts comments in various programming languages to
- X: UNIX-style manual pages.
- X: The command processes comments in the style of newsource(1);
- X: its standard output is suitable for formatting with nroff(1) or
- X: troff(1) using the "-man" macro package.
- X: Typically, srctoman is integrated with make(1) scripts.
- X:
- X: Source files are processed in the indicated order; if no
- X: files argument the command produces no output.
- X:
- X: The source file language can be specified through a command-line
- X: option, or can be implied by the filename suffix.
- X: The expected start-of-comment symbol is shown in the last column.
- X:
- X: .nf
- X option language comment
- X
- X - shell [:#]
- X -awk awk #
- X -c c /*
- X -f fortran [Cc]
- X -mk make #
- X -n nroff \\"
- X -p pascal {
- X -t troff \\"
- X -r ratfor #
- X -C any language next argument
- X: .fi
- X:
- X: .nf
- X suffix language comment
- X
- X .awk awk #
- X .c c /*
- X .f fortran [Cc]
- X .fh fortran [Cc]
- X .h c /*
- X .l lex /*
- X .man nroff,troff \\"
- X .mk make #
- X .me nroff,troff \\"
- X .ms nroff,troff \\"
- X .nr nroff,troff \\"
- X .p pascal {
- X .ph pascal {
- X .r ratfor #
- X .rh ratfor #
- X .sh shell [:#]
- X .y yacc /*
- X: .fi
- X:
- X: The required format of comments is discussed below, where SOC
- X: stands for the start-of-comment symbol of the language being used.
- X:
- X: 1) Start of manual: SOC, followed by `++'.
- X:
- X: 2) Section heading: SOC, blank, section name in upper case.
- X:
- X: 3) New paragraph: empty line or line with SOC only.
- X:
- X: 4) All other text: SOC and subsequent blanks or tabs are removed.
- X: Lines that do not start with SOC are left unchanged (useful for
- X: inclusion of program text).
- X:
- X: 5) End of manual: SOC, followed by `--'.
- X: An end-of-comment may follow if the source file language requires this.
- X:
- X: The following manual sections receive a special treatment:
- X: NAME and SUMMARY should appear at the beginning and in
- X: this order; DESCRIPTION, DIAGNOSTICS and BUGS will be
- X: right-margin adjusted.
- X: Other sections may be added freely without confusing srctoman.
- X: COMMANDS
- X: sh(1), sed(1), expr(1)
- X: SEE ALSO
- X: newsource(1), modsource(1), xman(1)
- X: The earlier commands new(1), mod(1), mkman(1) and dssman(1)
- X: by Ruud Zwart and Ben Noordzij (Erasmus University, Rotterdam)
- X: DIAGNOSTICS
- X: The program complains if an unknown language is specified
- X: or if the language cannot be deduced from the file suffix.
- X: AUTHOR(S)
- X: W.Z. Venema
- X: Eindhoven University of Technology
- X: Department of Mathematics and Computer Science
- X: Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X: CREATION DATE
- X: Fri Jan 17 22:59:27 MET 1986
- X: LAST MODIFICATION
- X: Thu Mar 10 20:08:15 MET 1988
- X: VERSION/RELEASE
- X: 1.20
- X:--
- X
- X
- END_OF_aux/srctoman.sh
- if test 4444 -ne `wc -c <aux/srctoman.sh`; then
- echo shar: \"aux/srctoman.sh\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f daemon/DAEMON.ins -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"daemon/DAEMON.ins\"
- else
- echo shar: Extracting \"daemon/DAEMON.ins\" \(4035 characters\)
- sed "s/^X//" >daemon/DAEMON.ins <<'END_OF_daemon/DAEMON.ins'
- X@(#) DAEMON.ins 1.3 90/01/06 19:47:10
- X
- XThis document describes how to install the daemon software on the file
- Xserver that exports the per-user mail directories, and how to adapt the
- Xlocal sendmail.cf file.
- X
- XOperation
- X=========
- X
- XThe per-user mail directories are mounted from a file server. The UUCP
- Xfile transfer functions of the pc-mail cico program are taken over by
- Xthe following two programs that run on the file server:
- X
- Xpc-mail: deliver mail to a user's mail directory (the receiving
- X function of the cico program). This program is intended
- X to be called by sendmail.
- X
- Xpc-maild: scan user mail directories for unsent mail, and pipe it
- X through the UNIX rmail command (the sending function of
- X the cico program). This program should be started at
- X system boot time.
- X
- XAll per-user mail directories live below the pc-mail spool directory
- X(/var/spool/pc-mail by default).
- X
- XBoth programs report all problems via the syslog facility. Most error
- Xconditions case the programs to retry at a later time.
- X
- XInstallation on the server
- X==========================
- X
- XBuild the pc-mail and pc-maild programs. In the Makefile, you should
- Xspecify the location of the executable programs and the pc-mail spool
- Xdirectory, and how often the daemon program will scan user directories
- Xfor unsent mail. You will probably have to do a `make depend' before
- Xyou can `make' the programs.
- X
- XExecute the following command to create the pc-mail spool directory, and
- Xto install the pc-mail and pc-maild programs. You must be root.
- X
- X % make install
- X
- XThe output from the "make" command will depend on how you specified the
- Xpath names in the Makefile:
- X
- X mkdir /var/spool/pc-mail
- X chmod 755 /var/spool/pc-mail
- X cp pc-mail pc-maild /usr/local/lib
- X chown root /usr/local/lib/pc-mail
- X chmod u+s /usr/local/lib/pc-mail
- X
- XExecute the following command if you wish to install the manual pages.
- X
- X % make installman
- X
- XAgain, the output from make will depend on what you specified in the
- XMakefile:
- X
- X cp pc-mail.8 pc-maild.8 /usr/local/man/man8
- X
- XAdd a line with the command
- X
- X /usr/local/lib/pc-maild
- X
- Xto the file /etc/rc.local (the exact name of the rc script depends on
- Xyour version of unix, and the exact path name of the pc-maild program
- Xdepends on where you installed it).
- X
- XFor now, you will have to start the pc-maild program by hand (unless
- Xyou wish to reboot the machine).
- X
- XAdd to the sendmail.cf file a line that looks like:
- X
- X Mpc, P=/usr/local/lib/pc-mail, F=lsDFMn, S=xxx, R=yyy, A=pc-mail $u
- X
- XWhere xxx and yyy may be the same rewriting rules as used for the local
- Xmailer (usually defined with the "Mlocal" line). The exact path name of
- Xthe pc-mail executable depends on what you specified in the Makefile.
- X
- XIn the file sendmail.cf, at the end of ruleset S0, but just BEFORE the
- Xlocal mailer will be invoked (something like "R$* $#local $:$1"), add a
- Xline with
- X
- X R $=X $#pc $:$1
- X
- XUse a different letter if X is already in use.
- X
- XThere are two ways to define X as a list of pc-mail users. The list can
- Xbe wired into the sendmail.cf file, e.g.:
- X
- X CXjohn marsha
- X
- XMultiple usernames on a line, and multiple CX lines are allowed.
- X
- XA better way is to have sendmail read the list from an external file, by
- Xputting the following line into the sendmail.cf file:
- X
- X FX/etc/pc-mail-users %s
- X
- XThe /etc/pc-mail-users file should contain only a single login name per
- Xline.
- X
- XEach time you change the list of pc-mail users (either in sendmail.cf,
- Xor in the /etc/pc-mail-users file) you will have to kill the sendmail
- Xdaemon and restart it.
- X
- XNote that the sendmail program ON THE NFS SERVER will never read the
- Xpc-mail user's .forward file. That file will still be useful, however,
- Xif the user's home directory is exported to OTHER hosts running
- Xsendmail. In that case you will want to create a .forward file in the
- Xuser's home directory containing
- X
- X username@fully-qualified-hostname-of-the-server
- X
- XThe same effect can be achieved, of course, by adding an entry to the
- Xnetwork-wide alias data base:
- X
- X username: username@server
- END_OF_daemon/DAEMON.ins
- if test 4035 -ne `wc -c <daemon/DAEMON.ins`; then
- echo shar: \"daemon/DAEMON.ins\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f daemon/Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"daemon/Makefile\"
- else
- echo shar: Extracting \"daemon/Makefile\" \(4614 characters\)
- sed "s/^X//" >daemon/Makefile <<'END_OF_daemon/Makefile'
- X# @(#) Makefile 1.7 12/29/89 18:08:05
- X
- X###############################
- X# Start of configurable options. You will also have to do a `make depend'.
- X
- X# Compiler options.
- X# -DSYSV is needed for system 5 release 2
- X# -DRFC822 if you want the daemon to produce To: and From: header lines
- X# -DSYSEXITS if your system has <sysexits.h>
- X# -DSYSLOG if your system has a BSD 4.3-like syslog facility
- X# -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" if you don't have BSD4.3-like syslog
- X# You will also have to create that file, with mode 666.
- X#
- X#BSD4.X: DEFS = -DRFC822 -DSYSEXITS -DSYSLOG
- X#SYSVR2: DEFS = -DRFC822 -DSYSV -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\"
- X
- XDEFS = -DRFC822 -DSYSEXITS -DSYSLOG
- X
- X# Location of pc-mail spool area
- X
- XMAILDIR = /var/spool/pc-mail
- X
- X# How often the daeman will scan the pc-mail spool area for unsent mail.
- X# This time interval can also be changed via the command line.
- X
- XDELAY = 30
- X
- X# Some system-5 implementations have a separate library with BSD-compatible
- X# directory access routines.
- X#
- X#LIBS = -lndir
- X
- XLIBS =
- X
- X# Location of the pc-mail en pc-maild binaries
- X
- XEXEDIR = /usr/local/lib
- X
- X# If you want to, where to install the manual pages
- X
- XMANDIR = /usr/local/man/man8
- X
- X# End of configurable options
- X#############################
- X
- XSHELL = /bin/sh
- XCFLAGS = $(DEFS) -DDELAY=$(DELAY) -DMAILDIR=\"$(MAILDIR)\"
- XARCHIVE = sarch
- XSOURCES = README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h \
- X syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h \
- X percentm.h percentm.c ms_parse.c ms_parse.h DAEMON.ins
- X
- XPCMOBJ = pc-mail.o syslog.o percentm.o dosunix.o ms_parse.o
- XPCMSRC = pc-mail.c syslog.c percentm.c dosunix.c ms_parse.c
- X
- XPCMDOBJ = pc-maild.o syslog.o percentm.o dosunix.o util.o mtime.o
- XPCMDSRC = pc-maild.c syslog.c percentm.c dosunix.c util.c mtime.c
- X
- Xall: pc-mail pc-maild
- X
- Xinstall: all
- X -mkdir $(MAILDIR)
- X chmod 755 $(MAILDIR)
- X cp pc-mail pc-maild $(EXEDIR)
- X chown root $(EXEDIR)/pc-mail
- X chmod 4755 $(EXEDIR)/pc-mail
- X
- Xinstallman:
- X cp pc-mail.8 pc-maild.8 $(MANDIR)
- X
- Xpc-mail: $(PCMOBJ)
- X $(CC) $(CFLAGS) -o $@ $(PCMOBJ) $(LIBS)
- X
- Xpc-maild: $(PCMDOBJ)
- X $(CC) $(CFLAGS) -o $@ $(PCMDOBJ) $(LIBS)
- X
- Xlint: lint1 lint2
- X
- Xlint1: $(PCMSRC)
- X lint $(CFLAGS) $(PCMSRC)
- X
- Xlint2: $(PCMDSRC)
- X lint $(CFLAGS) $(PCMDSRC)
- X
- Xshar: $(SOURCES) pc-mail.8 pc-maild.8
- X @shar $(SOURCES) pc-mail.8 pc-maild.8
- X
- Xclean:
- X rm -f *.o core nohup.out
- X
- Xclobber: clean
- X rm -f pc-maild pc-mail
- X
- Xarchive: $(SOURCES)
- X $(ARCHIVE) $?;
- X touch archive
- X
- Xdepend:
- X (sed '1,/^# do not edit/!d' Makefile; \
- X for i in [a-z][a-z]*.c; do \
- X $(CC) -E $(CFLAGS) $$i | sed -n '/^# *1 *"\([^"]*\)".*/{;s//'`echo $$i|sed 's/c$$/o/'`': \1/;p;}'; \
- X done)>$$$$ && mv $$$$ Makefile
- X
- X# do not edit below this line - it was create with `make depend'
- Xdosunix.o: dosunix.c
- Xdosunix.o: /usr/include/stdio.h
- Xdosunix.o: ./dosunix.h
- Xms_parse.o: ms_parse.c
- Xms_parse.o: /usr/include/stdio.h
- Xms_parse.o: /usr/include/ctype.h
- Xms_parse.o: ./dosunix.h
- Xms_parse.o: ./ms_parse.h
- Xmtime.o: mtime.c
- Xmtime.o: /usr/include/syslog.h
- Xmtime.o: ./mtime.h
- Xpc-mail.o: pc-mail.c
- Xpc-mail.o: /usr/include/stdio.h
- Xpc-mail.o: /usr/include/sys/types.h
- Xpc-mail.o: /usr/include/sys/sysmacros.h
- Xpc-mail.o: /usr/include/sys/stat.h
- Xpc-mail.o: /usr/include/pwd.h
- Xpc-mail.o: /usr/include/varargs.h
- Xpc-mail.o: /usr/include/syslog.h
- Xpc-mail.o: /usr/include/sys/dir.h
- Xpc-mail.o: /usr/include/sysexits.h
- Xpc-mail.o: ./dosunix.h
- Xpc-mail.o: ./percentm.h
- Xpc-mail.o: ./ms_parse.h
- Xpc-maild.o: pc-maild.c
- Xpc-maild.o: /usr/include/stdio.h
- Xpc-maild.o: /usr/include/pwd.h
- Xpc-maild.o: /usr/include/time.h
- Xpc-maild.o: /usr/include/signal.h
- Xpc-maild.o: /usr/include/vm/faultcode.h
- Xpc-maild.o: /usr/include/sys/types.h
- Xpc-maild.o: /usr/include/sys/sysmacros.h
- Xpc-maild.o: /usr/include/sys/stat.h
- Xpc-maild.o: /usr/include/syslog.h
- Xpc-maild.o: /usr/include/sys/types.h
- Xpc-maild.o: /usr/include/sys/dir.h
- Xpc-maild.o: /usr/include/sgtty.h
- Xpc-maild.o: /usr/include/sys/ioctl.h
- Xpc-maild.o: /usr/include/sys/ttychars.h
- Xpc-maild.o: /usr/include/sys/ttydev.h
- Xpc-maild.o: /usr/include/sys/ttold.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: /usr/include/sys/ttycom.h
- Xpc-maild.o: /usr/include/sys/filio.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: /usr/include/sys/sockio.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: ./dosunix.h
- Xpc-maild.o: ./util.h
- Xpc-maild.o: ./mtime.h
- Xpercentm.o: percentm.c
- Xpercentm.o: /usr/include/stdio.h
- Xpercentm.o: ./percentm.h
- Xsyslog.o: syslog.c
- Xutil.o: util.c
- Xutil.o: /usr/include/stdio.h
- Xutil.o: /usr/include/pwd.h
- Xutil.o: /usr/include/sys/types.h
- Xutil.o: /usr/include/sys/sysmacros.h
- Xutil.o: /usr/include/sys/dir.h
- Xutil.o: /usr/include/syslog.h
- Xutil.o: ./util.h
- END_OF_daemon/Makefile
- if test 4614 -ne `wc -c <daemon/Makefile`; then
- echo shar: \"daemon/Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f daemon/ms_parse.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"daemon/ms_parse.c\"
- else
- echo shar: Extracting \"daemon/ms_parse.c\" \(4182 characters\)
- sed "s/^X//" >daemon/ms_parse.c <<'END_OF_daemon/ms_parse.c'
- X/*++
- X/* NAME
- X/* ms_parse 3
- X/* SUMMARY
- X/* message parser
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include "ms_parse.h"
- X/*
- X/* int ms_parse(context, line)
- X/* int context;
- X/* char *line;
- X/*
- X/* int hscanf(line, prefix, format, result)
- X/* char *line;
- X/* char *prefix;
- X/* char *format;
- X/* char *result;
- X/* DESCRIPTION
- X/* The routines in this module recognize
- X/* the context in which successive lines of text occur within an
- X/* e-mail message, or extract specific information from header
- X/* lines.
- X/*
- X/* The expected format of an e-mail message is: UUCP header lines,
- X/* RFC822-like header lines, message body. Each of these sections
- X/* may be missing from the message. A header line is a line that
- X/* has no blanks before the first colon appearing on that line.
- X/*
- X/* ms_parse() determines the context in which a line of text was found:
- X/*
- X/* .nf
- X MS_UUCP UUCP-style From_ line
- X MS_HEADER RFC822-like header line
- X MS_CONT Continued header line
- X MS_BODY Line within message body
- X/* .fi
- X/*
- X/* The context argument should have the value MS_UUCP in the initial
- X/* call of ms_parse(). Upon successive calls the value should be equal
- X/* to the last value returned by ms_parse().
- X/*
- X/* hscanf() compares the beginning of a line with the specified prefix
- X/* (ignoring case differences), and if the comparison succeeds, it
- X/* invokes sscanf() on the remainder of that line. A zero return value
- X/* means that no information was extracted with sscanf.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sat Dec 9 18:50:35 MET 1989
- X/* LAST MODIFICATION
- X/* 1/6/90 19:45:16
- X/* VERSION/RELEASE
- X/* 1.7
- X/*--*/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "ms_parse.h"
- X
- Xextern char *strchr();
- X
- X/* forward declarations */
- X
- Xstatic int isheader();
- Xstatic int istrncmp();
- X
- X/* hscanf - match header and extract info from remainder of header line */
- X
- Xint hscanf(line, pre, fmt, ptr)
- Xchar *line;
- Xchar *pre;
- Xchar *fmt;
- Xchar *ptr;
- X{
- X int len = strlen(pre);
- X
- X return (istrncmp(pre, line, len) == 0 && sscanf(line + len, fmt, ptr) == 1);
- X}
- X
- X/* ms_parse - parse one message line */
- X
- Xint ms_parse(context, line)
- Xregister int context;
- Xregister char *line;
- X{
- X
- X /*
- X * A message may begin with UUCP header lines ("From blablabla",
- X * sometimes escaped with a ">" character), followed by RFC822-like
- X * header lines (lines that start with a word + colon, or continuation
- X * lines that start with whitespace), followed by the remainder of the
- X * message. Header and body are usually separated by an empty line (on
- X * systems that can handle that) but the we do not require this.
- X */
- X
- X switch (context) {
- X case MS_UUCP:
- X if (line[0] == '>' || strncmp(line, "From ", 5) == 0)
- X return (MS_UUCP);
- X if (isspace(line[0]))
- X return (MS_BODY);
- X /* FALLTHROUGH */
- X case MS_HEADER:
- X case MS_CONT:
- X if (isspace(line[0]))
- X return (MS_CONT);
- X if (isheader(line))
- X return (MS_HEADER);
- X /* FALLTHROUGH */
- X case MS_BODY:
- X return (MS_BODY);
- X }
- X /* NOTREACHED */
- X}
- X
- X/* isheader - does this line look like a header? */
- X
- Xstatic int isheader(buf)
- Xchar *buf;
- X{
- X static char blanks[] = " \t\f";
- X char *cp;
- X char *blk;
- X char *colon;
- X
- X /*
- X * A header line has no blanks before the first colon. Which means that a
- X * line that starts with a colon character is treated as header line.
- X * This turns out to be what many sendmail implementations do, too.
- X */
- X
- X if ((colon = strchr(buf, ':')) == 0) { /* check for colon */
- X return (0);
- X } else { /* find preceding blanks */
- X for (cp = blanks; *cp; cp++)
- X if ((blk = strchr(buf, *cp)) != 0 && blk < colon)
- X return (0);
- X }
- X return (1);
- X}
- X
- X#define low(x) ((isascii(x) && isupper(x)) ? tolower(x) : (x))
- X
- X/* istrncmp - case-insensitive strncmp */
- X
- Xstatic int istrncmp(s1, s2, len)
- Xchar *s1;
- Xchar *s2;
- Xint len;
- X{
- X while (len > 0 && *s1 && *s2 && low(*s1) == low(*s2))
- X len--, s1++, s2++;
- X return (len > 0 ? low(*s1) - low(*s2) : 0);
- X}
- END_OF_daemon/ms_parse.c
- if test 4182 -ne `wc -c <daemon/ms_parse.c`; then
- echo shar: \"daemon/ms_parse.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/Implement -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/Implement\"
- else
- echo shar: Extracting \"main/Implement\" \(4560 characters\)
- sed "s/^X//" >main/Implement <<'END_OF_main/Implement'
- X@(#) Implement 2.1 90/01/22 13:01:08
- X
- XThis document describes some implementation aspects of the pc-mail
- Xsoftware.
- X
- XMESSAGE DATA BASE
- X
- XThe message data base resides in the mail spool directory (de-
- Xfined with the MAILDIR environment variable). There are various
- Xclasses of message files:
- X
- X - mail received from the network
- X
- X - mail ready to send over the network
- X
- X - messages in preparation
- X
- X - mail that has been sent
- X
- XIn addition there are administrative files (LOGFILE, alias data
- Xbase and communications parameters). Optional files are: header
- X(with template message header) and trailer (with the user's
- Xsignature).
- X
- XEach message takes two files: a data file (with the actual mes-
- Xsage) and a meta file (with on the first line: originator or
- Xdestination addresses, or a one-line summary in case of a message
- Xin preparation; and on the second line: a subject).
- X
- XData/meta file names are constructed by concatenating a single-
- Xcharacter prefix with a five-digit sequence number. Corresponding
- Xdata and meta files have the same sequence number. The prefix
- Xcharacters are:
- X
- X E message in preparation
- X C description of message
- X
- X N message received from the net
- X H originator address and subject in case of an unread message
- X O originator address and subject in case of already read message
- X
- X D message ready to be sent over the net
- X X destination of that message and subject
- X
- X Q message already sent over the net
- X R destination of that message and subject
- X
- XAdministrative files are
- X
- X LOGFILE transaction log
- X s00000 communications parameters
- X a00000 alias data base
- X
- XAll files in the mail directory are ordinary text files, with a
- Xpossible exception for the message in preparation (this depends
- Xon the editor being used).
- X
- XFiles in the mail directory are normally write-protected to
- Xprevent accidents.
- X
- XThe length of lines in the "meta" files is at most 1024 bytes
- X(see the MAXLINE macro in the file defs.h).
- X
- XMost mailers will object to messages with lines longer than about
- X132 characters.
- X
- XHOW THE PROGRAMS OPERATE
- X
- XThe message data base is shared by several programs. First of
- Xall, there is the mail program itself that provides the main user
- Xinterface. Other programs are: cico (takes unsent messages from
- Xthe mail data base, and changes their status to "sent" after they
- Xhave been sent over the network), smail (queues a message for
- Xtransmission by the cico program), rmail (extracts originator
- Xnames and subject information from messages received by the cico
- Xprogram) and cmail (scans the mail data base for unread
- Xmessages). If the mail directory is mounted from a file server,
- Xthe cico program is not used; instead, its task is performed by
- Xthe pc-mail and pc-maild daemon programs that run on the file
- Xserver.
- X
- XThe following picture shows how the programs interact with each
- Xother, and with the mail data base.
- X
- X-----------------------------------------------------------------
- Xprogram |purpose |invokes
- X--------+-------------------------------+--------------------------
- Xmail |main user interface |cico, smail, rmail, editor
- X | |
- Xcico |file transfer program |none; invoked by mail, cmail
- X | |
- Xsmail |queue file for transmission |none; invoked by mail
- X | |
- Xrmail |extract sender and subject |none; invoked by mail, cmail
- X | |
- Xcmail |search for unread mail |none
- X--------+-------------------------------+--------------------------
- Xpc-mail |deliver mail (on file server) |none; invoked by sendmail
- X | |
- Xpc-maild|send mail (on file server) |/usr/bin/rmail
- X-------------------------------------------------------------------
- X
- XUUCP FUNCTIONALITY
- X
- XThe cico program provided here supports a subset of the uucp file
- Xexchange facilities, just enough to interface to the message
- Xdatabase structure (spool directory) described in the previous
- Xsection.
- X
- XThe main differences with the unix uucico program are:
- X
- X- No support for C (command) files. cico scans the spool
- Xdirectory for message and destination files instead.
- X
- X- Only the H (hangup), S (send) and C (copy) requests are
- Xsupported. R (receive) requests are not allowed. Sending or
- Xreceiving files by path name is rarely allowed anyway, and works
- Xonly between adjacent uucp nodes. This is only a minor
- Xlimitation; files can still be sent as mail messages.
- X
- X- The cico program assumes that all incoming D (data) files are
- Xmail messages.
- X
- X- The cico program ignores incoming X (execute) files. X files
- Xnormally contain the commands to dispose of D (data) files.
- X
- END_OF_main/Implement
- if test 4560 -ne `wc -c <main/Implement`; then
- echo shar: \"main/Implement\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/invoke.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/invoke.c\"
- else
- echo shar: Extracting \"main/invoke.c\" \(4246 characters\)
- sed "s/^X//" >main/invoke.c <<'END_OF_main/invoke.c'
- X/*++
- X/* NAME
- X/* invoke 3
- X/* SUMMARY
- X/* system-dependent process control stuff
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* mailsh
- X/* SYNOPSIS
- X/* #include "status.h"
- X/*
- X/* int invokelp(arg0,arg1,...)
- X/* char *arg0,*arg1,...
- X/*
- X/* int invokevp(argv)
- X/* char **argv;
- X/* DESCRIPTION
- X/* invokelp() creates a child process to execute a command.
- X/* arg0, arg1,... is a null-terminated list of string pointers,
- X/* the first being the name of the program. Use is made
- X/* of the search path to locate the program in arg0.
- X/* With MS-DOS, batch files can only be executed if their name is
- X/* given including the suffix.
- X/*
- X/* invokevp() is similar to invokelp; the difference is that
- X/* argv is an array of pointers to arguments, and that MS-DOS batch
- X/* files are not supported.
- X/* DIAGNOSTICS
- X/* invokelp(), invokevp() return the exit status of the child process,
- X/* E_SYSFAIL if there were insufficient resources, and
- X/* E_NOPROG if the program in arg0 or argv[0] could not be found.
- X/* BUGS
- X/* The invokexx() functions should not be used if the command involves
- X/* shell built-ins, i/o redirection or other shell meta characters.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Apr 5 15:27:37 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* 90/01/22 13:01:50
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- X
- X#include <stdio.h>
- X#include <varargs.h>
- X#include <errno.h>
- X
- X#include "defs.h"
- X#include "status.h"
- X
- X#ifdef MSDOS
- X#include <process.h>
- X#endif
- X
- X/* invokelp - create child process to execute command */
- X
- X/* VARARGS */
- X
- Xpublic int invokelp(va_alist)
- Xva_dcl
- X{
- X va_list ap;
- X#ifdef lint
- X static
- X#endif
- X char *argv[BUFSIZ];
- X char **cpp = argv;
- X#ifdef MSDOS
- X char *cp;
- X
- X /*
- X * Under MS-DOS, we must explicitly invoke a command processor in case of
- X * batch files. If we see the command is a batch file we just stick a
- X * command processor invocation in front of the argument vector. We try
- X * to avoid the command processor since it presently does not return exit
- X * status codes.
- X */
- X
- X va_start(ap);
- X cp = va_arg(ap, char *);
- X if (istrcmp(cp + strlen(cp) - 4, ".bat") == 0) {
- X *cpp++ = "command";
- X *cpp++ = "/c";
- X }
- X va_end(ap);
- X#endif
- X
- X /* Copy variable-length argument list to variable-length vector */
- X
- X va_start(ap);
- X while (*cpp++ = va_arg(ap, char *))
- X /* void */ ;
- X va_end(ap);
- X
- X /* invokevp will do the rest */
- X
- X return (invokevp(argv));
- X
- X#if (!defined(unix) && !defined(MSDOS))
- X "Specify how to do process management"
- X#endif
- X}
- X
- X/* invokevp - create child process to execute command */
- X
- Xpublic int invokevp(argv)
- Xchar **argv;
- X{
- X extern void _exit();
- X
- X /*
- X * On unix systems we fork a process and overlay the child with the
- X * desired program. This means we get -1 if the fork did not succeed,
- X * otherwise the exit status of the child process. The code is a bit
- X * elaborate since we want to handle various error conditions.
- X */
- X#ifdef unix
- X register int pid;
- X
- X if ((pid = fork()) < 0) { /* fork off a process */
- X return (E_SYSFAIL); /* resources exhausted */
- X } else if (pid == 0) { /* this is the child process */
- X (void) execvp(*argv, argv); /* try to replace it */
- X _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL); /* sorry, failed */
- X /* NOTREACHED */
- X } else { /* this is the parent */
- X int xstat,
- X wstat;
- X
- X /* wait till above child terminates */
- X
- X while ((wstat = wait(&xstat)) != -1 && wstat != pid)
- X /* void */ ;
- X if (wstat == -1) {
- X return (E_SYSFAIL); /* oops: no child! */
- X } else if (xstat & 0377) {
- X return (E_UNKNOWN); /* child was killed */
- X } else {
- X return (xstat >> 8); /* child died naturally */
- X }
- X /* NOTREACHED */
- X }
- X#endif
- X
- X /*
- X * With MS-DOS, less can go wrong. On the other hand, MS-DOS can do less.
- X */
- X#ifdef MSDOS
- X int stat;
- X
- X return ((stat = spawnvp(P_WAIT, *argv, argv)) >= 0 ?
- X stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
- X#endif
- X
- X#if (!defined(unix) && !defined(MSDOS))
- X "Specify how to do process management"
- X#endif
- X}
- END_OF_main/invoke.c
- if test 4246 -ne `wc -c <main/invoke.c`; then
- echo shar: \"main/invoke.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/msd_dir.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/msd_dir.c\"
- else
- echo shar: Extracting \"main/msd_dir.c\" \(4738 characters\)
- sed "s/^X//" >main/msd_dir.c <<'END_OF_main/msd_dir.c'
- X#ifdef MSDOS
- X/*
- X * @(#)msd_dir.c 1.4 87/11/06 Public Domain.
- X *
- X * A public domain implementation of BSD directory routines for
- X * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- X * August 1897
- X *
- X * Return file names in lower case W.Z. Venema (wswietse@lso.win.tue.nl)
- X * Aug 1988
- X *
- X * Added special-case code for the root directory WZV 891218
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "msd_dir.h" /* was: <sys/dir.h> */
- X#include <malloc.h>
- X#include <string.h>
- X#include <dos.h>
- X#include <ctype.h> /* for upper->lower case code */
- X
- X#ifndef NULL
- X# define NULL 0
- X#endif /* NULL */
- X
- X#ifndef MAXPATHLEN
- X# define MAXPATHLEN 255
- X#endif /* MAXPATHLEN */
- X
- X/* attribute stuff */
- X#define A_RONLY 0x01
- X#define A_HIDDEN 0x02
- X#define A_SYSTEM 0x04
- X#define A_LABEL 0x08
- X#define A_DIR 0x10
- X#define A_ARCHIVE 0x20
- X
- X/* dos call values */
- X#define DOSI_FINDF 0x4e
- X#define DOSI_FINDN 0x4f
- X#define DOSI_SDTA 0x1a
- X
- X#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
- X#define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM)
- X
- X/* what find first/next calls look use */
- Xtypedef struct {
- X char d_buf[21];
- X char d_attribute;
- X unsigned short d_time;
- X unsigned short d_date;
- X long d_size;
- X char d_name[13];
- X} Dta_buf;
- X
- Xstatic char *getdirent();
- Xstatic void setdta();
- Xstatic void free_dircontents();
- X
- Xstatic Dta_buf dtabuf;
- Xstatic Dta_buf *dtapnt = &dtabuf;
- Xstatic union REGS reg, nreg;
- X
- X#if defined(M_I86LM)
- Xstatic struct SREGS sreg;
- X#endif
- X
- Xstatic char *Strcpy(); /* lower-case copy */
- X
- XDIR *
- Xopendir(name)
- X char *name;
- X{
- X struct stat statb;
- X DIR *dirp;
- X char c;
- X char *s;
- X struct _dircontents *dp;
- X char nbuf[MAXPATHLEN + 1];
- X
- X /*
- X * Need special-case code for ".", to avoid problems with stat()
- X * in the root directory -- WZV 891218
- X */
- X
- X if (strcmp(name, ".") != 0
- X && (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR))
- X return (DIR *) NULL;
- X if (Newisnull(dirp, DIR))
- X return (DIR *) NULL;
- X if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
- X (void) strcat(strcpy(nbuf, name), "\\*.*");
- X else
- X (void) strcat(strcpy(nbuf, name), "*.*");
- X dirp->dd_loc = 0;
- X setdta();
- X dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
- X if ((s = getdirent(nbuf)) == (char *) NULL)
- X return dirp;
- X do {
- X if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
- X malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
- X {
- X if (dp)
- X free((char *) dp);
- X free_dircontents(dirp->dd_contents);
- X return (DIR *) NULL;
- X }
- X if (dirp->dd_contents)
- X dirp->dd_cp = dirp->dd_cp->_d_next = dp;
- X else
- X dirp->dd_contents = dirp->dd_cp = dp;
- X (void) strcpy(dp->_d_entry, s);
- X dp->_d_next = (struct _dircontents *) NULL;
- X } while ((s = getdirent((char *) NULL)) != (char *) NULL);
- X dirp->dd_cp = dirp->dd_contents;
- X
- X return dirp;
- X}
- X
- Xvoid
- Xclosedir(dirp)
- X DIR *dirp;
- X{
- X free_dircontents(dirp->dd_contents);
- X free((char *) dirp);
- X}
- X
- Xstruct direct *
- Xreaddir(dirp)
- X DIR *dirp;
- X{
- X static struct direct dp;
- X
- X if (dirp->dd_cp == (struct _dircontents *) NULL)
- X return (struct direct *) NULL;
- X dp.d_namlen = dp.d_reclen =
- X strlen(Strcpy(dp.d_name, dirp->dd_cp->_d_entry));
- X dp.d_ino = 0;
- X dirp->dd_cp = dirp->dd_cp->_d_next;
- X dirp->dd_loc++;
- X
- X return &dp;
- X}
- X
- Xvoid
- Xseekdir(dirp, off)
- X DIR *dirp;
- X long off;
- X{
- X long i = off;
- X struct _dircontents *dp;
- X
- X if (off < 0)
- X return;
- X for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
- X ;
- X dirp->dd_loc = off - (i + 1);
- X dirp->dd_cp = dp;
- X}
- X
- Xlong
- Xtelldir(dirp)
- X DIR *dirp;
- X{
- X return dirp->dd_loc;
- X}
- X
- Xstatic void
- Xfree_dircontents(dp)
- X struct _dircontents *dp;
- X{
- X struct _dircontents *odp;
- X
- X while (dp) {
- X if (dp->_d_entry)
- X free(dp->_d_entry);
- X dp = (odp = dp)->_d_next;
- X free((char *) odp);
- X }
- X}
- X
- Xstatic char *
- Xgetdirent(dir)
- X char *dir;
- X{
- X if (dir != (char *) NULL) { /* get first entry */
- X reg.h.ah = DOSI_FINDF;
- X reg.h.cl = ATTRIBUTES;
- X#if defined(M_I86LM)
- X reg.x.dx = FP_OFF(dir);
- X sreg.ds = FP_SEG(dir);
- X#else
- X reg.x.dx = (unsigned) dir;
- X#endif
- X } else { /* get next entry */
- X reg.h.ah = DOSI_FINDN;
- X#if defined(M_I86LM)
- X reg.x.dx = FP_OFF(dtapnt);
- X sreg.ds = FP_SEG(dtapnt);
- X#else
- X reg.x.dx = (unsigned) dtapnt;
- X#endif
- X }
- X#if defined(M_I86LM)
- X intdosx(®, &nreg, &sreg);
- X#else
- X intdos(®, &nreg);
- X#endif
- X if (nreg.x.cflag)
- X return (char *) NULL;
- X
- X return dtabuf.d_name;
- X}
- X
- Xstatic void
- Xsetdta()
- X{
- X reg.h.ah = DOSI_SDTA;
- X#if defined(M_I86LM)
- X reg.x.dx = FP_OFF(dtapnt);
- X sreg.ds = FP_SEG(dtapnt);
- X intdosx(®, &nreg, &sreg);
- X#else
- X reg.x.dx = (int) dtapnt;
- X intdos(®, &nreg);
- X#endif
- X}
- X
- Xstatic char *Strcpy(to,from)
- Xregister char *to,*from;
- X{
- X register int c;
- X char *start = to;
- X
- X while (*to++ = (islower(c = *from++) ? c : tolower(c)))
- X ;
- X return(start);
- X}
- X#endif
- END_OF_main/msd_dir.c
- if test 4738 -ne `wc -c <main/msd_dir.c`; then
- echo shar: \"main/msd_dir.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/screen.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/screen.h\"
- else
- echo shar: Extracting \"main/screen.h\" \(4726 characters\)
- sed "s/^X//" >main/screen.h <<'END_OF_main/screen.h'
- X/*++
- X/* NAME
- X/* screen
- X/* SUMMARY
- X/* structure of mail shell command windows
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* mail
- X/* SYNOPSIS
- X/* #include "screen.h"
- X/* DESCRIPTION
- X/* The data structures in this file are used by the interactive shell to
- X/* define what a screen looks like, and what commands the user can give.
- X/*
- X/* For each screen, one has to define a table of (selector, command name,
- X/* help string, and function pointer) tuples.
- X/* The command names are listed in the top window. If the user enters
- X/* the type of input specified by the selector, the associated function
- X/* is called. A null function pointer means go back to the calling screen.
- X/*
- X/* The table is terminated with a null selector entry; its help
- X/* string is displayed in the bottom window (as a prompt), and the
- X/* associated function is invoked upon entry of the screen.
- X/*
- X/* The return value of an action function determines what happens next.
- X/* An action function can signal an error condition, that the screen
- X/* needs to be redrawn, and whether the calling screen should terminate.
- X/*
- X/* User input can be of various forms: single-character, string or
- X/* escape/enter.
- X/*
- X/* In case of single-character input the selector fields should contain
- X/* for each key the (upper case) key code,
- X/* a label that is displayed at the top of the screen, and a help
- X/* text that explains the key's function.
- X/*
- X/* In case of string input the associated function is called with the
- X/* string input as argument. If that function returns an error status the
- X/* text in the help field is printed in the error window and the
- X/* user is given another chance.
- X/*
- X/* An alternative form of string input takes the text from the help field
- X/* as default input, and allows the user to edit that. Otherwise the
- X/* same functions are performed as with ordinary string input.
- X/*
- X/* A third form of string input only accepts yes or no. The action
- X/* function is called with an integer argument (1 = yes, 0 = no).
- X/*
- X/* In case of escape/enter the interpreter invokes the action function when
- X/* the user presses enter, and does nothing when escape is pressed.
- X/* .nf
- X
- X /* there is a Screen structure for each command for each screen */
- X
- Xtypedef struct {
- X short key; /* type of input */
- X char *name; /* key label (for top window) */
- X int (*action) (); /* action when command is selected */
- X char *help; /* explanation (for H command) */
- X} Screen;
- X
- X /* action function return masks */
- X
- X#define S_BREAK 1 /* return immediately after action */
- X#define S_REDRAW 2 /* redraw screen */
- X#define S_ERROR 4 /* action failed */
- X
- X /* input types: ordinary character keys are encoded as themselves */
- X
- X#define CTL(x) (x ^ 0100) /* ASCII control code */
- X#define BS CTL('H')
- X#define ENTER CTL('M')
- X#define CTLU CTL('U')
- X#define ESC CTL('[')
- X#define DEL CTL('?')
- X
- X#define ANY 256 /* press any key */
- X#define UP 257 /* up-arrow key */
- X#define DOWN 258 /* down-arrow key */
- X#define LEFT 259 /* left-arrow key */
- X#define RIGHT 260 /* right-arrow key */
- X#define PGUP 261 /* page-up */
- X#define PGDN 262 /* page-down */
- X#define STRING 263 /* string input, ESC to quit */
- X#define ESCCR 264 /* CR to confirm, ESC to quit */
- X#define EDIT 265 /* edit string, ESC to quit */
- X#define YESNO 266 /* yes or no, ESC to quit */
- X
- X#define iskey(key) (key > 0 && key < STRING)
- X
- X /* system-dependent function-key labels */
- X
- X#ifdef unix
- X# define PgUp "F1"
- X# define PgDn "F2"
- X#endif
- X
- X#ifdef MSDOS
- X# define PgUp "PgUp"
- X# define PgDn "PgDn"
- X#endif
- X
- X /* often-used strings and messages */
- X
- Xextern char anykey[]; /* Press any key to continue */
- Xextern char initscreen[]; /* Return to initial screen */
- Xextern char prevscreen[]; /* Return to previous screen */
- Xextern char int_error[]; /* The program is confused */
- Xextern char pageup[]; /* Move screen one page upwards */
- Xextern char pagedn[]; /* Move screen one page downwards */
- Xextern char csrup[]; /* Move cursor upwards */
- Xextern char csrdn[]; /* Move cursor downwards */
- Xextern char getsummary[]; /* Press ESC to cancel/give summary */
- Xextern char getaddr[]; /* Press ESC to cancel/enter address */
- Xextern char printcurr[]; /* Print current message */
- Xextern char delcurr[]; /* Delete current message */
- Xextern char *m_msgread[]; /* Cannot read that message */
- X
- X/* SEE ALSO
- X/* screen(3) screen table implementation
- X/* kbdinp(3) screen table interpreter
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Wed Apr 1 21:14:53 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* 90/01/22 13:02:34
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- END_OF_main/screen.h
- if test 4726 -ne `wc -c <main/screen.h`; then
- echo shar: \"main/screen.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/sendwork.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/sendwork.c\"
- else
- echo shar: Extracting \"main/sendwork.c\" \(4553 characters\)
- sed "s/^X//" >main/sendwork.c <<'END_OF_main/sendwork.c'
- X/*++
- X/* NAME
- X/* sendwork 3
- X/* SUMMARY
- X/* send local work to remote system
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* #include "work.h"
- X/*
- X/* void sendwork(wrk)
- X/* work *wrk;
- X/* DESCRIPTION
- X/* sendwork converts names and contents of local work files,
- X/* sends them to the remote system and deletes the files after
- X/* successfull transfer.
- X/*
- X/* In particular, it generates appropriate "From " lines at the
- X/* beginning of an outgoing mail message.
- X/* SEE ALSO
- X/* scanwork(3) locates work in the spool directory
- X/* DIAGNOSTICS
- X/* sendwork() returns via longjmp(systrap,errorcode) in case
- X/* of unrecoverable problems.
- X/*
- X/* The error codes are: E_CONFUSED (unexpected work type),
- X/* E_LOST (timed out), E_READERR (file read error).
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Thu Mar 26 11:32:23 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* 90/01/22 13:02:35
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- X
- X#include <stdio.h>
- X#include <time.h>
- X
- X#include "defs.h"
- X#include "work.h"
- X#include "logs.h"
- X#include "status.h"
- X#include "params.h"
- X#include "comm.h"
- X
- Xextern struct tm *localtime(); /* std C library */
- X
- X /*
- X * A pc-mail system can connect to the UNIX net in at least two modes:
- X *
- X * 1. As a real UUCP node, with it's own node name. This node name will have to
- X * appear in the "From " lines of outgoing mail. A consequence is that the
- X * pc mail node name should be known in mailer routing tables. Obviously
- X * this implies some administrative work when a pc mail node is added to the
- X * net or taken out of operation. This mode has not been tested by the
- X * author.
- X *
- X * 2. As an ordinary user. The program lets the UNIX host believe that mail
- X * messages come from an ordinary user. Recipients of mail will not be able
- X * to see that the mail came from the pc. Only the UNIX host knows it should
- X * forward mail for unixhost!xyz to the pc-mail node. This approach has the
- X * advantage that adding/deleting pc-mail nodes is simpler.
- X */
- X
- X#ifdef UUCP_NODE /* case 1 */
- X# define UUSER "root" /* use current user's name */
- X# define UHOST LOGIN_NAME /* use pc host name */
- X#else /* case 2 */
- X# define UUSER LOGIN_NAME /* use remote login name */
- X# define UHOST rmthost /* use remote host name */
- X#endif
- X
- X/* sendwork - adapt file contents for remote host */
- X
- Xpublic sendwork(wrk)
- Xwork *wrk;
- X{
- X long secs;
- X char buf[MAXLINE]; /* recipient addresses */
- X
- X switch (wrk->type) {
- X
- X /*
- X * Local D files contain the mail message. Except for the addition of
- X * a UUCP-style "From " line (with originator/date/system), D files
- X * are sent without modification.
- X */
- X
- X case 'd':
- X case 'D':
- X secs = time((long *) 0);
- X say(strcons("From %s %.24s remote from %s\n",
- X UUSER, asctime(localtime(&secs)), UHOST));
- X send_file(wrk->fp);
- X break;
- X
- X /*
- X * The first line of local X files contains the destination address.
- X * Real UUCP expects something entirely different.
- X *
- X * We make up some extra info to make the remote uuxqt program happy.
- X */
- X
- X case 'x':
- X case 'X':
- X say(strcons("U %s %s\n", UUSER, UHOST));/* U user system */
- X say(strcons("F %s\n",
- X rmtname('D', wrk->seqno))); /* F D.rmtsysGnumber */
- X say(strcons("I %s\n",
- X rmtname('D', wrk->seqno))); /* I D.rmtsysGnumber */
- X say("C rmail "); /* C rmail */
- X (void) fgets(buf, sizeof(buf), wrk->fp);/* read destinations */
- X say(buf); /* send destinations */
- X say(""); /* send EOF */
- X break;
- X
- X default:
- X trap(E_CONFUSED, "INTERNAL ERROR (unexpected work type: %c)", wrk->type);
- X }
- X}
- X
- X/* say - write string to host */
- X
- Xhidden say(str)
- Xchar *str;
- X{
- X if (CALL(Write) (ttfd, str, strlen(str)) < 0)
- X trap(E_LOST, "FAILED (link lost)");
- X}
- X
- X/* send_file - do the nitty-gritty of file transfer; traps on all errors */
- X
- Xhidden send_file(fp)
- Xregister FILE *fp;
- X{
- X register int nread;
- X register int nwrite = 0;
- X char buf[BUFSIZ];
- X register int rerror;
- X
- X while ((nread = fread(buf, sizeof(*buf), sizeof(buf), fp)) > 0
- X && (nwrite = CALL(Write) (ttfd, buf, nread)) == nread)
- X /* void */ ;
- X rerror = ferror(fp);
- X fclose(fp);
- X
- X if (rerror) {
- X trap(E_READERR, "FILE READ ERROR (%s)", sys_errlist[errno]);
- X /* NOTREACHED */
- X } else if (nwrite < 0 || CALL(Write) (ttfd, buf, 0) != 0) {
- X trap(E_LOST, "FAILED (link lost)");
- X /* NOTREACHED */
- X }
- X}
- END_OF_main/sendwork.c
- if test 4553 -ne `wc -c <main/sendwork.c`; then
- echo shar: \"main/sendwork.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/setup.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/setup.c\"
- else
- echo shar: Extracting \"main/setup.c\" \(4086 characters\)
- sed "s/^X//" >main/setup.c <<'END_OF_main/setup.c'
- X/*++
- X/* NAME
- X/* setup 3
- X/* SUMMARY
- X/* edit/display configuration parameters
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* mail
- X/* SYNOPSIS
- X/* #include "mail.h"
- X/*
- X/* int setup()
- X/* DESCRIPTION
- X/* The functions in this module handle the configurations file with
- X/* communications parameters.
- X/*
- X/* setup() starts a dialogue with the user. It allows the user to
- X/* select a parameter and enter a new value. All modifications are
- X/* done in core (pager file). Upon exit, the setup is written to
- X/* disk if any changes were made.
- X/* FUNCTIONS AND MACROS
- X/* open_pager(), app_pager(), gets_pager(), puts_pager()
- X/* kbdinp()
- X/* FILES
- X/* In the spool directory: the configuration file s00000.
- X/* SEE ALSO
- X/* cico(1) communications program.
- X/* DIAGNOSTICS
- X/* An error message if the setup file could not be created.
- X/* BUGS
- X/* Does not check parameter values at all, just like the UUCP
- X/* configurations files L.sys etcetera.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Wed Apr 8 15:16:18 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* 90/01/22 13:02:36
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- X
- X#include "defs.h"
- X#include "path.h"
- X#include "screen.h"
- X#include "mail.h"
- X#include "pager.h"
- X#include "params.h"
- X#include "status.h"
- X#include "window.h"
- X
- Xhidden void make_setup(); /* forward declarations */
- Xhidden int change_setup();
- Xhidden int pick_setup();
- Xhidden int show_setup();
- X
- Xhidden File *setfile = 0; /* memory! */
- Xhidden Info *prmtable = 0; /* more memory */
- Xhidden int chgflag = 0; /* more flags! */
- X
- Xhidden char setfmt[] = "%-20s %s"; /* display format */
- X#define LABLEN 20 /* length of first %s specifier */
- X
- X/* setup - start dialogue */
- X
- Xpublic int setup()
- X{
- X static Screen screen[] = {
- X 'C', "Close",0, prevscreen,
- X PGUP, PgUp, pu_pager, pageup,
- X PGDN, PgDn, pd_pager, pagedn,
- X UP, "Up", up_pager, csrup,
- X DOWN, "Down", dn_pager, csrdn,
- X ENTER, "Enter",pick_setup, "Modify selected parameter",
- X 0, 0, show_setup,
- X "Select communications parameter with cursor keys, then press ENTER",
- X };
- X
- X kbdinp(screen); /* start dialogue */
- X if (chgflag && cp_pager(parm_file())) { /* save setup if changed */
- X errdisp(E_WRITERR); /* save failed */
- X } else {
- X chgflag = 0; /* save succeeded */
- X }
- X close_pager(setfile);
- X setfile = 0;
- X return (S_REDRAW); /* refresh screen */
- X}
- X
- X/* show_setup - make setup display or use existing one */
- X
- Xhidden int show_setup()
- X{
- X if (setfile == 0 || prmtable == 0) { /* no setup display */
- X prmtable = getparams();
- X setfile = open_pager();
- X make_setup();
- X } else { /* use existing display */
- X set_pager(setfile);
- X }
- X ds_pager(); /* display it */
- X return (0);
- X}
- X
- X/* make_setup - create setup display */
- X
- Xhidden void make_setup()
- X{
- X register File *f = setfile;
- X register Info *i;
- X
- X for (i = prmtable; i->ident; i++)
- X app_pager(f, strcons(setfmt, i->ident, i->strval ? i->strval : ""));
- X}
- X
- X/* pick_setup - user has selected one parameter */
- X
- Xhidden int pick_setup()
- X{
- X static Screen screen[] = {
- X EDIT, 0, change_setup, 0,
- X 0, 0, 0,
- X "Press ESC to cancel. New parameter value:"
- X };
- X register char *sp = gets_pager();
- X register Info *ip;
- X
- X for (ip = prmtable; ip->ident; ip++) /* check id string */
- X if (strncmp(ip->ident, sp, ip->length) == 0)
- X break;
- X if (ip) {
- X screen->help = sp + LABLEN + 1; /* default is current value */
- X kbdinp(screen); /* ask for new value */
- X return (S_REDRAW);
- X } else {
- X beep(); /* bad id string */
- X return (0);
- X }
- X}
- X
- X/* change_setup - enter new communications parameter value */
- X
- Xhidden int change_setup(newval)
- Xchar *newval;
- X{
- X register char *sp = gets_pager(); /* read from display */
- X register Info *ip;
- X
- X for (ip = prmtable; ip->ident; ip++) { /* check id string */
- X if (strncmp(ip->ident, sp, ip->length) == 0) {
- X puts_pager(strcons(setfmt, ip->ident, newval));
- X chgflag = 1; /* say change made */
- X }
- X }
- X return (S_BREAK | S_REDRAW); /* screen changed */
- X}
- END_OF_main/setup.c
- if test 4086 -ne `wc -c <main/setup.c`; then
- echo shar: \"main/setup.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/switcher.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/switcher.c\"
- else
- echo shar: Extracting \"main/switcher.c\" \(4183 characters\)
- sed "s/^X//" >main/switcher.c <<'END_OF_main/switcher.c'
- X/*++
- X/* NAME
- X/* switcher 3
- X/* SUMMARY
- X/* master/slave protocol control switcher
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* cico
- X/* SYNOPSIS
- X/* int switcher(role)
- X/* int role;
- X/* DESCRIPTION
- X/* switcher() takes care of the high-level protocol on top of
- X/* the packet protocol.
- X/*
- X/* The system is in one of two roles: MASTER or SLAVE. In MASTER
- X/* mode (initial mode of the caller) a system scans its local
- X/* spool directory for work until no more is found, and then
- X/* sends a H (hangup) request. The slave will respond with HY
- X/* if it has no work, otherwise it will respond with HN and
- X/* the two systems switch roles.
- X/*
- X/* Work can be of the form of S (send) requests or R (receive)
- X/* requests. The slave responds with SY (RY) or SN (RN), depending on
- X/* whether it is willing to process the request. The recipient
- X/* of a message sends a CY or CN message, depending on whether
- X/* transmission was successfull.
- X/*
- X/* Only H(angup) and S(end) requests are implemented here. This is
- X/* for security reasons. Thus, the only way to exchange data is
- X/* through electronic mail.
- X/* FUNCTIONS AND MACROS
- X/* isok, talk(), hear(), trap(), scanwork(), sendwork()
- X/* rmtwork(), getwork()
- X/* DIAGNOSTICS
- X/* Various nonzero status codes are returned in case of problems.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Fri Mar 27 21:49:16 GMT+1:00 1987
- X/* LAST MODIFICATION
- X/* 90/01/22 13:02:45
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X
- X#include "defs.h"
- X#include "work.h"
- X#include "params.h"
- X#include "comm.h"
- X#include "logs.h"
- X#include "status.h"
- X
- X/* switcher - handles master/slave role swicthing until all work is done */
- X
- Xpublic switcher(role)
- Xregister int role;
- X{
- X int *savetrap = systrap;
- X jmp_buf mytrap;
- X int status;
- X
- X if (status = setjmp(systrap = mytrap)) {
- X systrap = savetrap; /* get here on fatal errors */
- X return (status);
- X }
- X /* switch roles until both ends out of work */
- X
- X while (role != DONE) {
- X switch (role) {
- X case MASTER:
- X role = master();
- X break;
- X case SLAVE:
- X role = slave();
- X break;
- X default:
- X trap(E_CONFUSED, "INTERNAL ERROR (unexpected role: %d)", role);
- X }
- X }
- X systrap = savetrap; /* no fatal errors */
- X return (0);
- X}
- X
- X/* master - process local work; when done, switch roles or finish */
- X
- Xhidden int master()
- X{
- X register work *wrk;
- X register char *resp;
- X
- X while (wrk = scanwork()) { /* scan for work */
- X log("REQUEST (%s)", wrk->rqst);
- X if (wrk->fp == 0) { /* check file exists */
- X log("CAN'T READ DATA (%s)", sys_errlist[errno]);
- X trap(E_SYSFAIL, "FAILED"); /* don\'t loop forever */
- X } else if (isok(wrk->rqst) == NO) { /* check xfer allowed */
- X log("PERMISSION (DENIED)");
- X trap(E_REJECT, "FAILED"); /* don\'t loop forever */
- X } else {
- X sendwork(wrk); /* adapt and send data */
- X log("REQUESTED (%s)", resp = hear());/* get remote status */
- X if (strcmp(resp, "CY")) /* check for sucessful */
- X trap(E_REJECT, "FAILED"); /* completion */
- X unlink(wrk->sent); /* just in case */
- X rename(wrk->path, wrk->sent); /* change status to "sent" */
- X }
- X }
- X
- X /* switch roles or finish if slave has no work */
- X
- X return (isok("H") == YES ? (talk("HY"), DONE) : SLAVE);
- X}
- X
- X/* slave - process remote work; accept H and S requests only */
- X
- Xhidden int slave()
- X{
- X register char *cmnd;
- X register work *wrk;
- X
- X for (;;) {
- X switch ((cmnd = hear())[0]) {
- X case 'S': /* master wants to send */
- X log("REQUESTED (%s)", cmnd); /* log the request */
- X wrk = rmtwork(cmnd); /* parse the request */
- X talk("SY"); /* say ok */
- X getwork(wrk); /* receive work */
- X talk("CY"); /* we never copy */
- X log("COPY (SUCCEEDED)");
- X break;
- X case 'H': /* master is out of work */
- X return (scanwork() ? (talk("HN"), MASTER) : (talk("HY"), DONE));
- X default:
- X talk(strcons("%cN", cmnd[0])); /* refuse other type of work */
- X break;
- X }
- X }
- X}
- END_OF_main/switcher.c
- if test 4183 -ne `wc -c <main/switcher.c`; then
- echo shar: \"main/switcher.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f main/unalias.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"main/unalias.c\"
- else
- echo shar: Extracting \"main/unalias.c\" \(4641 characters\)
- sed "s/^X//" >main/unalias.c <<'END_OF_main/unalias.c'
- X/*++
- X/* NAME
- X/* unalias 3
- X/* SUMMARY
- X/* alias processing
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* smail
- X/* SYNOPSIS
- X/* char **unalias(namevec)
- X/* char **namevec;
- X/* DESCRIPTION
- X/* unalias() takes an array of string pointers and returns a vector
- X/* with string pointers to their alias expansions. The resulting
- X/* vector is in static memory.
- X/*
- X/* After alias expansion, all addresses are sorted and duplicate
- X/* names are eliminated. The algorithms for alias expansion and
- X/* duplicate elimination are case-insensitive.
- X/*
- X/* unalias() accesses the alias data base through the ascf ASCII
- X/* filter.
- X/* DIAGNOSTICS
- X/* unalias() returns a null pointer in case of memory-allocation problems.
- X/*
- X/* unalias() terminates prematurely when the alias expansion has
- X/* produced BUFSIZ recipients. This provides some defense against
- X/* cycles in the alias data base. It is up to the caller to
- X/* recognize this condition.
- X/* BUGS
- X/* The overflow/cycle detection algorithm is inelegant.
- X/* FILES
- X/* Alias data base in spool directory
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Wed Apr 6 20:21:35 MET 1988
- X/* LAST MODIFICATION
- X/* 90/01/22 13:02:54
- X/* VERSION/RELEASE
- X/* 2.1
- X/*--*/
- X
- X#include "defs.h"
- X#include "hsearch.h"
- X#include "path.h"
- X#include "ascf.h"
- X
- X/* forward declarations */
- X
- Xhidden int hash_alias();
- Xhidden void sort_alias();
- Xhidden void uniq_alias();
- Xhidden char **find_alias();
- X
- X/* unalias - replace aliases by their equivalents */
- X
- Xpublic char **unalias(names)
- Xchar **names;
- X{
- X static int dohash = 1; /* hash table not yet made */
- X static char *recp[BUFSIZ + 1]; /* the result of alias expansion */
- X char **stop = recp + BUFSIZ; /* overflow limit */
- X
- X if (dohash && (dohash = hash_alias())) /* build the hash table */
- X return (0);
- X if (stop > find_alias(names, recp, stop)) { /* build vector of addresses */
- X sort_alias(recp); /* sort the recp list */
- X uniq_alias(recp); /* eliminate duplicates */
- X }
- X return (recp);
- X}
- X
- X/* hash_alias - copy alias data base to hash table */
- X
- Xhidden int hash_alias()
- X{
- X register FILE *fp;
- X char buf[BUFSIZ];
- X
- X /* initialize the hash table */
- X
- X if (hcreate(BUFSIZ) == 0)
- X return (-1);
- X
- X /*
- X * Lines in the alias data base are of the form
- X *
- X * <left-hand part> <right-hand part>
- X *
- X * where the l.h. part is an alias, and the r.h. part one or more words. Of
- X * course, those words can be aliases. The order in which aliases are
- X * defined is not important. The alias data base is used only after it
- X * has been loaded into memory.
- X *
- X * Each l.h. part is used as the key for finding the r.h. part in the hash
- X * table. The r.h. part is stored as a vector of pointers to strings.
- X */
- X
- X if (fp = ascopen(aliases(), "r")) { /* read through ASCII filter */
- X while (ascgets(buf, sizeof(buf), fp)) { /* read entry from alias file */
- X register char **cpp;
- X ENTRY e;
- X
- X if ((cpp = strvec(buf, ", \t\r\n")) == 0) /* split alias entry */
- X return (-1);
- X if ((e.key = *cpp) /* left-hand part exists */
- X &&(e.data = (char *) (cpp + 1)) /* right-hand part exists */
- X &&(hsearch(e, ENTER) == 0)) /* enter hash table */
- X return (-1);
- X }
- X ascclose(fp);
- X }
- X return (0);
- X}
- X
- X/* find_alias - recursively expand aliases */
- X
- Xhidden char **find_alias(from, to, stop)
- Xchar **from;
- Xregister char **to;
- Xregister char **stop;
- X{
- X register char **cpp;
- X register ENTRY *sp;
- X ENTRY e;
- X
- X /* recursively replace aliases, but don't crash in case of cycles */
- X
- X for (cpp = from; *cpp && (to < stop); cpp++) {
- X e.key = *cpp;
- X if (sp = hsearch(e, FIND)) {
- X to = find_alias((char **) sp->data, to, stop);
- X } else {
- X *to++ = *cpp;
- X }
- X }
- X *to = 0;
- X return (to);
- X}
- X
- X/* Istrcmp - interface between qsort and istrcmp */
- X
- Xhidden int Istrcmp(p1, p2)
- Xchar **p1,
- X **p2;
- X{
- X return (istrcmp(*p1, *p2));
- X}
- X
- X/* sort_alias - sort the addresses after alias substitutions */
- X
- Xhidden void sort_alias(to)
- Xchar **to;
- X{
- X register char **cpp;
- X int istrcmp();
- X
- X /* find out length of the list */
- X
- X for (cpp = to; *cpp; cpp++)
- X /* void */ ;
- X
- X /* sort the list */
- X
- X qsort((char *) to, cpp - to, sizeof(*to), Istrcmp);
- X}
- X
- X/* uniq_alias - collapse sequences of identical addresses */
- X
- Xhidden void uniq_alias(to)
- Xchar **to;
- X{
- X register char **in = to;
- X register char **out = to;
- X
- X while (*out = *in) {
- X while (*++in && istrcmp(*out, *in) == 0) {
- X /* void */ ;
- X }
- X ++out;
- X }
- X}
- END_OF_main/unalias.c
- if test 4641 -ne `wc -c <main/unalias.c`; then
- echo shar: \"main/unalias.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 4 \(of 11\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-
-