[mod.sources] v09i002: ELM Mail System, Part02/19

sources-request@mirror.UUCP (03/09/87)

Submitted by: Dave Taylor <hplabs!taylor>
Mod.sources: Volume 9, Issue 2
Archive-name: elm2/Part02

[  Yes, this is bigger than the News B2.11 distribution... --r$  ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If this archive is complete, you will see the message:
#		"End of archive 2 (of 19)."
# Contents:  NOTICE doc/elm.1 doc/elmrc-info doc/fastmail.1
#   doc/readmsg.1 filter/utils.c src/Makefile src/Makefile.mstr
#   src/args.c src/bounceback.c src/connect_to.c src/errno.c
#   src/fileio.c src/mkhdrs.c src/showmsg_cmd.c src/softkeys.c
#   utils/printmail.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"NOTICE\" \(2958 characters\)
if test -f NOTICE ; then 
  echo shar: Will not over-write existing file \"NOTICE\"
else
sed "s/^X//" >NOTICE <<'END_OF_NOTICE'
X
X                The Elm(tm) Mail System General Public License
X  		 
X
X		   	(C) Copyright 1986, Dave Taylor
X
X
X			  	COPYING POLICIES
X
X     Permission is hereby granted for copying and distribution of copies of
X  the Elm source files, and that of any part thereof, subject to the following 
X  license conditions:
X
X        1. You may without additional permission from the author, distribute 
X           Elm or components of Elm, with or without additions developed by 
X           you or by others at no charge.  You may also distribute Elm along 
X           with any other product for sale, provided that the cost of the 
X           bundled package is the same regardless of whether Elm is included,
X           and provided that those interested only in Elm must be notified 
X           that it is product freely available from the author.
X
X        2. Furthermore, if you distribute Elm software or parts of Elm, with 
X           or without additions developed by you or others, then you must 
X           either make available source of all portions of the Elm program 
X           (exclusive of any additions made by you or by others) upon request, 
X           or instead you may notify anyone requesting source that it is 
X           freely available from the author.
X
X        3. In addition, you may not omit any of the copyright notices
X           on either the source files, the executable file, or the 
X           documentation, and
X
X        4. Also, you may not omit transmission of this License agreement with 
X           whatever portions of Elm that are distributed.
X
X        5. Lastly, any users of this software must be notified that it is any 
X           without warrantee, or guarantee of any nature, express or implied, 
X           nor is there any fitness for use represented.
X
XSoftware is a malleable thing - especially Unix - and the author can in no
Xway guarantee that using this program will not cause grevious damage to your
Xsystem.  Of course this isn't anticipated, but if it does happen, the author
Xcannot be held liable for any damages either directly or indirectly caused
Xby this event.
X
XModification of the system is encouraged, providing that the portions of 
Xthe system that are from the original still carry the appropriate copyright
Xnotices and that the changed sections are clearly delimited as such.  The
Xauthor requests copies of any changes made to ensure that the various versions
Xstay reasonably in sync with each other.
X
XNOTE that it is not permitted to copy, sublicense distribute or transfer any
Xof the Elm software except as expressly indicated herein.  Any attempts to
Xdo otherwise will be considered a violation of this license and your rights
Xto the Elm software will be voided.
X
X
XComments on the system and/or this licensing agreement is encouraged.  Send
Xelectronic mail to "taylor@hplabs.HP.COM".  This license was written with
Xhelp from Scott McGregor.  Thanks Scott!
X
X
X----
XElm is a trademark of Dave Taylor. 
END_OF_NOTICE
if test 2958 -ne `wc -c <NOTICE`; then
    echo shar: \"NOTICE\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"doc/elm.1\" \(2799 characters\)
if test -f doc/elm.1 ; then 
  echo shar: Will not over-write existing file \"doc/elm.1\"
else
sed "s/^X//" >doc/elm.1 <<'END_OF_doc/elm.1'
X.TH ELM 1L 
X.ad b
X.SH NAME
Xelm - an interactive mail system
X.SH SYNOPSIS
X.B elm
X[
X.B \-achkKmrwz
X] [
X.B \-f
X<
X.B file
X>] [
X.B \-d
X<
X.B level
X>]
X.br
X.B elm 
X[
X.B \-s 
X<
X.B subject
X>] <
X.B "list of aliases or addresses"
X>
X.PP
X.SH HP-UX COMPATIBILITY
X.TP 10
XLevel:
XHP-UX/CONTRIBUTED
X.TP
XOrigin:
XHewlett-Packard
X.SH DESCRIPTION
X.I Elm\^
Xis a new interactive mailer program that supercedes 
X.I mail
Xand 
X.I mailx.
X.PP
XThere are three main ways to use the \fBelm\fR mailer; 
Xone way to use the mailer is to specify a list of addresses on the
Xcommand line when the mailer is invoked.  This will allow sending
Xof a single message to the specified recipients with all the
Xoptions usually available in the \fBelm\fR system itself.
X.PP
XThe second way, used most commonly when transmitting files and such,
Xis to specify the subject of the message and the recipients using
Xthe command line and redirect a file as standard input.  For example,
Xthe command 
X.nf
X
X	elm -s testing joe < test.c 
X
X.fi
Xwould mail a copy of the
Xfile test.c to alias joe, with the subject "testing" indicated.
X.PP
XOtherwise, the starting options are;
X.TP 1.0i
X.B "-a"
XArrow - force the arrow cursor (instead of the inverse bar)
X.TP
X.B "-c"
XCheckalias - expand the following aliases and return.
X.TP
X.B "-d <level>"
XDebug - set specified debug level - Output to "$HOME/Elm:debug.info"
X.TP
X.B "-f <file>"
XFile - read file (specified) rather than the incoming mailbox.
X.TP
X.B "-h"
XHelp - give a list of starting options.
X.TP
X.B "?"
XSynonymous with the "-h" option.
X.TP
X.B "-k"
XKeypad - force knowledge of HP terminal keyboard, to allow
Xthe use of the NEXT, PREV and HOME/SHIFT-HOME keys.
X.TP
X.B "-K"
XKeypad + softkeys - enable use of softkeys on HP terminals only.
X.TP
X.B "-m"
XMenu off - Use the extra lines for more message headers.
X.TP
X.B "-s"
XSubject - specify subject for message to mail.
X.TP
X.B "-z"
XZero - don't enter \fBElm\fR if no mail is pending.
X.SH AUTHOR
XDave Taylor, Hewlett-Packard Laboratories
X.SH SEE ALSO
X.I "Elm Users Guide", 
Xby Dave Taylor
X.sp
X.br
X.I "Elm Reference Guide"
Xby Dave Taylor
X.sp 
X.br
X.I "Elm Alias Users Guide"
Xby Dave Taylor
X.sp 
X.br
Xnewalias(1L), checkalias(1L), mail(1), mailx(1), from(1L), printmail(1L)
X.SH FILES
X/usr/local/bin/elm-help.main      help file
X.br
X/usr/mail/.alias_hash             system alias hash table
X.br
X/usr/mail/.alias_data             system alias data table
X.br
X$home/.alias_hash                 user alias hash table
X.br
X$home/.alias_data                 user alias data table
X.br
X/tmp/snd*                         outgoing mail edit buffer
X.br
X/tmp/mbox*                        temporary mailbox
X.br
X$HOME/ELM:debug.info              Debug output if turned on
X.SH DIAGNOSTICS
XShould know about keyboards/softkey terminals other than HP.  (If only 
Xtermcap were that powerful!)
END_OF_doc/elm.1
if test 2799 -ne `wc -c <doc/elm.1`; then
    echo shar: \"doc/elm.1\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"doc/elmrc-info\" \(2800 characters\)
if test -f doc/elmrc-info ; then 
  echo shar: Will not over-write existing file \"doc/elmrc-info\"
else
sed "s/^X//" >doc/elmrc-info <<'END_OF_doc/elmrc-info'
Xshell
X# The shell to use for shell escapes
X
Xfullname
X# The full user name for outbound mail
X
Xmaildir
X# where to save my mail to, default directory
X
Xmailbox
X# where to save messages to, default file
X
Xeditor
X# what editor to use (none = simulate Berkeley Mail)
X
Xsavemail
X# where to save mail if not specified somewhere else
X
Xcalendar
X# where to save calendar entries
X
Xsortby
X# and how to sort mailboxes, by default
X
Xprint
X# how to print a message ('%s' is the filename)
X
Xprefix
X# prefix sequence for including message text in other messages...
X
Xweedout
X# what headers I DON'T want to see, ever.
X
Xbounceback
X# threshold for bouncing copies of remote uucp messages...
X# zero = disable function.
X
Xtimeout
X# Set the main prompt timeout for resynching...
X
Xautocopy
X# automatically copy message being replied to into buffer? 
X
Xcopy
X# save a copy of all outbound messages? 
X
Xresolve
X# emulate the mailx message increment mode (only increment after something
X# has been 'done' to a message, either saved or deleted, as opposed to 
X# simply each time something is touched)
X
Xweed
X# enable the weedout list to be read...
X
Xnoheader
X# when messages are copied into the outbound buffer, don't include headers
X
Xtitles
X# display message title when displaying pages of message
X
Xeditout
X# edit the headers as the message leaves the machine (sort of)
X
Xsavename
X# save messages, incoming and outbound, by login name of sender/recipient
X
Xmovepage
X# when using the page commands (+ - <NEXT> <PREV>) change the current
X# message pointer...
X
Xpointnew
X# start up by pointing to the first new message received, if possible
X
Xsignature
X# ".signature" files to append to outbound messages...
X
Xlocalsignature
X# local ".signature" files to append to appropriate messages...
X
Xremotesignature
X# remote ".signature" files to append to appropriate messages...
X
Xalwaysleave
X# should we always leave messages as pending (change the default answer to yes)
X
Xalwaysdelete
X# should we always delete messages we've marked for deletion (change the
X# default answer to yes)
X
Xpager
X# program to use for displaying messages ('builtin' is recommended)
X
Xkeypad
X# we're running on an HP terminal and want HOME, PREV, NEXT, etc...
X
Xsoftkeys
X# we're running on an HP terminal and want softkeys available too!
X# (this implies "keypad=ON" too)
X
Xalternatives
X# alternative addresses that I could receive mail from (usually a
X# forwarding mailbox) and don't want to have listed...
X
Xforms
X# we might mail out AT&T Mail Forms
X
Xwarnings
X# tell us about addresses to machines we can't directly get to?
X
Xuserlevel
X# are we good at it?  0=beginner, 1=intermediate, 2+ = expert!
X
Xnames
X# let's just show the names, though, when expanding aliases...
X
Xarrow
X# should we use the "->" rather than the inverse video bar?
X
Xmenu
X# should we display the three-line menus?
END_OF_doc/elmrc-info
if test 2800 -ne `wc -c <doc/elmrc-info`; then
    echo shar: \"doc/elmrc-info\" unpacked with wrong size!?
fi
chmod +x doc/elmrc-info
# end of overwriting check
fi
echo shar: Extracting \"doc/fastmail.1\" \(3033 characters\)
if test -f doc/fastmail.1 ; then 
  echo shar: Will not over-write existing file \"doc/fastmail.1\"
else
sed "s/^X//" >doc/fastmail.1 <<'END_OF_doc/fastmail.1'
X.TH FASTMAIL 1L
X.ad b
X.SH NAME
Xfastmail - quick batch mail interface to a single address
X.SH SYNOPSIS
X.B fastmail
X[-b bcc-list] [-c cc-list] [-d] [-f fromname] [-r replyto] 
X[-s subject] filename address-list
X.br
X.SH HP-UX COMPATIBILITY
X.TP 10
XLevel:
XHP-UX/CONTRIBUTED
X.TP
XOrigin:
XHewlett-Packard
X.SH DESCRIPTION
X.I Fastmail
Xis a low-level interface to the mail system that allows batch
Xprocessing of mail.  It's intended for mailing to very large
Xgroups of people in a staggered fashion. 
X.PP
XThe starting options are;
X.TP 1.0i
X.B "-b bcc-list"
XThis allows a list of people to receive blind-carbon copies, or BCCs, of
Xthe message.  This list should be full email addresses.
X.TP
X.B "-c cc-list"
XThis allows a list of people to receive carbon copies, or CCs, of
Xthe message.  This list should be full email addresses.
X.TP
X.B "-d"
XDebug.  This is helpful for strange, unfriendly errors from
Xthe program (etc).
X.TP
X.B "-f from"
XThis overrides the users name in the From: line, so that if
Xthe user was x@y, and their name was MrX then the default 
XFrom: line would be "From: x@y (MrX)".  Using "-f Joe" when
Xinvoking this, though, would change it to "From: x@y (Joe)"
X.TP
X.B "-r replyto"
XOccasionally, you might send mail but want the replies to go
Xto a different address (very common with mailing lists).  
XThere is a header for this purpose called "Reply-To:" which
Xcan be utilized by using this starting option.  For example,
Xwe could send mail with a reply-to to list-request by
Xusing "-r list-request".  The header generated would then
Xbe of the form "Reply-To: list-request".
X.TP
X.B "-s subject"
XThe subject of the message is specified by using 
Xthis starting option.
X.SH EXAMPLE
XLet's say we're user "big" on machine "big-vax" and we have a
Xshell script called 'batch-mail' that contains the following
Xlines:
X.nf
X
X   #
X   # Batch Mail - batch mailing of a file to a LOT of users
X   #  
X   # Usage: batch-mail "from" "subject" filename
X
X   sender_copy = $LOGIN
X   replto = "The-Mr-Big-list"
X
X   fastmail -b $sender_copy -r $replyto -f "$1" -s "$2" $3 person1
X   sleep 10
X   fastmail -r $replyto -f "$1" -s "$2" $3 person2
X   sleep 10
X   fastmail -r $replyto -f "$1" -s "$2" $3 person3
X   sleep 10
X   fastmail -r $replyto -f "$1" -s "$2" $3 person4
X
X   < etc >
X
Xwith the invocation:
X
X   batch-mail "Mr. Big" "Warning to all" warning.text
X
X.fi
Xwould mail a copy of the 'warning.text' file to person1, person2, 
Xperson3, etc.  "$LOGIN" will also receive a copy of the first message
Xin the mail, \fIsilently\fR.  Each resultant message will include the headers:
X.nf
X
X    From: big-vax!big (Mr. Big)
X    Subject: Warning to all
X    Reply-To: The-Mr-Big-list
X
X.fi
XThis program should turn out to be considerably
Xfaster than the alternative methods of accomplishing this task.
X.SH FILES
X/usr/lib/sendmail       sendmail transport if available
X.br
X/bin/rmail              transport if no sendmail
X.br
X/tmp/fastmail.$$        temporary file 
X.SH AUTHOR
XDave Taylor, Hewlett-Packard Laboratories
X.SH SEE\ ALSO
Xsendmail(1), rmail(1), elm(1L)
END_OF_doc/fastmail.1
if test 3033 -ne `wc -c <doc/fastmail.1`; then
    echo shar: \"doc/fastmail.1\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"doc/readmsg.1\" \(3666 characters\)
if test -f doc/readmsg.1 ; then 
  echo shar: Will not over-write existing file \"doc/readmsg.1\"
else
sed "s/^X//" >doc/readmsg.1 <<'END_OF_doc/readmsg.1'
X.TH READMSG 1L
X.ad b
X.SH NAME
Xreadmsg - read messages from incoming mail
X.SH SYNOPSIS
X.B readmsg 
X[\fB-p\fR]
X[\fB-n\fR]
X[\fB-f filename\fR]
X[\fB-h\fR]
X.br
X.B readmsg
X[\fB-p\fR]
X[\fB-n\fR]
X[\fB-f filename\fR]
X[\fB-h\fR]
Xnumber [number ...]
X.br
X.B readmsg 
X[\fB-p\fR]
X[\fB-n\fR]
X[\fB-f filename\fR]
X[\fB-h\fR]
Xpattern
X.br
X.SH HP-UX COMPATIBILITY
X.TP 10
XLevel:
XHP-UX/CONTRIBUTED
X.TP
XOrigin:
XHewlett-Packard
X.SH DESCRIPTION
X.I Readmsg
Xis a program that gives the \fBElm\fR user the functionality of
Xthe mailx "~r" command from the editor of their choice.  There
Xare three different ways of using the program;
X.P
XFirst off, if you're actually creating a reply to a message
Xfrom within the \fBElm\fR system then \fIreadmsg\fR without any
Xarguments will include a summary of the headers and the body 
Xof the message being replied
Xto.  If you aren't currently editing a message the program will
Xreturn an error.
X.P
XSecondly, if you want to include certain messages, you can
Xspecify them by listing their ordinal locations in the 
Xmail file (that is, their "message numbers")
Xup to 25 at a time.  The \fImeta-\fRnumber '$' is understood to mean
Xthe last message in the mailfile.  Similarly, '*' is understood to
Xrepresent every message in the file (that is, 1-$)
X.P
XFinally, you can also specify a pattern that occurs in one of
Xthe messages as a way of including it.  This pattern can be
Xtyped in directly (no quotes) if the words are separated by a 
Xsingle space in the actual message.  The pattern matching is case
Xsensitive, so "Hello" and "hello" are NOT the same thing!!
X.sp
X.P
XThe \fB-f\fR flag indicates that you'd rather use the file specified
Xfor the operations specified rather than the default mailbox (see
Xthe way \fBElm\fR implements printing multiple messages for more
Xinformation on this...)
X.P
XThe \fB-h\fR flag instructs the program to include the entire header
Xof the matched message or messages when displaying their
Xtext.  (default is to display the From: Date: and Subject: lines
Xonly)
X.P
XThe \fB-n\fR flag instructs the program to exclude \fIall\fR
Xheaders.  This is used mostly for extracting files mailed and
Xsuch.
X.P
XFinally, the \fB-p\fR flag indicates that the program should
Xput form-feeds (control-L) between message headers.
X.sp
X.SH "EXAMPLES"
XFirst off, to use this from within \fBvi\fR to include the text of the 
Xcurrent message at the end of the current message, you could
Xuse the command;
X.nf
X
X	!!readmsg
X
X.fi
X(as you hit the 'G' the editor will put you at the bottom of the screen
Xwith the '!' prompt).
X.sp 2
XLet's look at something more interesting, however;
X.sp
XSuppose you have the mailfile;
X.nf
X
X   From joe Jun 3 1986 4:45:30 MST
X   Subject: hello
X   
X   Hey Guy!  Wanta go out and have a milk this evening?
X   
X   Joe
X   
X   From john Jun 3 1986 4:48:20 MST
X   Subject: Dinner at Eight
X   From: John Dinley <xyz!john>
X
X   Remember you should show up about eight, okay?
X
X		   - John D -
X
X   From xxzyz!cron Jun 3 1986 5:02:43 MST
X
X   Cannot connect to server: blob
X   Job 43243 deleted from queue.
X   
X.fi
XThe following commands will result in;
X.nf
X
X  $ readmsg 2		
X  [ display the second message, from John ]
X
X  $ readmsg 		
X  [ an error, unless we're calling from \fBElm\fR ]
X
X  $ readmsg BLOB	
X  [ no match - case sensitive! ]
X
X  $ readmsg -h connect to server 
X  [ displays third message, including headers ]
X
X.fi
X.SH FILES
X/usr/mail/<username>   		The incoming mail
X.br
X$home/.readmsg			The temp file from \fBElm\fR
X.SH AUTHOR
XDave Taylor, Hewlett-Packard Laboratories
X.SH SEE\ ALSO
Xnewmail(1L), Elm(1L)
X.SH BUGS
XThe '*' metacharacter doesn't always work as expected!
X.br
XPerhaps the pattern matching should be case insensitive?
END_OF_doc/readmsg.1
if test 3666 -ne `wc -c <doc/readmsg.1`; then
    echo shar: \"doc/readmsg.1\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"filter/utils.c\" \(2862 characters\)
if test -f filter/utils.c ; then 
  echo shar: Will not over-write existing file \"filter/utils.c\"
else
sed "s/^X//" >filter/utils.c <<'END_OF_filter/utils.c'
X/**			utils.c				**/
X
X/** Utility routines for the filter program...
X
X   (C) Copyright 1986, Dave Taylor
X**/
X
X#include <stdio.h>
X#include <pwd.h>
X#include <ctype.h>
X#include <fcntl.h>
X
X#include "defs.h"
X#include "filter.h"
X
Xleave(reason)
Xchar *reason;
X{
X	fprintf(stderr,"%sfilter (%s): LEAVE %s\n", BEEP, username, reason);
X	exit(1);
X}
X
Xlog(what)
Xint what;
X{
X	/** make an entry in the log files for the specified entry **/
X
X	FILE *fd;
X	char filename[SLEN];
X
X	if (! show_only) {
X	  sprintf(filename, "%s/%s", home, filtersum);	/* log action once! */
X	  if ((fd = fopen(filename, "a")) == NULL) {
X	    fprintf(stderr,"%sfilter (%s): Couldn't open log file %s\n", 
X		    BEEP, filename);
X	    fd = stdout;
X	  }
X	  fprintf(fd, "%d\n", rule_choosen);
X	  fclose(fd);
X	}
X
X	sprintf(filename, "%s/%s", home, filterlog);
X
X	if (show_only)
X	  fd = stdout;
X	else if ((fd = fopen(filename, "a")) == NULL) {
X	  fprintf(stderr,"%sfilter (%s): Couldn't open log file %s\n", 
X		  BEEP, filename);
X	  fd = stdout;
X	}
X	
X	setvbuf(fd, NULL, _IOFBF, BUFSIZ);
X
X	if (strlen(from) + strlen(subject) > 60)
X	  fprintf(fd, "\nMail from %s\n\tabout %s\n", from, subject);
X	else
X	  fprintf(fd, "\nMail from %s about %s\n", from, subject);
X
X	if (rule_choosen != -1)
X	  if (rules[rule_choosen].condition->matchwhat == TO)
X	    fprintf(fd, "\t(addressed to %s)\n", to);
X
X	switch (what) {
X	  case DELETE : fprintf(fd, "\tDELETED");			break;
X	  case SAVE   : fprintf(fd, "\tSAVED in file \"%s\"", 
X				rules[rule_choosen].argument2);		break;
X	  case SAVECC : fprintf(fd,"\tSAVED in file \"%s\" AND PUT in mailbox", 
X				rules[rule_choosen].argument2);  	break;
X	  case FORWARD: fprintf(fd, "\tFORWARDED to \"%s\"", 
X				rules[rule_choosen].argument2);		break;
X	  case EXEC   : fprintf(fd, "\tEXECUTED \"%s\"",
X				rules[rule_choosen].argument2);		break;
X	  case LEAVE  : fprintf(fd, "\tPUT in mailbox");		break;
X	}
X
X	if (rule_choosen != -1)
X	  fprintf(fd, " by rule #%d\n", rule_choosen+1);
X	else
X	  fprintf(fd, ": the default action\n");
X
X	fflush(fd);
X	fclose(fd);
X}
X
Xint
Xcontains(string, pattern)
Xchar *string, *pattern;
X{
X	/** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/ 
X
X	register int i = 0, j = 0;
X
X	while (string[i] != '\0') {
X	  while (tolower(string[i++]) == tolower(pattern[j++])) 
X	    if (pattern[j] == '\0') 
X	      return(TRUE);
X	  i = i - j + 1;
X	  j = 0;
X	}
X	return(FALSE);
X}
X
Xchar *itoa(i, two_digit)
Xint i, two_digit;
X{	
X	/** return 'i' as a null-terminated string.  If two-digit use that
X	    size field explicitly!  **/
X
X	static char value[10];
X	
X	if (two_digit)
X	  sprintf(value, "%02d", i);
X	else
X	  sprintf(value, "%d", i);
X
X	return( (char *) value);
X}
X
Xlowercase(string)
Xchar *string;
X{
X	/** translate string into all lower case **/
X
X	register int i;
X
X	for (i=0; i < strlen(string); i++)
X	  if (isupper(string[i]))
X	    string[i] = tolower(string[i]);
X}
END_OF_filter/utils.c
if test 2862 -ne `wc -c <filter/utils.c`; then
    echo shar: \"filter/utils.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/Makefile\" \(2597 characters\)
if test -f src/Makefile ; then 
  echo shar: Will not over-write existing file \"src/Makefile\"
else
sed "s/^X//" >src/Makefile <<'END_OF_src/Makefile'
X#
X#  Makefile for the ELM mail program.
X#
X#         (C) Copyright 1986, Dave Taylor
X#
X#  Last modification: August 15th, 1986
X
XSHELL=/bin/sh
X
XDEFINE= -DBSD
XLIB2  = -lcurses
X
X# IF you're on an ACSnet system (Australia) then
X# you'll want to uncomment the following;
X
X#   DEFINE= ${DEFINE} -DACSNET
X
X##############################
X
XCFILES=	addr_utils.c alias.c aliasdb.c aliaslib.c args.c bounceback.c 	\
X	builtin.c calendar.c connect_to.c curses.c date.c delete.c	\
X	domains.c edit.c editmsg.c elm.c encode.c errno.c file.c	\
X	file_utils.c fileio.c forms.c getopt.c hdrconfg.c help.c	\
X	initialize.c input_utils.c leavembox.c limit.c mailmsg1.c	\
X	mailmsg2.c mailtime.c mkhdrs.c newmbox.c opt_utils.c options.c	\
X	output_utils.c pattern.c pmalloc.c quit.c read_rc.c remail.c	\
X	reply.c return_addr.c savecopy.c screen.c showmsg.c signals.c	\
X	softkeys.c sort.c string2.c strings.c syscall.c utils.c		\
X	save_opts.c validname.c
X
XHEADERS=../hdrs/curses.h ../hdrs/defs.h ../hdrs/headers.h ../hdrs/sysdefs.h
X
XOBJS  =	addr_utils.o alias.o aliasdb.o aliaslib.o args.o bounceback.o 	\
X	builtin.o calendar.o connect_to.o curses.o date.o delete.o	\
X	domains.o edit.o editmsg.o elm.o encode.o errno.o file.o	\
X	file_utils.o fileio.o forms.o getopt.o hdrconfg.o help.o	\
X	initialize.o input_utils.o leavembox.o limit.o mailmsg1.o	\
X	mailmsg2.o mailtime.o mkhdrs.o newmbox.o opt_utils.o options.o	\
X	output_utils.o pattern.o pmalloc.o quit.o read_rc.o remail.o	\
X	reply.o return_addr.o savecopy.o screen.o showmsg.o signals.o	\
X	softkeys.o sort.o string2.o strings.o syscall.o utils.o		\
X	save_opts.o validname.o
X
XBIN=    ../bin
XLIBS=   -ltermcap
XCFLAGS= -O -I../hdrs
XCC=	/bin/cc
XRM=	/bin/rm -f
X
X../bin/elm: ${OBJS} ${EXTRA} ${HEADERS} ../hdrs/elm.h
X	${CC} -o ${BIN}/elm -n ${OBJS} ${LIBS} ${LIB2}
X
X.c.o:   ${HEADERS}
X	${CC} -c ${CFLAGS} ${DEFINE} $*.c 
X
Xcurses.o: curses.c ../hdrs/curses.h
X	${CC} -c ${CFLAGS} -DRAWMODE ${DEFINE} curses.c
X
X# curses.c : curses.q
X# 	@../bin/quickscreen curses.q
X#
X# curses.q :
X# 	@cp curses.c curses.q
X
Xclean:
X	${RM} ${OBJS} LINT.OUT ../bin/elm 
X
Xlint: LINT.OUT
X
XLINT.OUT: ${CFILES}
X	lint -DRAWMODE -I../hdrs ${CFILES} -ltermcap > LINT.OUT
X
Xlisting: LISTING
X
XLISTING: Makefile INDEX ${HEADERS} ${CFILES}
X	@echo adding file 'Makefile'...
X	@/bin/echo \\f > LISTING
X	@cat Makefile >> LISTING
X	@echo adding file 'INDEX'...
X	@/bin/echo \\f >> LISTING
X	@cat INDEX >> LISTING
X	@../bin/makelisting ${HEADERS} ${CFILES}
X	@echo LISTING generated.
X
Xindex: INDEX
X
XINDEX: ${CFILES} ${HEADERS}
X	@echo Creating function definition index
X	@index *.c | sort > INDEX
X	@echo File INDEX generated
END_OF_src/Makefile
if test 2597 -ne `wc -c <src/Makefile`; then
    echo shar: \"src/Makefile\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/Makefile.mstr\" \(2589 characters\)
if test -f src/Makefile.mstr ; then 
  echo shar: Will not over-write existing file \"src/Makefile.mstr\"
else
sed "s/^X//" >src/Makefile.mstr <<'END_OF_src/Makefile.mstr'
X#
X#  Makefile for the ELM mail program.
X#
X#         (C) Copyright 1986, Dave Taylor
X#
X#  Last modification: August 15th, 1986
X
XSHELL=/bin/sh
X
XDEFINE= >os-define<
XLIB2  = >lib2<
X
X# IF you're on an ACSnet system (Australia) then
X# you'll want to uncomment the following;
X
X#   DEFINE= ${DEFINE} -DACSNET
X
X##############################
X
XCFILES=	addr_utils.c alias.c aliasdb.c aliaslib.c args.c bounceback.c 	\
X	builtin.c calendar.c connect_to.c curses.c date.c delete.c	\
X	domains.c edit.c editmsg.c elm.c encode.c errno.c file.c	\
X	file_utils.c fileio.c forms.c getopt.c hdrconfg.c help.c	\
X	initialize.c input_utils.c leavembox.c limit.c mailmsg1.c	\
X	mailmsg2.c mailtime.c mkhdrs.c newmbox.c opt_utils.c options.c	\
X	output_utils.c pattern.c pmalloc.c quit.c read_rc.c remail.c	\
X	reply.c return_addr.c savecopy.c screen.c showmsg.c signals.c	\
X	softkeys.c sort.c string2.c strings.c syscall.c utils.c		\
X	save_opts.c validname.c
X
XHEADERS=../hdrs/curses.h ../hdrs/defs.h ../hdrs/headers.h ../hdrs/sysdefs.h
X
XOBJS  =	addr_utils.o alias.o aliasdb.o aliaslib.o args.o bounceback.o 	\
X	builtin.o calendar.o connect_to.o curses.o date.o delete.o	\
X	domains.o edit.o editmsg.o elm.o encode.o errno.o file.o	\
X	file_utils.o fileio.o forms.o getopt.o hdrconfg.o help.o	\
X	initialize.o input_utils.o leavembox.o limit.o mailmsg1.o	\
X	mailmsg2.o mailtime.o mkhdrs.o newmbox.o opt_utils.o options.o	\
X	output_utils.o pattern.o pmalloc.o quit.o read_rc.o remail.o	\
X	reply.o return_addr.o savecopy.o screen.o showmsg.o signals.o	\
X	softkeys.o sort.o string2.o strings.o syscall.o utils.o		\
X	save_opts.o validname.o
X
XBIN=    ../bin
XLIBS=   >libs<
XCFLAGS= -O -I../hdrs
XCC=	>cc<
XRM=	>rm<
X
X../bin/elm: ${OBJS} ${EXTRA} ${HEADERS} ../hdrs/elm.h
X	${CC} -o ${BIN}/elm -n ${OBJS} ${LIBS} ${LIB2}
X
X.c.o:   ${HEADERS}
X	${CC} -c ${CFLAGS} ${DEFINE} $*.c 
X
Xcurses.o: curses.c ../hdrs/curses.h
X	${CC} -c ${CFLAGS} -DRAWMODE ${DEFINE} curses.c
X
X# curses.c : curses.q
X# 	@../bin/quickscreen curses.q
X#
X# curses.q :
X# 	@cp curses.c curses.q
X
Xclean:
X	${RM} ${OBJS} LINT.OUT ../bin/elm 
X
Xlint: LINT.OUT
X
XLINT.OUT: ${CFILES}
X	lint -DRAWMODE -I../hdrs ${CFILES} -ltermcap > LINT.OUT
X
Xlisting: LISTING
X
XLISTING: Makefile INDEX ${HEADERS} ${CFILES}
X	@echo adding file 'Makefile'...
X	@/bin/echo \\f > LISTING
X	@cat Makefile >> LISTING
X	@echo adding file 'INDEX'...
X	@/bin/echo \\f >> LISTING
X	@cat INDEX >> LISTING
X	@../bin/makelisting ${HEADERS} ${CFILES}
X	@echo LISTING generated.
X
Xindex: INDEX
X
XINDEX: ${CFILES} ${HEADERS}
X	@echo Creating function definition index
X	@index *.c | sort > INDEX
X	@echo File INDEX generated
END_OF_src/Makefile.mstr
if test 2589 -ne `wc -c <src/Makefile.mstr`; then
    echo shar: \"src/Makefile.mstr\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/args.c\" \(2975 characters\)
if test -f src/args.c ; then 
  echo shar: Will not over-write existing file \"src/args.c\"
else
sed "s/^X//" >src/args.c <<'END_OF_src/args.c'
X/**			args.c			**/
X
X/** starting argument parsing routines for ELM system...
X
X    (C) Copyright 1986 Dave Taylor
X**/
X
X#include "headers.h"
X
X#define DONE		0
X#define ERROR		-1
X
Xextern char *optional_arg;		/* optional argument as we go */
Xextern int   opt_index;			/* argnum + 1 when we leave   */
X
Xvoid exit();	/* just keeping lint happy.... */
X
Xparse_arguments(argc, argv, to_whom)
Xint argc;
Xchar *argv[], *to_whom;
X{
X	/** Set flags according to what was given to program.  If we are 
X	    fed a name or series of names, put them into the 'to_whom' buffer
X	    and set "mail_only" to TRUE **/
X
X	register int c = 0, check_size = 0;
X	char *strcpy();
X
X	infile[0] = '\0';
X	to_whom[0] = '\0';
X	batch_subject[0] = '\0';
X
X	while ((c = get_options(argc, argv, "?acd:f:hkKms:wz")) > 0) {
X	   switch (c) {
X	     case 'a' : arrow_cursor++;		break;
X	     case 'c' : check_only++;		break;
X	     case 'd' : debug = atoi(optional_arg);	break;
X	     case 'f' : strcpy(infile, optional_arg); 
X	                mbox_specified = 2;  break;
X	     case '?' :
X	     case 'h' : args_help();
X	     case 'k' : hp_terminal++;	break;
X	     case 'K' : hp_terminal++; hp_softkeys++;	break;
X	     case 'm' : mini_menu = 0;	break;
X	     case 's' : strcpy(batch_subject, optional_arg);	break;
X	     case 'w' : warnings = 0;	break;
X	     case 'z' : check_size++;   break;
X	    }
X	 }
X
X	 if (c == ERROR) {
X	   printf(
X          "Usage: %s [achkKmwz] [-d level] [-f file] [-s subject] <names>\n\n",
X	     argv[0]);
X	   args_help();
X	}
X
X	if (opt_index < argc) {
X	  while (opt_index < argc) {
X	    sprintf(to_whom, "%s%s%s", to_whom, 
X	            to_whom[0] != '\0'? " " : "", argv[opt_index]);
X	    mail_only++;
X	    opt_index++;
X	  }
X	  check_size = 0;	/* NEVER do this if we're mailing!! */
X	}
X
X	 if (strlen(batch_subject) > 0 && ! mail_only) 
X	   exit(printf(
X     "\n\rDon't understand specifying a subject and no-one to send to!\n\r"));
X
X	if (!isatty(fileno(stdin)) && strlen(batch_subject) == 0 && !check_only)
X	  strcpy(batch_subject, DEFAULT_BATCH_SUBJECT);
X
X	if (check_size)
X	  check_mailfile_size();
X}
X
Xargs_help()
X{
X	/**  print out possible starting arguments... **/
X
X	printf("\nPossible Starting Arguments for ELM program:\n\n");
X	printf("\targ\t\t\tMeaning\n");
X	printf("\t -a \t\tArrow - use the arrow pointer regardless\n");
X	printf("\t -c \t\tCheckalias - check the given aliases only\n");
X	printf("\t -dn\t\tDebug - set debug level to 'n'\n");
X	printf("\t -fx\t\tFile - read file 'x' rather than mailbox\n");
X	printf("\t -h \t\tHelp - give this list of options\n");
X	printf("\t -k \t\tKeypad - enable HP 2622 terminal keyboard\n");
X	printf("\t -K \t\tKeypad&softkeys - enable use of softkeys + \"-k\"\n");
X	printf("\t -m \t\tMenu - Turn off menu, using more of the screen\n");
X	printf("\t -sx\t\tSubject 'x' - for batchmailing\n");
X	printf("\t -w \t\tSupress warning messages...\n");
X	printf("\t -z \t\tZero - don't enter Elm if no mail is pending\n");
X	printf("\n");
X	printf("\n");
X	exit(1);
X}
END_OF_src/args.c
if test 2975 -ne `wc -c <src/args.c`; then
    echo shar: \"src/args.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/bounceback.c\" \(2525 characters\)
if test -f src/bounceback.c ; then 
  echo shar: Will not over-write existing file \"src/bounceback.c\"
else
sed "s/^X//" >src/bounceback.c <<'END_OF_src/bounceback.c'
X/**			bounceback.c			**/
X
X/** This set of routines implement the bounceback feature of the mailer.
X    This feature allows mail greater than 'n' hops away (n specified by
X    the user) to have a 'cc' to the user through the remote machine.  
X
X    Due to the vagaries of the Internet addressing (uucp -> internet -> uucp)
X    this will NOT generate bounceback copies with mail to an internet host!
X
X    (C) Copyright 1986 by Dave Taylor
X**/
X
X#include "headers.h"
X
Xchar *bounce_off_remote(),		/* forward declaration */
X     *strcat(), *strcpy();
X
Xint
Xuucp_hops(to)
Xchar *to;
X{	
X	/** Given the entire "To:" list, return the number of hops in the
X	    first address (a hop = a '!') or ZERO iff the address is to a
X  	    non uucp address.
X	**/
X
X	register int hopcount = 0, index;
X
X	for (index = 0; ! whitespace(to[index]) && to[index] != '\0'; index++) {
X	  if (to[index] == '!')
X	    hopcount++;
X	  else if (to[index] == '@' || to[index] == '%' || to[index] == ':')
X	    return(0);	/* don't continue! */
X	}
X
X	return(hopcount);
X}
X	
Xchar *bounce_off_remote(to)
Xchar *to;
X{
X	/** Return an address suitable for framing (no, that's not it...)
X	    Er, suitable for including in a 'cc' line so that it ends up
X	    with the bounceback address.  The method is to take the first 
X	    address in the To: entry and break it into machines, then 
X	    build a message up from that.  For example, consider the
X	    following address:
X			a!b!c!d!e!joe
X	    the bounceback address would be;
X			a!b!c!d!e!d!c!b!a!ourmachine!ourname
X	    simple, eh?
X	**/
X
X	static char address[LONG_STRING];	/* BEEG address buffer! */
X
X	char   host[MAX_HOPS][SHORT_SLEN];	/* for breaking up addr */
X	register int hostcount = 0, hindex = 0, 
X	       index;
X
X	for (index = 0; !whitespace(to[index]) && to[index] != '\0'; index++) {
X	  if (to[index] == '!') {
X	    host[hostcount][hindex] = '\0';
X	    hostcount++;
X	    hindex = 0;
X	  }
X	  else 
X	    host[hostcount][hindex++] = to[index];
X	}
X
X	/* we have hostcount hosts... */
X
X	strcpy(address, host[0]);	/* initialize it! */
X
X	for (index=1; index < hostcount; index++) {
X	  strcat(address, "!");
X	  strcat(address, host[index]);
X	}
X	
X	/* and now the same thing backwards... */
X
X	for (index = hostcount -2; index > -1; index--) {
X	  strcat(address, "!");
X	  strcat(address, host[index]);
X	}
X
X	/* and finally, let's tack on our machine and login name */
X
X	strcat(address, "!");
X	strcat(address, hostname);
X	strcat(address, "!");
X	strcat(address, username);
X
X	/* and we're done!! */
X
X	return( (char *) address );
X}
END_OF_src/bounceback.c
if test 2525 -ne `wc -c <src/bounceback.c`; then
    echo shar: \"src/bounceback.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/connect_to.c\" \(3860 characters\)
if test -f src/connect_to.c ; then 
  echo shar: Will not over-write existing file \"src/connect_to.c\"
else
sed "s/^X//" >src/connect_to.c <<'END_OF_src/connect_to.c'
X/**			connect_to.c			**/
X
X/** This contains the routine(s) needed to have the Elm mailer figure
X    out what machines the current machine can talk to.   This can be
X    done in one of two ways - either the program can read the L.sys
X    file, or (if it fails or "UUNAME" define is present) will invoke
X    uuname to a file, then read the file in!
X
X    (C) Copyright Dave Taylor, 1986
X**/
X
X#include "headers.h"
X
Xchar *strcpy();
X
Xstruct lsys_rec *pmalloc(); 
X
Xget_connections()
X{
X
X	/** get the direct connections that this machine has, by hook
X	    or by crook (so to speak) 
X	**/
X
X#ifndef USE_UUNAME
X	FILE *lsysfile;
X	char  buffer[SLEN], sysname[NLEN];
X	struct lsys_rec *system_record, *previous_record;
X	int    loc_on_line;
X
X	previous_record = NULL;
X	if ((lsysfile = fopen(Lsys,"r")) == NULL) {
X	  dprint1(1, "Warning: Can't open L.sys file %s (read_lsys)\n", Lsys);
X#endif
X
X	  if (read_uuname() == -1) {
X	    error("Warning: couldn't figure out system connections...");
X	    talk_to_sys = NULL;
X	  }
X
X#ifndef USE_UUNAME
X	  /** ELSE: already read in uuname() output if we're here!! **/
X	  return;
X	}
X
X	while (fgets(buffer, SLEN, lsysfile) != NULL) {
X	  sscanf(buffer,"%s", sysname);
X
X	  if (previous_record == NULL) {
X	    dprint1(2, "L.sys\tdirect connection to %s, ", sysname);
X	    loc_on_line = 30 + strlen(sysname);  
X	    previous_record = pmalloc(sizeof *talk_to_sys);
X
X	    strcpy(previous_record->name, sysname);
X	    previous_record->next = NULL;
X	    talk_to_sys = previous_record;
X	  }
X	  else if (! talk_to(sysname) && sysname[0] != '#') {
X	    if (loc_on_line + strlen(sysname) > 80) {
X	      dprint0(2, "\n\t");
X	      loc_on_line = 8;
X	    }
X	    dprint1(2, "%s, ", sysname);
X	    loc_on_line += (strlen(sysname) + 2);
X	    system_record = pmalloc(sizeof *talk_to_sys);
X	  
X	    strcpy(system_record->name, sysname);
X	    system_record->next = NULL;
X	    previous_record->next = system_record;
X	    previous_record = system_record;
X	  }
X	}
X
X	fclose(lsysfile);
X
X	if (loc_on_line != 8)
X	  dprint0(2, "\n");
X
X	dprint0(2, "\n");			/* for a nice format! Yeah! */
X#endif
X}
X
Xint
Xread_uuname()
X{
X	/** This routine trys to use the uuname routine to get the names of
X	    all the machines that this machine connects to...it returns
X	    -1 on failure.
X	**/
X
X	FILE *fd;
X	char  buffer[SLEN], filename[SLEN];
X	struct lsys_rec *system_record, *previous_record;
X	int   loc_on_line;
X
X	sprintf(filename, "%s%d", temp_uuname, getpid());
X	sprintf(buffer,"%s > %s", uuname, filename);
X
X	if (system_call(buffer, SH) != 0) {
X	  dprint0(1, "Can't get uuname info - system call failed!\n");
X	  unlink(filename);	/* insurance */
X	  return(-1);
X	}
X	
X	if ((fd = fopen(filename, "r")) == NULL) {
X	  dprint1(1, "Can't get uuname info - can't open file %s for reading\n",
X		   filename);
X	  unlink(filename);	/* insurance */
X	  return(-1);
X	}
X	
X	previous_record = NULL;
X
X	while (fgets(buffer, SLEN, fd) != NULL) {
X	  no_ret(buffer);
X	  if (previous_record == NULL) {
X	    dprint1(2, "uuname\tdirect connection to %s, ", buffer);
X	    loc_on_line = 30 + strlen(buffer);
X	    previous_record = pmalloc(sizeof *talk_to_sys);
X
X	    strcpy(previous_record->name, buffer);
X	    previous_record->next = NULL;
X	    talk_to_sys = previous_record;
X	  }
X	  else {	/* don't have to check uniqueness - uuname does that! */
X	    if (loc_on_line + strlen(buffer) > 80) {
X	      dprint0(2, "\n\t");
X	      loc_on_line = 8;
X	    }
X	    dprint1(2, "%s, ", buffer);
X	    loc_on_line += (strlen(buffer) + 2);
X	    system_record = pmalloc(sizeof *talk_to_sys);
X	  
X	    strcpy(system_record->name, buffer);
X	    system_record->next = NULL;
X	    previous_record->next = system_record;
X	    previous_record = system_record;
X	  }
X	}
X
X	fclose(fd);
X
X	(void) unlink(filename);		/* kill da temp file!! */
X
X	dprint0(2, "\n");			/* for a nice format! Yeah! */
X
X	return(0);				/* it all went okay... */
X}
END_OF_src/connect_to.c
if test 3860 -ne `wc -c <src/connect_to.c`; then
    echo shar: \"src/connect_to.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/errno.c\" \(2500 characters\)
if test -f src/errno.c ; then 
  echo shar: Will not over-write existing file \"src/errno.c\"
else
sed "s/^X//" >src/errno.c <<'END_OF_src/errno.c'
X/**		errno.c			**/
X
X/** This routine maps error numbers to error names and error messages.
X    These are all directly ripped out of the include file errno.h, and
X    are HOPEFULLY standardized across the different breeds of Unix!!
X
X    If (alas) yours are different, you should be able to use awk to
X    mangle your errno.h file quite simply...
X
X   (C) Copyright 1986 Dave Taylor
X**/
X
X#include "headers.h"
X
Xchar *err_name[] = { 
X/* 0 */	        "NOERROR", "No error status currently",
X/* 1 */		"EPERM",   "Not super-user",
X/* 2 */		"ENOENT",  "No such file or directory",
X/* 3 */		"ESRCH",   "No such process",
X/* 4 */		"EINTR",   "Interrupted system call",
X/* 5 */		"EIO",     "I/O error",
X/* 6 */		"ENXIO",   "No such device or address",
X/* 7 */		"E2BIG",   "Arg list too long",
X/* 8 */		"ENOEXEC", "Exec format error",
X/* 9 */		"EBADF",   "Bad file number",
X/* 10 */	"ECHILD",  "No children",
X/* 11 */	"EAGAIN",  "No more processes",
X/* 12 */	"ENOMEM",  "Not enough core",
X/* 13 */	"EACCES",  "Permission denied",
X/* 14 */	"EFAULT",  "Bad address",
X/* 15 */	"ENOTBLK", "Block device required",
X/* 16 */	"EBUSY",   "Mount device busy",
X/* 17 */	"EEXIST",  "File exists",
X/* 18 */	"EXDEV",   "Cross-device link",
X/* 19 */	"ENODEV",  "No such device",
X/* 20 */	"ENOTDIR", "Not a directory",
X/* 21 */	"EISDIR",  "Is a directory",
X/* 22 */	"EINVAL",  "Invalid argument",
X/* 23 */	"ENFILE",  "File table overflow",
X/* 24 */	"EMFILE",  "Too many open files",
X/* 25 */	"ENOTTY",  "Not a typewriter",
X/* 26 */	"ETXTBSY", "Text file busy",
X/* 27 */	"EFBIG",   "File too large",
X/* 28 */	"ENOSPC",  "No space left on device",
X/* 29 */	"ESPIPE",  "Illegal seek",
X/* 30 */	"EROFS",   "Read only file system",
X/* 31 */	"EMLINK",  "Too many links",
X/* 32 */	"EPIPE",   "Broken pipe",
X/* 33 */	"EDOM",    "Math arg out of domain of func",
X/* 34 */	"ERANGE",  "Math result not representable",
X/* 35 */	"ENOMSG",  "No message of desired type",
X/* 36 */	"EIDRM",   "Identifier removed"
X	};
X
Xchar *strcpy();
X
Xchar *error_name(errnumber)
Xint errnumber;
X{
X	static char buffer[50];
X
X	if (errnumber < 0 || errnumber > 36) 
X	  sprintf(buffer,"ERR-UNKNOWN (%d)", errnumber);
X	else
X	  strcpy(buffer, err_name[2*errnumber]);
X
X	return( (char *) buffer);
X}
X
Xchar *error_description(errnumber)
Xint errnumber;
X{
X	static char buffer[50];
X
X	if (errnumber < 0 || errnumber > 36) 
X	  sprintf(buffer,"Unknown error - %d - No description", errnumber);
X	else
X	  strcpy(buffer, err_name[2*errnumber + 1]);
X
X	return ( (char *) buffer);
X}
END_OF_src/errno.c
if test 2500 -ne `wc -c <src/errno.c`; then
    echo shar: \"src/errno.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/fileio.c\" \(3020 characters\)
if test -f src/fileio.c ; then 
  echo shar: Will not over-write existing file \"src/fileio.c\"
else
sed "s/^X//" >src/fileio.c <<'END_OF_src/fileio.c'
X/**			fileio.c			**/
X
X/** File I/O routines, including deletion from the mailbox! 
X
X    (C) Copyright 1986 Dave Taylor
X**/
X
X#include "headers.h"
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X
Xextern int errno;
X
Xchar *error_name();
X
Xcopy_message(prefix, dest_file, remove_header, remote)
Xchar *prefix;
XFILE *dest_file;
Xint  remove_header, remote;
X{
X	/** Copy current message to destination file, with optional 'prefix' 
X	    as the prefix for each line.  If remove_header is true, it will 
X	    skip lines in the message until it finds the end of header line...
X            then it will start copying into the file... If remote is true
X	    then it will append "remote from <hostname>" at the end of the
X	    very first line of the file (for remailing) 
X	**/
X
X    char buffer[LONG_SLEN];
X    register int ok = 1, lines, in_header = 1, first_line = TRUE;
X
X    /** get to the first line of the message desired **/
X
X    if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
X       dprint2(1,"ERROR: Attempt to seek %d bytes into file failed (%s)",
X		header_table[current-1].offset, "copy_message");
X       error1("ELM [seek] failed trying to read %d bytes into file",
X	     header_table[current-1].offset);
X       return;
X    }
X
X    /* how many lines in message? */
X
X    lines = header_table[current-1].lines;
X
X    /* now while not EOF & still in message... copy it! */
X
X    while (ok && lines--) {
X      ok = (int) (fgets(buffer, LONG_SLEN, mailfile) != NULL);
X      if (strlen(buffer) < 2) in_header = 0;
X      if (ok) 
X	if (! (remove_header && in_header))
X	  if (first_line && remote) {
X	    no_ret(buffer);
X	    fprintf(dest_file, "%s%s remote from %s\n",
X		    prefix, buffer, hostname);
X	    first_line = FALSE;
X	  }
X	  else if (! in_header && first_word(buffer, "From ")) {
X	    dprint0(1,"\n*** Internal Problem...Tried to add the following;\n");
X	    dprint1(1,"  '%s'\nto output file (copy_message) ***\n", buffer);
X	    ok = 0;	/* STOP NOW! */
X	  }
X	  else
X	    fprintf(dest_file, "%s%s", prefix, buffer);
X    }
X    if (strlen(buffer) + strlen(prefix) > 1)
X      fprintf(dest_file, "\n");	/* blank line to keep mailx happy *sigh* */
X}
X
X#ifdef SITE_HIDING
X
Xint
Xis_a_hidden_user(specific_username)
Xchar *specific_username;
X{
X	/** Returns true iff the username is present in the list of
X	   'hidden users' on the system.
X	**/
X	
X	FILE *hidden_users;
X	char  buffer[SLEN];
X
X	this is shit and should be flagged as bad news!
X
X	if ((hidden_users = fopen (HIDDEN_SITE_USERS,"r")) == NULL) {
X	  dprint2(1,"Couldn't open hidden site file %s [%s]\n",
X		  HIDDEN_SITE_USERS, error_name(errno));
X	  return(FALSE);
X	}
X
X	while (fscanf(hidden_users, "%s", buffer) != EOF)
X	  if (strcmp(buffer, specific_username) == 0) {
X	    dprint1(3,"** Found user '%s' in hidden site file!\n",
X		    specific_username);
X	    fclose(hidden_users);
X	    return(TRUE);
X	  }
X
X	fclose(hidden_users);
X	dprint1(3,"** Couldn't find user '%s' in hidden site file!\n",
X		specific_username);
X
X	return(FALSE);
X}
X
X#endif
END_OF_src/fileio.c
if test 3020 -ne `wc -c <src/fileio.c`; then
    echo shar: \"src/fileio.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/mkhdrs.c\" \(3189 characters\)
if test -f src/mkhdrs.c ; then 
  echo shar: Will not over-write existing file \"src/mkhdrs.c\"
else
sed "s/^X//" >src/mkhdrs.c <<'END_OF_src/mkhdrs.c'
X/**			mkhdrs.c		**/
X
X/** This contains all the header generating routines for the ELM
X    program.
X
X    (C) Copyright 1985 Dave Taylor
X
X**/
X
X#include <stdio.h>
X#include "headers.h"
X
Xextern char in_reply_to[SLEN];
X
Xchar *strcpy();
Xunsigned long sleep();
X
Xgenerate_reply_to(msg)
Xint msg;
X{
X	/** Generate an 'in-reply-to' message... **/
X	char buffer[SLEN];
X
X
X	if (msg == -1)		/* not a reply! */
X	  in_reply_to[0] = '\0';
X	else {
X	  if (chloc(header_table[msg].from, '!') != -1)
X	    tail_of(header_table[msg].from, buffer, FALSE);
X	  else
X	    strcpy(buffer, header_table[msg].from);
X	  sprintf(in_reply_to, "Message from \"%s\" of %s %s, %s at %s",
X		  buffer,
X		  header_table[msg].month,
X		  header_table[msg].day,
X		  header_table[msg].year,
X		  header_table[msg].time);
X	}
X}
X
Xadd_mailheaders(filedesc)
XFILE *filedesc;
X{
X	/** Add the users .mailheaders file if available.  Allow backquoting 
X	    in the file, too, for fortunes, etc...*shudder*
X	**/
X
X	FILE *fd;
X	char filename[SLEN], buffer[LONG_SLEN];
X
X	sprintf(filename, "%s/%s", home, mailheaders);
X
X	if ((fd = fopen(filename, "r")) != NULL) {
X	  while (fgets(buffer, LONG_SLEN, fd) != NULL)
X	    if (strlen(buffer) < 2) {
X	      dprint0(2,
X	         "Strlen of line from .elmheaders is < 2 (write_header_info)");
X	      if (mail_only)
X	        printf("Warning: blank line in %s ignored!\r\n", filename);
X	      else {
X	        error1("Warning: blank line in %s ignored!", filename);
X	        sleep(2);
X	      }
X	    }
X	    else if (occurances_of(BACKQUOTE, buffer) == 2) 
X	      expand_backquote(buffer, filedesc);
X	    else 
X	      fprintf(filedesc, "%s", buffer);
X
X	    fclose(fd);
X	}
X}
X
Xexpand_backquote(buffer, filedesc)
Xchar *buffer;
XFILE *filedesc;
X{
X	/** This routine is called with a line of the form:
X		Fieldname: `command`
X	    and is expanded accordingly..
X	**/
X
X	FILE *fd;
X	char command[SLEN], command_buffer[SLEN], fname[SLEN],
X	     prefix[SLEN];
X	register int i, j = 0;
X
X	for (i=0; buffer[i] != BACKQUOTE; i++)
X	  prefix[j++] = buffer[i];
X	prefix[j] = '\0';
X
X	j = 0;
X
X	for (i=chloc(buffer, BACKQUOTE)+1; buffer[i] != BACKQUOTE;i++)
X	  command[j++] = buffer[i];
X	command[j] = '\0';
X
X	sprintf(fname,"%s%d", temp_print, getpid());
X
X	sprintf(command_buffer, "%s > %s", command, fname);
X
X	system_call(command_buffer, SH);
X
X	if ((fd = fopen(fname, "r")) == NULL) {
X	  if (mail_only)
X	    printf("\nbackquoted command \"%s\" in .elmheaders failed\n", 
X		   command);
X	  else
X	    error1("backquoted command \"%s\" in .elmheaders failed", command);
X	  return;	
X	}
X
X	/* If we get a line that is less than 80 - length of prefix then we
X	   can toss it on the same line, otherwise, simply prepend each line
X	   *starting with this line* with a leading tab and cruise along */
X
X	if (fgets(command_buffer, SLEN, fd) == NULL) 
X	  fprintf(filedesc, prefix);
X	else {
X	  if (strlen(command_buffer) + strlen(prefix) < 80) 
X	    fprintf(filedesc, "%s%s", prefix, command_buffer);
X	  else
X	    fprintf(filedesc, "%s\n\t%s", prefix, command_buffer);
X	  
X	  while (fgets(command_buffer, SLEN, fd) != NULL) 
X	    fprintf(filedesc, "\t%s", command_buffer);
X	
X	  fclose(fd);
X	}
X
X	unlink(fname);	/* don't leave the temp file laying around! */
X}
END_OF_src/mkhdrs.c
if test 3189 -ne `wc -c <src/mkhdrs.c`; then
    echo shar: \"src/mkhdrs.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/showmsg_cmd.c\" \(3188 characters\)
if test -f src/showmsg_cmd.c ; then 
  echo shar: Will not over-write existing file \"src/showmsg_cmd.c\"
else
sed "s/^X//" >src/showmsg_cmd.c <<'END_OF_src/showmsg_cmd.c'
X/**			showmsg_cmd.c			**/
X
X/** This is an interface for the showmsg command line.  The possible
X    functions that could be invoked from the showmsg command line are
X    almost as numerous as those from the main command line and include
X    the following;
X
X	   |    = pipe this message to command...
X	   !    = call Unix command
X	   <    = scan message for calendar info
X	   b    = bounce (remail) message
X	   d    = mark message for deletion
X	   e    = edit entire mailbox
X	   f    = forward message
X	   g    = group reply
X	   j,n  = move to body of next message
X	   k    = move to body of previous message
X	   p    = print this (all tagged) message
X	   r    = reply to this message
X	   s    = save this message to a maibox/folder 
X	   t    = tag this message
X	   x    = Exit Elm NOW
X
X    all commands not explicitly listed here are returned as unprocessed
X    to be dealt with at the main command level.
X
X    This function returns 0 if it dealt with the command, or the command
X    otherwise.
X**/
X
X#include "headers.h"
X
Xprocess_showmsg_command(command)
Xchar command;
X{
X	switch (command) {
X	  case '|' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: pipe");
X		     softkeys_off();
X		     (void) pipe();	/* do pipe regardless */
X		     softkeys_on();
X		     return(0);		/* must have new screen */
X
X	  case '!' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: system call");
X		     softkeys_off();
X		     (void) subshell();	/* do shell regardless */
X		     softkeys_on();
X		     return(0);		/* must have new screen */
X
X	  case '<' : 
X#ifdef ENABLE_CALENDAR
X		     scan_calendar();
X#else
X		     error("can't scan for calendar entries!");
X#endif
X		    break;
X
X	  case 'b' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: bounce message");
X		     remail();
X		     return(0);		/* must have new screen */
X
X	  case 'd' : delete(TRUE);
X		     break;
X
X	  case 'e' : edit_mailbox();
X		     return(0);		/* must have new screen */
X
X	  case 'f' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: forward message");
X		     (void) forward();
X		     return(0);		/* must have new screen */
X
X	  case 'g' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: group reply");
X		     (void) reply_to_everyone();
X		     return(0);		/* must have new screen */
X
X	  case 'j' :
X	  case 'n' : if (current < message_count)
X		       show_msg(++current);
X		     return(0);	
X
X	  case 'k' : if (current > 0)
X		       show_msg(--current);
X		     return(0);
X
X
X	  case 'p' : printmsg();	
X		     break;
X
X	  case 'r' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: reply to message");
X		     (void) reply();
X		     return(0);		/* must have new screen */
X
X	  case 's' : clear_bottom_of_screen();
X		     PutLine0(LINES-3,0,"Command: save message");
X		     (void) save();
X		     break;
X
X	  case 't' : tag_message();	
X		     break;
X
X	  case 'x' : leave();
X
X	  case '\n':
X	  case '\r': return(0);		/* avoid <return> looping */
X
X	  default  : return(command);	/* couldn't deal with it! */
X	}
X
X	return(1);	/* done with it! */
X}
X
Xclear_bottom_of_screen()
X{
X	/** clear the last 4 lines of the screen... **/
X
X	MoveCursor(LINES-4, 0);
X	CleartoEOS();
X}
END_OF_src/showmsg_cmd.c
if test 3188 -ne `wc -c <src/showmsg_cmd.c`; then
    echo shar: \"src/showmsg_cmd.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/softkeys.c\" \(2576 characters\)
if test -f src/softkeys.c ; then 
  echo shar: Will not over-write existing file \"src/softkeys.c\"
else
sed "s/^X//" >src/softkeys.c <<'END_OF_src/softkeys.c'
X/**			softkeys.c			**/
X
X/** This file and associated routines: (C) Copyright 1986, Dave Taylor **/
X
X#include <stdio.h>
X#include "headers.h"
X
Xdefine_softkeys(level)
Xint level;
X{
X	if (! hp_softkeys) return;
X
X	if (level == MAIN) {
X
X	  define_key(f1, "  Show     Msg",   "\r");
X	  define_key(f2, "  Mail     Msg",   "m");
X	  define_key(f3, "  Reply  to Msg",  "r");
X
X	  if (user_level == 0) {
X	    define_key(f4, "  Save     Msg",   "s");
X	    define_key(f5, " Delete    Msg",   "d");
X	    define_key(f6, "Undelete   Msg",   "u");
X   	  }
X	  else {
X	    define_key(f4, " Change  Mailbox", "c");
X	    define_key(f5, "  Save     Msg",   "s");
X	    define_key(f6, " Delete/Undelete", "^");
X	  }
X
X	  define_key(f7, " Print     Msg",   "p");
X	  define_key(f8, "  Quit     Elm",   "q");
X	}
X	else if (level == ALIAS) {
X	  define_key(f1, " Alias  Current",  "a");
X	  define_key(f2, " Check  Person",   "p");
X	  define_key(f3, " Check  System",   "s");
X	  define_key(f4, " Make    Alias",   "m");
X	  clear_key(f5);
X	  clear_key(f6);
X	  clear_key(f7);
X	  define_key(f8, " Return  to Elm",  "r");
X	}
X	else if (level == YESNO) {
X	  define_key(f1, "  Yes",  "y");
X	  clear_key(f2);
X	  clear_key(f3);
X	  clear_key(f4);
X	  clear_key(f5);
X	  clear_key(f6);
X	  clear_key(f7);
X	  define_key(f8, "   No",  "n");
X	}
X	else if (level == READ) {
X	  define_key(f1, "  Next    Page  ", " ");
X	  clear_key(f2);
X	  define_key(f3, "  Skip    Page  ", "f");
X	  clear_key(f4);
X	  clear_key(f5);
X	  clear_key(f6);
X	  clear_key(f7);
X	  define_key(f8, " Return  to Elm", "q");
X	}
X	else if (level == CHANGE) {
X	  define_key(f1, "  Mail  Directry", "=/");
X	  define_key(f2, "  Home  Directry", "~/");
X	  clear_key(f3);
X	  define_key(f4, "Incoming Mailbox", "!\n");
X	  clear_key(f5);
X	  clear_key(f6);
X	  clear_key(f7);
X	  define_key(f8, " Cancel", "\n");
X	}
X
X	softkeys_on();
X}
X
Xdefine_key(key, display, send)
Xint key;
Xchar *display, *send;
X{
X
X	char buffer[30];
X
X	sprintf(buffer,"%s%s", display, send);
X
X	fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
X		strlen(display), strlen(send), buffer);
X	fflush(stdout);
X}
X
Xsoftkeys_on()	
X{ 
X	/* enable (esc&s1A) turn on softkeys (esc&jB) and turn on MENU 
X	   and USER/SYSTEM options. */
X
X	if (hp_softkeys) {
X	  fprintf(stderr, "%c&s1A%c&jB%c&jR", ESCAPE, ESCAPE, ESCAPE); 
X	  fflush(stdout);
X	}
X	
X}
X
Xsoftkeys_off()	
X{ 
X	/* turn off softkeys (esc&j@) */
X
X	if (hp_softkeys) {
X	  fprintf(stderr, "%c&s0A%c&j@", ESCAPE, ESCAPE); 
X	  fflush(stdout);
X	}
X}
X
Xclear_key(key)  
X{ 	
X	/** set a key to nothing... **/
X
X	if (hp_softkeys) 
X	   define_key(key, "                ", ""); 
X}
END_OF_src/softkeys.c
if test 2576 -ne `wc -c <src/softkeys.c`; then
    echo shar: \"src/softkeys.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"utils/printmail.c\" \(2471 characters\)
if test -f utils/printmail.c ; then 
  echo shar: Will not over-write existing file \"utils/printmail.c\"
else
sed "s/^X//" >utils/printmail.c <<'END_OF_utils/printmail.c'
X/**		printmail.c		**/
X
X/** print mail, adding a formfeed between each message  **/
X/** Modified to use stdin if being fed from a pipe.	**/
X
X/** (C) Copyright 1985, Dave Taylor **/
X
X#include <stdio.h>
X#include "defs.h"
X
Xstatic char ident[] = { WHAT_STRING };
X
X#define  dashes		  \
X"\n\n------------------------------------------------------------------------------\n\n"
X#define  FF	  	  "\014"	/* form feed! */
X
XFILE *mailfile;
Xchar  separator[80];
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	char infile[80], username[40], c;
X
X	strcpy(separator, FF);
X
X	argv++;				/* get past argv[0] */
X
X	if (argc > 1) 
X	  if (strcmp(*argv, "-d") == 0) {
X	    strcpy(separator, dashes);
X	    --argc;
X	    argv++;
X	  }
X	
X	if (argc > 1 && *argv[0] == '-') 
X	    exit(fprintf(stderr, "Usage: printmail {-d} {filename (s)}\n"));
X	
X	if (argc == 1) {
X	  strcpy(username, getlogin());
X	  if (strlen(username) == 0)
X	    cuserid(username);
X	  if (isatty(fileno(stdin))) {	/* normal invokation... */
X	    sprintf(infile,"%s/%s",mailhome, username);
X	    if ((mailfile = fopen(infile,"r")) == NULL) {
X	      fprintf(stderr, "No mail!\n");
X	      exit(0);
X	    }
X	  }
X	  else 
X	    mailfile = stdin;	/* read from stdin! */
X
X	  if (read_headers() == 0)
X	    fprintf(stderr, "No messages in mailbox!\n");
X	}
X
X	if (argc > 1)		/* more than one file - delimit each */
X	  if (strcmp(separator, FF) != 0) 
X	    printf("\t\t\t%s\n%s", *argv, separator);
X	  else
X	    printf("\t\t\t%s\n\n", *argv);	/* Don't put a formfeed! */
X
X	while (--argc) {
X	  if ((mailfile = fopen(*argv,"r")) == NULL) {
X	    fprintf(stderr, "Could not open file '%s'!", *argv);
X	    break;
X	  }
X	  else
X	    if (read_headers() == 0)
X	      fprintf(stderr, "No messages in mailbox '%s'!\n", *argv);
X	  argv++;
X	  if (argc-1) {
X	    if (strcmp(separator, FF) != 0) 
X	      printf("%s\t\t\t%s%s", separator, *argv, separator);
X	    else
X	      printf("%s\t\t\t%s\n\n", separator, *argv);
X	  }
X	}
X}
X
Xint
Xread_headers()
X{
X	char buffer[100];
X	register int count = 0;
X
X	while (fgets(buffer, 100, mailfile) != NULL) 
X	  if (first_word(buffer,"From ")) {
X	    if (real_from(buffer)) {
X	      printf("%s%s", count ? separator : "", buffer);
X	      count++;
X	    }
X	  }
X	  else
X	    printf("%s", buffer);
X
X	return(count);
X}
X
Xint
Xreal_from(buffer)
Xchar *buffer;
X{
X	/***** returns true iff 's' has the seven 'from' fields *****/
X
X	char junk[80];
X
X	junk[0] = '\0';
X	sscanf(buffer, "%*s %*s %*s %*s %*s %*s %s", junk);
X	return(junk[0] != '\0');
X}
END_OF_utils/printmail.c
if test 2471 -ne `wc -c <utils/printmail.c`; then
    echo shar: \"utils/printmail.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 19\).
cp /dev/null ark2isdone
DONE=true
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
    if test ! -f ark${I}isdone ; then
	echo shar: You still need to run archive ${I}.
	DONE=false
    fi
done
if test "$DONE" = "true" ; then
	echo You have unpacked all 19 archives.
	echo "See the Instructions file"
	rm -f ark[1-9]isdone ark[1-9][0-9]isdone
fi
##  End of shell archive.
exit 0