[mod.sources] v09i003: ELM Mail System, Part03/19

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

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

#! /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 3 (of 19)."
# Contents:  Instructions MANIFEST filter/summarize.c hdrs/filter.h
#   hdrs/shortnames.h src/builtin.c src/encode.c src/savecopy.c
#   utils/Makefile utils/Makefile.mstr utils/autoreply.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"Instructions\" \(4676 characters\)
if test -f Instructions ; then 
  echo shar: Will not over-write existing file \"Instructions\"
else
sed "s/^X//" >Instructions <<'END_OF_Instructions'
X
X				Instructions
X				------------
X
X			Last Update: July 17th, 1986
X
X
X	This file contains instructions on how to create and install
Xthe entire ELM mail system.  It should be read BEFORE any attempts
Xare made at actually creating and/or installing any of the software
Xcontained herein!
X
X	There is actually really one step needed - unpack all the shar
Xfiles and then;
X
X	$ cd <where-ever you're keeping the Elm sources>
X
X	$ sh Configure.sh
X
X	Answer the questions of that program,, then let it create the localized
XMakefiles and system definition files for you.  When it's done you can double
Xcheck the configuration (or customize it further) by reading the Configuration
XGuide + editing the file "hdrs/sysdefs.h".  There are lots of neat features
Xthat are unique to this mailer - it's worth a quick perusal at least!
X
X	Once you're happy with the localized files, you then need to create
Xthe documentation (so there's a bit of a catch-22 that you need to format the
XConfiguration guide before you are happy with the localization but can't do
Xthat until you're happy with the localization...oh well).
X
X	$
X
X	$ make documentation
X
X    When that's done, or even if it fails (don't worry too much about it)
X
X	$ (make -i all >& MAKELOG) &
X	$ tail -f MAKELOG
X
X    (if you're in "sh", you can use "> MAKELOG 2>&1" instead of ">& MAKELOG")
X
XThis will take a fair while, so it's recommended that you go and eat 
Xlunch or play a game for a while!! (alternatively, spend lots of money
Xon a really FAST machine and blink your eyes a few times...)
X
XAssuming there are no errors during compilation (we'll have to assume
Xthat for the moment) you should now be able to list the directory "bin"
Xand find the following files:
X
X    "answer", "arepdaemon", "autoreply", "fastmail", "from", 
X    "elm", "newalias", "newmail", "printmail", and "readmsg".
X
Xnext, you can install all the software on your system by;
X
X	$ make -i install
X	
XNote: the mailer runs as setgid mail to have the ability to WRITE
Xto the /usr/mail directory (for lock files).   If you have a different
Xscheme at your site, feel free to set it up to use that instead.
X
XFinally, we're just about done!   The final checks can be made
Xby the following commands:
X
X	$ /usr/local/bin/elm -z
X
Xshould say "no mail" if nothing's in your incoming mailbox, and
X
X	$ /usr/local/bin/elm -f test/test.mail
X
Xshould read in EIGHT messages from various people.  While here, try to
XA)lias C)urrent message for each of the eight messages to confirm that
Xthe reply/address system is working okay.   Now try to C)hange mailboxes
Xto the file "test/test.note" and use the '%' key to see if the mailer is
Xgenerating valid return addresses for the notes (If not, then you might
Xneed to install the pathalias database - see "sysdefs.h" for more info)
XChange back to "test/test.mail" and Q)uit without having marked anything 
Xfor deletion...answer the questions accordingly.
X
XIf you get this far you're in Wonderful shape!  In fact, you're done!
X
XCongratulations!  You've just installed one of the best electronic mail
Xsystems available today on your machine (if I say so myself!)
X
XHANDY HINTS:  If you want to create a print of the entire set of
Xsources, including this file, use the command:
X
X	$ make listing
X
XIf, on the other hand, you just want to create a listing file of 
Xjust the ELM sources, try:
X
X	$ make elm-listing
X
XAlso, if you have a number of machines on a network, you can rlogin
Xto the remote machine and then do a remote install (after checking
Xto ensure that the networking copy method in the Makefile under the
Xtarget "remote-install" is correct) by typing:
X
X	$ make -f <remote Makefile> REMOTE=<remote file system> rmt-install
X
X(for example, if we had installed the system on machine "machx" and 
X wanted to install it on "machy", with the Makefile in /src/Elm on
X "machx", we could type from "machy";
X	 $ make -f machx:/src/Elm/Makefile REMOTE=machx: rmt-install
X to have it install the system on machine y!)
X
XOne final note for non-US distribution - the program might complain
Xat link time that it can't find "crypt()".  If so, and if you cannot
Xobtain a copy, you should merely instruct your users to not use the
Xencrypted mail option on outgoing mail.
X
XThat's it!
X----------
X
XOh!  One final note: if you'd like a nicely typeset copy of the documentation,
Xfeel free to drop me a line with your full (overland) mail address!!  I'll
Xtry to get it back to you within a week or two.
X
X-----------
X
X	Author's address:	taylor@HPLABS
X				hplabs!taylor
X
X	Mail address:		Dave Taylor
X				Hewlett Packard Laboratories
X				1501 Page Mill Road
X				Palo Alto CA
X				94304
X
X  This document and the entire mail system is
X
X	(C) Copyright 1986, Dave Taylor
END_OF_Instructions
if test 4676 -ne `wc -c <Instructions`; then
    echo shar: \"Instructions\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"MANIFEST\" \(4296 characters\)
if test -f MANIFEST ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X Configure.sh             18	
X Instructions              3	
X MANIFEST                  3	
X Makefile                  9	
X Makefile.mstr             9	
X NOTICE                    2	
X Overview                  4	
X bin                       1	
X doc                       1	
X doc/Alias.guide          15	
X doc/Config.guide         15	
X doc/Elm.coversheet        1	
X doc/Filter.guide         14	
X doc/Form.guide           10	
X doc/Ref.guide            19	
X doc/Users.guide          18	
X doc/answer.1              1	
X doc/autoreply.1           1	
X doc/checkalias.1          1	
X doc/elm-help.0            1	
X doc/elm-help.1            1	
X doc/elm-help.2            1	
X doc/elm.1                 2	
X doc/elmrc-info            2	
X doc/elmrc.sample          1	
X doc/fastmail.1            2	
X doc/filter.1              1	
X doc/from.1                1	
X doc/listalias.1           1	
X doc/messages.1            1	
X doc/newalias.1            1	
X doc/newmail.1             1	
X doc/printmail.1           1	
X doc/readmsg.1             2	
X doc/trim-headers.1        1	
X doc/wnewmail.1            1	
X filter                    1	
X filter/Makefile           1	
X filter/Makefile.mstr      1	
X filter/actions.c          5	
X filter/filter.c           4	
X filter/parse.c            8	
X filter/rules.c            5	
X filter/summarize.c        3	
X filter/utils.c            2	
X filter/utils2.c           4	
X hdrs                      1	
X hdrs/curses.h             1	
X hdrs/defs.h               6	
X hdrs/elm.h                5	
X hdrs/filter.h             3	
X hdrs/headers.h            5	
X hdrs/save_opts.h          1	
X hdrs/shortnames.h         3	
X hdrs/sysdefs.h            6	
X hdrs/sysdefs.master       6	
X hdrs/sysdefs.old          6	
X src                       1	
X src/Makefile              2	
X src/Makefile.mstr         2	
X src/addr_utils.c         15	
X src/alias.c              10	
X src/aliasdb.c             7	
X src/aliaslib.c            4	
X src/args.c                2	
X src/bounceback.c          2	
X src/builtin.c             3	
X src/calendar.c            5	
X src/connect_to.c          2	
X src/curses.c             16	
X src/curses.q             12	
X src/date.c               10	
X src/delete.c              1	
X src/domains.c             7	
X src/edit.c                4	
X src/editmsg.c            12	
X src/elm.c                17	
X src/encode.c              3	
X src/errno.c               2	
X src/file.c                6	
X src/file_utils.c          4	
X src/fileio.c              2	
X src/forms.c               9	
X src/getopt.c              1	
X src/hdrconfg.c            5	
X src/help.c                5	
X src/initialize.c          7	
X src/initialize.uts        6	
X src/input_utils.c         8	
X src/leavembox.c          12	
X src/limit.c               6	
X src/mailmsg1.c            8	
X src/mailmsg2.c           17	
X src/mailtime.c            4	
X src/mkhdrs.c              2	
X src/newmbox.c            14	
X src/opt_utils.c           4	
X src/options.c             8	
X src/output_utils.c        1	
X src/pattern.c             5	
X src/pmalloc.c             1	
X src/quit.c                1	
X src/read_rc.c            16	
X src/remail.c              1	
X src/reply.c              14	
X src/return_addr.c         9	
X src/save_opts.c           9	
X src/savecopy.c            3	
X src/screen.c             11	
X src/screen3270.q         11	
X src/showmsg.c            11	
X src/showmsg_cmd.c         2	
X src/signals.c             1	
X src/softkeys.c            2	
X src/sort.c                4	
X src/string2.c             1	
X src/strings.c            11	
X src/syscall.c             4	
X src/utils.c               5	
X src/validname.c           1	
X test                      1	
X test/test.empty           1	
X test/test.mail           10	
X test/test.notes          13	
X utils                     1	
X utils/Makefile            3	
X utils/Makefile.mstr       3	
X utils/answer.c            8	
X utils/arepdaemon.c       13	
X utils/autoreply.c         3	
X utils/fastmail.c          7	
X utils/from.c             10	
X utils/listalias.c         1	
X utils/mailrc.awk          1	
X utils/newalias.c         13	
X utils/newmail.c           7	
X utils/printmail.c         2	
X utils/readmsg.c          12	
X utils/trim-headers        1	
X utils/wnewmail.c          7	
END_OF_MANIFEST
if test 4296 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"filter/summarize.c\" \(4658 characters\)
if test -f filter/summarize.c ; then 
  echo shar: Will not over-write existing file \"filter/summarize.c\"
else
sed "s/^X//" >filter/summarize.c <<'END_OF_filter/summarize.c'
X/**			summarize.c			**/
X
X/** This routine is called from the filter program (or can be called
X    directly with the correct arguments) and summarizes the users filterlog
X    file.  To be honest, there are two sorts of summaries that are
X    available - either the '.filterlog' file can be output (filter -S) 
X    or a summary by rule and times acted upon can be output (filter -s).
X    Either way, this program will delete the two associated files each
X    time ($HOME/.filterlog and $HOME/.filtersum) *if* the -c option is
X    used to the program (e.g. clear_logs is set to TRUE).
X
X    (C) Copyright 1986, Dave Taylor
X**/
X
X#include <stdio.h>
X
X#include "defs.h"
X
X#include "filter.h"
X
Xshow_summary()
X{
X	/* Summarize usage of the program... */
X
X	FILE   *fd;				/* for output to temp file! */
X	char filename[SLEN],			/* name of the temp file    */
X	     buffer[LONG_SLEN];			/* input buffer space       */
X	int  erroneous_rules = 0,
X	     default_rules   = 0,
X	     rule,
X	     applied[MAXRULES];
X
X	if (long_summary) 
X	  long_sum();
X	else {
X
X	  sprintf(filename, "%s/%s", home, filtersum);
X
X	  if ((fd = fopen(filename, "r")) == NULL) {
X	    fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
X		    username, filename);
X	    exit(1);
X	  }
X
X	  for (rule=0;rule < MAXRULES; rule++)
X	    applied[rule] = 0;			/* initialize it all! */
X
X	  /** Next we need to read it all in, incrementing by which rule
X	      was used.  The format is simple - each line represents a 
X	      single application of a rule, or '-1' if the default action
X	      was taken.  Simple stuff, eh?  But oftentimes the best.  
X	  **/
X
X	  while (fgets(buffer, LONG_SLEN, fd) != NULL) {
X	    if ((rule = atoi(buffer)) > total_rules || rule < -1) {
X	      fprintf(stderr,
X      "%sfilter (%s): Warning - rule #%d is invalid data for short summary!!\n",
X		     BEEP, username, rule);
X	      erroneous_rules++;
X	    }
X	    else if (rule == -1)
X	      default_rules++;
X	    else
X	      applied[rule]++;
X	  }
X	
X	  fclose(fd);
X
X	  /** now let's summarize the data... **/
X
X	  printf("\nSummary of filter activity;\n\n");
X
X	  if (erroneous_rules)
X	    printf("** Warning: %d erroneous rule%s logged and ignored! **\n\n",
X		   erroneous_rules, erroneous_rules > 1? "s were" : " was");
X	
X	  if (default_rules)
X	    printf(
X   "The default rule of putting mail into your mailbox was used %d time%s\n\n",
X		   default_rules, plural(default_rules));
X
X	  /** and now for each rule we used... **/
X
X	  for (rule = 0; rule < total_rules; rule++) {
X	    if (applied[rule]) {
X	       printf("Rule #%d: ", rule+1);
X	       switch (rules[rule].action) {
X		  case LEAVE:	printf("(leave mail in mailbox)");	break;
X		  case DELETE:  printf("(delete message)");		break;
X		  case SAVE  :  printf("(save in \"%s\")",
X					rules[rule].argument2);		break;
X		  case SAVECC:  printf("(left in mailbox and saved in \"%s\")",
X					rules[rule].argument2);		break;
X		  case FORWARD: printf("(forwarded to \"%s\")",
X					rules[rule].argument2);		break;
X		  case EXEC  :  printf("(given to command \"%s\")",
X					rules[rule].argument2);		break;
X	       }
X	       printf(" was applied %d time%s.\n\n", applied[rule],
X		      plural(applied[rule]));
X	     }
X	   }
X
X	  /* next, after a ^L, include the actual log file... */
X
X	  sprintf(filename, "%s/%s", home, filterlog);
X
X	  if ((fd = fopen(filename, "r")) == NULL) {
X	    fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
X		    username, filename);
X	  }
X	  else {
X	    printf("\n\n\n%c\n\nExplicit log of each action;\n\n", (char) 12);
X	    while (fgets(buffer, LONG_SLEN, fd) != NULL)
X	      printf("%s", buffer);
X	    printf("\n-----\n");
X	    fclose(fd);
X	  }
X
X	  /* now remove the log files, please! */
X
X	  if (clear_logs) {
X	    unlink(filename);
X	    sprintf(filename, "%s/%s", home, filtersum);
X	    unlink(filename);
X	  }
X
X	  return;
X	}
X}
X
Xlong_sum()
X{
X	/** summarize by listing the .fitlerlog file.  The simplest of the
X	    two possible options this one is indeed rather trivial!  **/
X
X	FILE   *fd;				/* for output to temp file! */
X	char filename[SLEN],			/* name of the temp file    */
X	     buffer[LONG_SLEN];			/* input buffer space       */
X
X	sprintf(filename,"%s/%s", home, filterlog);
X
X	if ((fd = fopen(filename, "r")) == NULL) {
X	  fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
X		  username, filename);
X	  exit(1);
X	}
X
X	while (fgets(buffer, SLEN, fd) != NULL)
X	  printf("%s", buffer);	/* already has '\n' doesn't it? */
X	fclose(fd);
X
X	/** now let's waste the TWO log files and get outta here! **/
X
X	if (clear_logs) {
X	  unlink(filename);
X	  sprintf(filename, "%s/%s", home, filtersum);
X	  unlink(filename);
X	}
X
X	return;
X}
END_OF_filter/summarize.c
if test 4658 -ne `wc -c <filter/summarize.c`; then
    echo shar: \"filter/summarize.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"hdrs/filter.h\" \(3994 characters\)
if test -f hdrs/filter.h ; then 
  echo shar: Will not over-write existing file \"hdrs/filter.h\"
else
sed "s/^X//" >hdrs/filter.h <<'END_OF_hdrs/filter.h'
X/**			filter.h			**/
X
X/** Headers for the filter program.
X
X   (C) Copyright 1986, Dave Taylor
X**/
X
X#ifdef   BSD
X# undef  tolower
X# define tolower(c)	(isupper(c)?  c = c - 'A' + 'a' : c)
X#endif
X
X/** define a few handy macros for later use... **/
X
X#define  BEEP		(audible? "\007" : "")
X
X#define  the_same(a,b)	(strncmp(a,b,strlen(b)) == 0)
X
X#define relationname(x)  (x == 1?"<=":x==2?"<":x==3?">=":x==4?">":x==5?"!=":"=")
X
X#define quoteit(x)	 (x == LINES? "" : "\"")
X
X/** some of the files we'll be using, where they are, and so on... **/
X
X#define  filter_temp	"/tmp/filter"
X#define  filterfile	".filter-rules"
X#define  filterlog	".filterlog"
X#define  filtersum	".filtersum"
X
X#define  EMERGENCY_MAILBOX	"EMERGENCY_MBOX"
X#define  EMERG_MBOX		"MBOX.EMERGENCY"
X
X/** and now the hardwired constraint of the program.. **/
X
X#define  MAXRULES	25		/* can't have more den dis, boss! */
X
X/** some random defines for mnemonic stuff in the program... **/
X
X#define  TO		1
X#define  FROM		2
X#define  LINES		3
X#define  CONTAINS	4
X
X#define  DELETE 	5
X#define  SAVE		6
X#define  SAVECC		7
X#define  FORWARD	8
X#define  LEAVE		9
X#define  EXEC		10
X
X#define  FAILED_SAVE	20
X
X/** Some conditionals... **/
X
X#define LE		1
X#define LT		2
X#define GE		3
X#define GT		4
X#define NE		5
X#define EQ		6
X
X/** A funky way to open a file using open() to avoid file locking hassles **/
X
X#define  FOLDERMODE	O_WRONLY | O_APPEND | O_CREAT | O_SYNCIO
X
X/** cheap but easy way to have two files share the same #include file **/
X
X#ifdef MAIN_ROUTINE
X# define  extern
X#endif
X
Xextern char home[SLEN],				/* the users home directory */
X            hostname[SLEN],			/* the machine name...      */
X            username[SLEN];			/* the users login name...  */
X
Xextern char to[VERY_LONG_STRING], 
X            from[SLEN], 
X            subject[SLEN];			/* from current message     */
X
X#ifdef MAIN_ROUTINE
Xint  total_rules = 0,				/* how many rules to check  */
X     show_only = FALSE,				/* just for show?           */
X     long_summary = FALSE,			/* what sorta summary??     */
X     verbose   = FALSE,				/* spit out lots of stuff   */
X     audible   = FALSE,				/* be noisy with output?    */
X     lines     = 0,				/* lines in message..       */
X     clear_logs = FALSE,			/* clear files after sum?   */
X     already_been_forwarded = FALSE,		/* has this been filtered?  */
X     log_actions_only = FALSE,			/* log actions | everything */
X     rule_choosen;				/* which one we choose      */
X#else
Xextern int total_rules,				/* how many rules to check  */
X           show_only,				/* just for show?           */
X           long_summary,			/* what sorta summary??     */
X           verbose,				/* spit out lots of stuff   */
X           audible,				/* be noisy with output?    */
X           lines,				/* lines in message..       */
X           clear_logs,			        /* clear files after sum?   */
X	   already_been_forwarded,		/* has this been filtered?  */
X           log_actions_only,			/* log actions | everything */
X           rule_choosen;			/* which one we choose      */
X#endif
X
X/** and our ruleset record structure... **/
X
Xstruct condition_rec {
X	int     matchwhat;			/* type of 'if' clause      */
X	int     relation;			/* type of match (eq, etc)  */
X	char    argument1[SLEN];		/* match against this       */
X	struct  condition_rec  *next;		/* next condition...	    */
X      };
X
Xextern struct ruleset_record {
X	char  	printable[SLEN];		/* straight from file...    */
X	struct  condition_rec  *condition;
X	int     action;				/* what action to take      */
X	char    argument2[SLEN];		/* argument for action      */
X      } rules[MAXRULES];
X
X
X/** finally let's keep LINT happy with the return values of all these pups! ***/
X
Xunsigned short getuid();
X
Xunsigned long sleep();
X
Xchar *malloc(), *strcpy(), *strcat(), *itoa();
X
Xvoid	exit();
X
X#ifdef BSD
X	
X  FILE *popen();
X
X  extern char  _vbuf[5*BUFSIZ];		/* space for file buffering */
X
X# define _IOFBF		0		/* doesn't matter - ignored */
X
X# define setvbuf(fd,a,b,c)	setbuffer(fd, _vbuf, 5*BUFSIZ)
X
X#endif
END_OF_hdrs/filter.h
if test 3994 -ne `wc -c <hdrs/filter.h`; then
    echo shar: \"hdrs/filter.h\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"hdrs/shortnames.h\" \(3969 characters\)
if test -f hdrs/shortnames.h ; then 
  echo shar: Will not over-write existing file \"hdrs/shortnames.h\"
else
sed "s/^X//" >hdrs/shortnames.h <<'END_OF_hdrs/shortnames.h'
X/**			shortnames.h			**/
X
X/** This file is from Geoff Kuenning, and will help those poor users that
X    are stuck using C compilers that don't have flexnames.   Too bad.
X
X	This file has no explicit copyright.
X
X**/
X
X#define PutLine0		PLine0
X#define PutLine1		PLine1
X#define PutLine2		PLine2
X#define PutLine3		PLine3
X
X#define add_to_table		add_2_table
X#define address1		addrs1
X#define addressII		addrsII
X#define addresses		addr_s
X#define alternate_prompt	alt_prompt
X#define alternative_addresses	alt_addrs
X#define always_leave		alw_leave
X
X#define calendar_line		cal_line
X#define cancelled_msg		cncld_msg
X#define central_message_buffer	cntrl_bfr
X#define compare_dates		cmp_dates
X#define compare_headers		cmp_hdrs
X#define copy_message_across	cpy_msg_across
X#define current_record		cur_rec
X#define current_time		cur_time
X
X#define define_softkeys		def_softkeys
X#define display_central_message	displ_cntrl_msg
X#define display_error		displ_error
X#define display_headers		displ_hdrs
X#define display_helpfile	dspl_helpfile
X#define display_options		displ_options
X#define display_title		displ_titles
X#define display_to		displ_to
X
X#define encrypted		crypted
X#define encrypted_key		crypt_key
X#define expanded_cc		xp_cc
X#define expanded_to		xp_to
X#define expand_address		xp_addr
X#define expand_domain		xp_domain
X#define expand_env		xp_env
X#define expand_filename		xp_filename
X#define expand_group		xp_group
X#define expand_logname		xp_logname
X#define expand_site		xp_site
X#define expand_system		xp_system
X
X#define filename2		fn2
X#define forward			forwrd
X
X#define generate_reply_to	gen_reply_to
X#define get_return_name		g_ret_name
X
X#define header_line		h_line
X#define header_page		h_page
X#define headers_per_page	h_per_page
X#define header_table		h_table
X
X#define install_aliases		ins_aliases
X
X#define last_line_loc		last_ln_loc
X
X#define machine_group		mach_group
X#define mailbox_defined		mbox_defined
X#define mailfile_size		mfile_size
X#define message_count		msg_count
X#define message_number		msg_number
X
X#define newaliases		nwaliases
X#define noptimize_return	noret_opt
X#define noptimize_usenet	nousenet_opt
X
X#define optimize_and_add	opt_and_add
X#define optimize_arpa		opt_arpa
X#define optimize_cmplx_arpa	opt_cmplx_arpa
X#define optimize_return		opt_return
X#define optimize_usenet		opt_usenet
X#define optional_arg		opt_arg
X#define optionally_enter	opt_enter
X#define original_cc		orig_cc
X#define original_msg_num	orig_msg_num
X#define original_to		orig_to
X
X#define parse_arguments		pars_arguments
X#define parse_arpa_from		prs_arpa_from
X#define password_entry		pw_entry
X#define pattern_enter		pat_enter
X#define pattern_match		pat_match
X
X#define read_alias_files	rd_alias_files
X#define read_headers		rd_headers
X#define read_rc			rd_rc
X#define read_rc_file		rd_rc_file
X#define received_on_machine	rcvd_on_machine
X#define remove_all		rem_all
X#define remove_first_word	rem_1st_word
X#define remove_domains		rem_domains
X#define remove_header		rem_hdr
X#define remove_user		rem_user
X#define remove_through_ch	rem_thru_ch
X#define reply_to_everyone	repl_to_everyone
X#define resolve_received	rslv_received
X
X#define show_message		shw_message
X#define show_msg		showmsg
X#define show_msg_tag		sh_msg_tag
X#define size_of_pathfd		sz_of_pathfd
X#define softkeys_off		soft_off
X#define softkeys_on		soft_on
X#define subjectbuffer		subjbuff
X#define subject_matches		subj_matches
X#define system_call		sys_call
X#define system_data		sys_data
X#define system_files		sys_files
X#define system_hash_table	sys_hash_table
X#define system_record		sys_record
X
X#define tail_of_string		tl_of_string
X#define talk_to_sys		tlk_to_sys
X#define tempfile		tmpfile
X#define termcap_label		tcap_label
X#define top_of_screen_left	top_left_of_screen
X#define top_of_screen_right	top_right_of_screen
X#define translate_return	xlate_return
X
X#define update_mailtime		upd_mailtime
X#define update_title		upd_title
X#define unexpanded_cc		unexp_cc
X#define unexpanded_to		unexp_to
X
X#define verify_transmission	vfy_xmsn
X
X#define weeding_out		wding_out
END_OF_hdrs/shortnames.h
if test 3969 -ne `wc -c <hdrs/shortnames.h`; then
    echo shar: \"hdrs/shortnames.h\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/builtin.c\" \(4541 characters\)
if test -f src/builtin.c ; then 
  echo shar: Will not over-write existing file \"src/builtin.c\"
else
sed "s/^X//" >src/builtin.c <<'END_OF_src/builtin.c'
X/**			builtin.c		**/
X
X/** This is the built-in pager for displaying messages while in the Elm
X    program.  It's a bare-bones pager with precious few options. The idea
X    is that those systems that are sufficiently slow that using an external
X    pager such as 'more' is too slow, then they can use this!
X
X    Added the following functionality;
X
X	<number>s	skip <number> lines
X	<number>f	forward a page or <number> pages
X	/pattern	skip forward to pattern		
X
X    (C) Copyright 1986, Dave Taylor
X**/
X
X#include "headers.h"
X#include <ctype.h>
X
X#define  BEEP		007		/* ASCII Bell character */
X
X#ifdef BSD
X#  undef tolower
X#endif
X
Xint	lines_put_on_screen = 0,    /* number of lines displayed per screen */
X	lines_displayed = 0,	    /* Total number of lines displayed      */
X	total_lines_to_display,	    /* total number of lines in message     */
X	lines_to_ignore = 0;	    /* for 'f' and 's' functions...         */
X
Xstart_builtin(lines_in_message)
Xint lines_in_message;
X{
X	/** clears that screen and resets it's internal counters... **/
X
X	dprint1(8,"displaying %d lines from message using internal pager\n",
X		lines_in_message);
X
X	lines_displayed = 0;
X	lines_put_on_screen = 0;
X	lines_to_ignore = 0;
X
X	total_lines_to_display = lines_in_message;
X}
X
Xint
Xdisplay_line(line)
Xchar *line;
X{
X	/** Display the given line on the screen, taking into account such
X	    dumbness as wraparound and such.  If displaying this would put
X	    us at the end of the screen, put out the "MORE" prompt and wait
X	    for some input.   Return non-zero if the user terminates the
X	    paging (e.g. 'q') or zero if we should continue...
X	**/
X	
X	register int lines_needed, okay_char, ch, len = 12, iteration = 0;
X	char     pattern[SLEN];
X
X	if (lines_to_ignore != 0) {
X	   if (--lines_to_ignore <= 0) {
X	     putchar('\n');
X	     lines_to_ignore = 0;
X	   }
X	   return(0);
X	}
X
X	lines_needed = (int) (printable_chars(line)/COLUMNS); /* wraparound */
X
X	for (ch = 0; ch < strlen(line); ch++)
X	  if (line[ch] == '\n') lines_needed++;
X
X	if (lines_needed + lines_put_on_screen > LINES-1) {
X	  StartBold();
X	  if (user_level == 0) {
X	    Write_to_screen(
X               "You've read %d%%: press <space> for more, or 'q' to return", 1,
X		(int) (100.0 * (
X		   (float) lines_displayed / (float) total_lines_to_display)));
X	    len = 59;
X	  }
X	  else if (user_level == 1) {
X	    Write_to_screen( 
X		"More (%d%%) Press <space> for more, 'q' to return", 1, 
X		(int) (100.0 * (
X		   (float) lines_displayed / (float) total_lines_to_display)));
X	    len = 49;
X	  }
X	  else 
X	    Write_to_screen(" More (%d%%)", 1, 
X		(int) (100.0 * (
X		   (float) lines_displayed / (float) total_lines_to_display)));
X
X	  EndBold();
X	  okay_char = FALSE;
X	  do {
X	     Raw(ON);
X	     ch =  tolower(ReadCh());
X	     Raw(OFF);
Xloop_top:     switch (ch) {
X	       case '\n' : 
X	       case '\r' : /* <return> pressed... */
X			   lines_put_on_screen -= lines_needed;
X			   okay_char = TRUE;
X			   break;
X	       case ' '  : /* <space> pressed... */
X			   lines_put_on_screen = 0;
X			   okay_char = TRUE;
X			   break;
X	       case '/'  : putchar('/');fflush(stdout);
X			   Raw(ON);
X			   optionally_enter(pattern,-1,-1,FALSE);
X			   Raw(OFF);
X			   CursorLeft(len+strlen(pattern)+1); CleartoEOLN();
X			   printf("...searching for pattern \"%s\"...",
X				  pattern);
X			   fflush(stdout);
X			   break;
X	       case 'f'  : lines_to_ignore = ((iteration?iteration:1)*LINES)-5;	
X			   CursorLeft(len); CleartoEOLN();
X			   printf("...skipping %d lines...",lines_to_ignore+2); 
X			   fflush(stdout);
X			   lines_put_on_screen = 0;
X			   return(0);
X	       case 's'  : lines_to_ignore = (iteration?iteration-1:0);
X			   CursorLeft(len); CleartoEOLN();
X			   if (lines_to_ignore)
X			    printf("...skipping %d lines...",lines_to_ignore+1);
X			   else
X			    printf("...skipping one line...\n");
X			   fflush(stdout);
X			   lines_put_on_screen = 0;
X			   return(0);
X	       case 'q'  :
X	       case 'Q'  : return(TRUE);	/* get OUTTA here! */
X	       default   : if (isdigit(ch)) {
X		             Raw(ON);
X			     do {
X			       iteration = 10*iteration + (ch - '0');
X			     } while (isdigit(ch = ReadCh()));
X			     Raw(OFF);
X	                     goto loop_top;	
X			   }
X			   putchar(BEEP);	
X			   fflush(stdout);
X			   break;
X	     }
X	  } while (! okay_char);
X
X	  CursorLeft(len);		/* back up to the beginning of line */
X	  CleartoEOLN();
X	}
X
X	Write_to_screen("%s", 1, line);
X
X	lines_displayed     += 1;		   /* tossed on screen */
X	lines_put_on_screen += lines_needed;	   /* read from file   */
X
X	return (FALSE);
X}
END_OF_src/builtin.c
if test 4541 -ne `wc -c <src/builtin.c`; then
    echo shar: \"src/builtin.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/encode.c\" \(4300 characters\)
if test -f src/encode.c ; then 
  echo shar: Will not over-write existing file \"src/encode.c\"
else
sed "s/^X//" >src/encode.c <<'END_OF_src/encode.c'
X/**		encode.c		**/
X
X/** This is a heavily mangled version of the 'cypher' program written by
X    person or persons unknown.  
X
X    (C) Copyright 1986, Dave Taylor
X**/
X
X#include <stdio.h>
X#include "curses.h"
X#include "headers.h"
X
X#define RS	94
X#define RN	4
X#define RMASK	0x7fff	/* use only 15 bits */
X
Xstatic char r[RS][RN];		/* rotors */
Xstatic char ir[RS][RN];		/* inverse rotors */
Xstatic char h[RS];		/* half rotor */
Xstatic char s[RS];		/* shuffle vector */
Xstatic int  p[RN];		/* rotor indices */
X
Xstatic char the_key[SLEN];	/* unencrypted key */
Xstatic char *encrypted_key;	/* encrypted key   */
X
Xchar *getpass(), *strncpy(), *strcpy();
Xunsigned long sleep();
X
Xgetkey(send)
Xint send;
X{
X	/** this routine prompts for and returns an encode/decode
X	    key for use in the rest of the program.  If send == 1
X	    then need to mess with rawmode. **/
X
X	char buffer[NLEN];
X	int gotkey = 0, x, y;
X
X	GetXYLocation(&x,&y);
X
X	ClearLine(21);
X
X	if (send) Raw(OFF);
X
X	while ( !gotkey ) {
X	  MoveCursor(LINES-1,0);
X	  ClearLine(LINES-1);
X	  if (send)
X	    strcpy( buffer, getpass( "Enter encryption key: "));
X	  else
X	    strcpy( buffer, getpass( "Enter decryption key: "));
X	  MoveCursor(LINES-1,0);
X	  if ( strcmp( buffer, getpass( "Please enter it again: "))) {
X	    error("Your keys were not the same!");
X	    sleep(1);
X	    clear_error();
X	    continue;
X	  }
X	  strcpy(the_key, buffer);	/* save unencrypted key */
X	  makekey( buffer );
X	  gotkey = 1;
X	}
X
X	if (send) Raw(ON);
X
X	setup();		/** initialize the rotors etc. **/
X
X	ClearLine(LINES-1);		
X	clear_error();
X
X	MoveCursor(x+1,0);	/* move to 'next' line... */
X}
X
Xget_key_no_prompt()
X{
X	/** This performs the same action as get_key, but assumes that
X	    the current value of 'the_key' is acceptable.  This is used
X	    when a message is encrypted twice... **/
X
X	char buffer[SLEN];
X
X	strcpy(buffer, the_key);
X
X	makekey( buffer );
X
X	setup();
X}
X
Xencode(line)
Xchar *line;
X{
X	/** encrypt or decrypt the specified line.  Uses the previously
X	    entered key... **/
X
X	register int i, index, j, ph = 0;
X
X	for (index=0; index < strlen(line); index++) {
X	  i = (int) line[index];
X
X	  if ( (i >= ' ') && (i < '~') ) {
X	    i -= ' ';
X
X	    for ( j = 0; j < RN; j++ )		/* rotor forwards */
X	      i = r[(i+p[j])%RS][j];
X
X	    i = ((h[(i+ph)%RS])-ph+RS)%RS;	/* half rotor */
X
X	    for ( j--  ; j >= 0; j-- )		/* rotor backwards */
X	      i = (ir[i][j]+RS-p[j])%RS;
X
X	    j = 0;				/* rotate rotors */
X	    p[0]++;
X	    while ( p[j] == RS ) {
X	      p[j] = 0;
X	      j++;
X	      if ( j == RN ) break;
X	      p[j]++;
X            }
X  
X	    if ( ++ph == RS )
X	      ph = 0;
X
X	    i += ' ';
X	  }
X	  
X	  line[index] = (char) i;	/* replace with altered one */
X	}
X}
X
X
Xmakekey( rkey)
Xchar *rkey;
X{
X	/** encrypt the key using the system routine 'crypt' **/
X
X	char key[8], salt[2], *crypt();
X
X	strncpy( key, rkey, 8);
X	salt[0] = key[0];
X	salt[1] = key[1];
X	encrypted_key = crypt( key, salt);
X}
X
X/*
X * shuffle rotors.
X * shuffle each of the rotors indiscriminately.  shuffle the half-rotor
X * using a special obvious and not very tricky algorithm which is not as
X * sophisticated as the one in crypt(1) and Oh God, I'm so depressed.
X * After all this is done build the inverses of the rotors.
X */
X
Xsetup()
X{
X	register long i, j, k, temp;
X	long seed;
X
X	for ( j = 0; j < RN; j++ ) {
X		p[j] = 0;
X		for ( i = 0; i < RS; i++ )
X			r[i][j] = i;
X	}
X
X	seed = 123;
X	for ( i = 0; i < 13; i++)		/* now personalize the seed */
X	  seed = (seed*encrypted_key[i] + i) & RMASK;
X
X	for ( i = 0; i < RS; i++ )		/* initialize shuffle vector */
X	  h[i] = s[i] = i;
X
X	for ( i = 0; i < RS; i++) {		/* shuffle the vector */
X	  seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
X	  k = ((seed % 65521) & RMASK) % RS;
X	  temp = s[k];
X	  s[k] = s[i];
X	  s[i] = temp;
X	}
X
X	for ( i = 0; i < RS; i += 2 ) {	/* scramble the half-rotor */
X	  temp = h[s[i]];			/* swap rotor elements ONCE */
X	  h[s[i]] = h[s[i+1]];
X	  h[s[i+1]] = temp;
X	}
X
X	for ( j = 0; j < RN; j++) {			/* select a rotor */
X
X	  for ( i = 0; i < RS; i++) {		/* shuffle the vector */
X	    seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
X	    k = ((seed % 65521) & RMASK) % RS;
X	    temp = r[i][j];
X	    r[i][j] = r[k][j];
X	    r[k][j] = temp;
X	  }
X
X	  for ( i = 0; i < RS; i++) 		/* create inverse rotors */
X	    ir[r[i][j]][j] = i;
X       }
X}
END_OF_src/encode.c
if test 4300 -ne `wc -c <src/encode.c`; then
    echo shar: \"src/encode.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/savecopy.c\" \(4180 characters\)
if test -f src/savecopy.c ; then 
  echo shar: Will not over-write existing file \"src/savecopy.c\"
else
sed "s/^X//" >src/savecopy.c <<'END_OF_src/savecopy.c'
X/** 			savecopy.c			**/
X
X/** Save a copy of the specified message in the users savemail mailbox.
X
X         (C) Copyright 1986, Dave Taylor 			       
X**/
X
X#include "headers.h"
X#ifdef BSD
X# ifdef BSD4.1
X#  include <time.h>
X# else
X#  include <sys/time.h>
X# endif
X#else
X#  include <time.h>
X#endif
X
X#include <errno.h>
X
Xchar *format_long(), *get_arpa_date();
Xchar *error_name(), *error_description();
Xchar *ctime();
X
Xextern char in_reply_to[SLEN];	/* In-Reply-To: string */
Xextern int gotten_key;		/* for encryption      */
Xextern int errno;
X
Xchar *strcat(), *strcpy();
Xunsigned long sleep();
Xlong  time();
X
Xsave_copy(subject, to, cc, filename, original_to)
Xchar *subject, *to, *cc, *filename, *original_to;
X{
X	/** This routine appends a copy of the outgoing message to the
X	    file specified by the SAVEFILE environment variable.  **/
X
X	FILE *save,		/* file id for file to save to */
X	     *message;		/* the actual message body     */
X	long  thetime,		/* variable holder for time    */
X	      time();
X	char  buffer[SLEN],	/* read buffer 		       */
X	      savename[SLEN],	/* name of file saving into    */
X	      newbuffer[SLEN];  /* first name in 'to' line     */
X	register int i;		/* for chopping 'to' line up   */
X	int   crypted=0;	/* are we encrypting?          */
X
X	savename[0] = '\0';
X
X	if (save_by_name) {
X	  get_return_name(to, buffer, FALSE);
X	  if (strlen(buffer) == 0) {
X	    dprint1(3,"Warning: get_return_name couldn't break down %s\n", to);
X	    savename[0] = '\0';
X	  }
X	  else {
X	    sprintf(savename, "%s%s%s", folders, 
X	            lastch(folders) == '/'? "" : "/", buffer);
X
X	    if (can_access(savename, READ_ACCESS) != 0)
X	      savename[0] = '\0';
X	  }
X	}
X
X	if (strlen(savename) == 0) {
X	  if (strlen(savefile) == 0)
X	    return(error("variable 'SAVEFILE' not defined!"));
X	  strcpy(savename, savefile);
X	}
X
X	if ((errno = can_access(savename, WRITE_ACCESS))) {
X	  dprint0(2,"Error: attempt to autosave to a file that can't...\n");
X	  dprint1(2,"\tbe appended to: %s (save_copy)\n", savename);
X	  dprint2(2,"** %s - %s **\n", error_name(errno),
X		  error_description(errno));
X	  error1("permission to append to %s denied!", savename);
X	  sleep(2);
X	  return(FALSE);
X	}
X
X	if ((save = fopen(savename, "a")) == NULL) {
X	  dprint2(1,"Error: Couldn't append message to file %s (%s)\n",
X		  savename, "save_copy");
X	  dprint2(1,"** %s - %s **\n", error_name(errno),
X		  error_description(errno));
X	  error1("couldn't append to %s", savename);
X	  sleep(2);
X	  return(FALSE);
X	}
X
X	if ((message = fopen(filename, "r")) == NULL) {
X	  fclose(save);
X	  dprint1(1,"Error: Couldn't read file %s (save_copy)\n", filename);
X	  dprint2(1,"** %s - %s **\n", error_name(errno),
X		  error_description(errno));
X	  error1("couldn't read file %s!", filename);
X	  sleep(2);
X	  return(FALSE);
X	}
X
X	for (i=0; original_to[i] != '\0' && ! whitespace(original_to[i]); i++)
X	  newbuffer[i] = original_to[i];
X
X	newbuffer[i] = '\0';
X
X	tail_of(newbuffer, buffer, FALSE);
X
X	thetime = time((long *) 0);      /* dumb dumb dumb routine */
X
X	fprintf(save,"\nFrom To:%s %s", buffer, ctime(&thetime));
X
X	fprintf(save, "Date: %s\n", get_arpa_date());
X			
X	fprintf(save,"To: %s\nSubject: %s\n", 
X		format_long(to,strlen("To: ")), subject);
X
X	if (strlen(cc) > 0)
X	  fprintf(save,"Cc: %s\n", 
X		  format_long(cc, strlen("Cc:")));
X
X	if (strlen(in_reply_to) > 0)
X	  fprintf(save, "In-Reply-To: %s\n", in_reply_to);
X
X	(void) putc('\n', save);	/* put another return, please! */
X
X	/** now copy over the message... **/
X
X	while (fgets(buffer, SLEN, message) != NULL) {
X	  if (buffer[0] == '[') {
X	    if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
X	      crypted = 1;
X	    else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
X	      crypted = 0;
X	    else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0) {
X	      fclose(message);
X	      fclose(save);
X	      chown(savename, userid, groupid);	
X	      return(TRUE);
X	    }
X	  }
X	  else if (crypted) {
X	    if (! gotten_key++)
X	      getkey(ON);
X	    encode(buffer);
X	  }
X	  fputs(buffer, save);
X	}
X
X	fclose(message);
X	fclose(save);
X
X	/* make sure save file isn't owned by root! */
X	chown(savename, userid, groupid);	
X
X	return(TRUE);
X}
END_OF_src/savecopy.c
if test 4180 -ne `wc -c <src/savecopy.c`; then
    echo shar: \"src/savecopy.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"utils/Makefile\" \(4197 characters\)
if test -f utils/Makefile ; then 
  echo shar: Will not over-write existing file \"utils/Makefile\"
else
sed "s/^X//" >utils/Makefile <<'END_OF_utils/Makefile'
X#
X#  Makefile for the Elm system utilities
X#
X#         (C) Copyright 1986, Dave Taylor
X#
X#  Last modification: Sept 15th, 1986
X
XSHELL=/bin/sh
X
XDEFINE= -DBSD
XLIB2  = -lcurses
X
XCFLAGS= -O -I../hdrs
XCC=	/bin/cc
XRM= 	/bin/rm -f
XECHO=  /bin/echo
X
XOBJS=	../bin/newalias ../bin/from ../bin/newmail ../bin/answer       \
X	../bin/printmail ../bin/fastmail ../bin/readmsg                \
X	../bin/checkalias ../bin/arepdaemon ../bin/autoreply ../bin/wnewmail \
X	../bin/messages ../bin/trim-headers ../bin/listalias 
X
Xall: ${OBJS}
X
X../bin/newalias:  ../hdrs/defs.h newalias.c ../src/validname.o \
X	../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} newalias.c ../src/validname.o \
X	../src/opt_utils.o -o ../bin/newalias 
X
X../bin/from: from.c ../src/opt_utils.o ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} from.c ../src/opt_utils.o \
X	../src/string2.o -o ../bin/from
X
X../bin/newmail: ../src/opt_utils.c newmail.c ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} newmail.c \
X	../src/string2.o -o ../bin/newmail
X
X../bin/wnewmail: ../src/opt_utils.c wnewmail.c ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} ../src/opt_utils.o \
X	../src/string2.o wnewmail.c -o ../bin/wnewmail
X
X../bin/listalias: listalias.c 
X	${CC} ${CFLAGS} ${DEFINE} listalias.c -o ../bin/listalias
X
X../bin/answer: answer.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} answer.c ../src/opt_utils.o -o ../bin/answer
X
X../bin/printmail: printmail.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} printmail.c ../src/opt_utils.o \
X	-o ../bin/printmail
X
X../bin/fastmail: fastmail.c 
X	${CC} ${CFLAGS} ${DEFINE} fastmail.c ../src/opt_utils.o \
X	-o ../bin/fastmail
X
X../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o ../src/string2.o \
X	../src/opt_utils.o -o ../bin/readmsg
X
X../bin/arepdaemon: arepdaemon.c
X	${CC} ${CFLAGS} ${DEFINE} arepdaemon.c -o ../bin/arepdaemon
X
X../bin/autoreply: autoreply.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \
X	-o ../bin/autoreply
X
X../bin/checkalias: 
X	@echo ': Use /bin/sh' > ../bin/checkalias
X	@echo 'if [ "$$*" = "" ]; then' >> ../bin/checkalias
X	@echo '  echo Usage: checkalias alias \[or aliases\]' >>  \
X	      ../bin/checkalias
X	@echo '  exit 1' >> ../bin/checkalias
X	@echo 'fi' >> ../bin/checkalias
X	@echo ' '  >> ../bin/checkalias
X	@echo 'exec elm -c $$*' >> ../bin/checkalias
X	@chmod +x ../bin/checkalias
X
X../bin/messages: 
X	@echo ': Use /bin/sh' 				 > ../bin/messages
X	@echo 'if [ "$$2" != "" ]; then' 		>> ../bin/messages
X	@echo '  echo Usage: messages \{folder-name\}'  >> ../bin/messages
X	@echo '  exit 1' 				>> ../bin/messages
X	@echo 'fi' 					>> ../bin/messages
X	@echo ' '  					>> ../bin/messages
X	@echo 'if [ "$$1" = "" ]; then' 		>> ../bin/messages
X	@echo '  fname=$$MAIL' 				>> ../bin/messages
X	@echo '  optional="in your mailbox"'  		>> ../bin/messages
X	@echo 'else'		 			>> ../bin/messages
X	@echo '  fname=$$1'				>> ../bin/messages
X	@echo '  optional="in folder $$1"' 		>> ../bin/messages
X	@echo 'fi'	       				>> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'mcount=`egrep "^From " $$fname | wc -l`' >> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'if [ $$mcount = 1 ];then'		>> ../bin/messages
X	@echo '  echo There is $$mcount message $$optional' >> ../bin/messages
X	@echo 'else'					>> ../bin/messages
X	@echo '  echo There are $$mcount messages $$optional' >> ../bin/messages
X	@echo 'fi'					>> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'exit 0'					>> ../bin/messages
X	@chmod +x ../bin/messages
X
X../bin/trim-headers:
X	@cp trim-headers ../bin/trim-headers
X	@chmod +x ../bin/trim-headers
X
X../src/validname.o: ../src/validname.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils)
X
X../src/opt_utils.o: ../src/opt_utils.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils)
X
X../src/getopt.o: ../src/getopt.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils)
X
X../src/string2.o: ../src/string2.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils)
X
Xclean:
X	${RM} *.o ${OBJS} ../bin/utils
X
Xlint:
X	lint -p -I../hdrs *.c > LINT.OUT
END_OF_utils/Makefile
if test 4197 -ne `wc -c <utils/Makefile`; then
    echo shar: \"utils/Makefile\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"utils/Makefile.mstr\" \(4192 characters\)
if test -f utils/Makefile.mstr ; then 
  echo shar: Will not over-write existing file \"utils/Makefile.mstr\"
else
sed "s/^X//" >utils/Makefile.mstr <<'END_OF_utils/Makefile.mstr'
X#
X#  Makefile for the Elm system utilities
X#
X#         (C) Copyright 1986, Dave Taylor
X#
X#  Last modification: Sept 15th, 1986
X
XSHELL=/bin/sh
X
XDEFINE= >os-define<
XLIB2  = >lib2<
X
XCFLAGS= -O -I../hdrs
XCC=	>cc<
XRM= 	>rm<
XECHO=  /bin/echo
X
XOBJS=	../bin/newalias ../bin/from ../bin/newmail ../bin/answer       \
X	../bin/printmail ../bin/fastmail ../bin/readmsg                \
X	../bin/checkalias ../bin/arepdaemon ../bin/autoreply ../bin/wnewmail \
X	../bin/messages ../bin/trim-headers ../bin/listalias 
X
Xall: ${OBJS}
X
X../bin/newalias:  ../hdrs/defs.h newalias.c ../src/validname.o \
X	../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} newalias.c ../src/validname.o \
X	../src/opt_utils.o -o ../bin/newalias 
X
X../bin/from: from.c ../src/opt_utils.o ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} from.c ../src/opt_utils.o \
X	../src/string2.o -o ../bin/from
X
X../bin/newmail: ../src/opt_utils.c newmail.c ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} newmail.c \
X	../src/string2.o -o ../bin/newmail
X
X../bin/wnewmail: ../src/opt_utils.c wnewmail.c ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} ../src/opt_utils.o \
X	../src/string2.o wnewmail.c -o ../bin/wnewmail
X
X../bin/listalias: listalias.c 
X	${CC} ${CFLAGS} ${DEFINE} listalias.c -o ../bin/listalias
X
X../bin/answer: answer.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} answer.c ../src/opt_utils.o -o ../bin/answer
X
X../bin/printmail: printmail.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} printmail.c ../src/opt_utils.o \
X	-o ../bin/printmail
X
X../bin/fastmail: fastmail.c 
X	${CC} ${CFLAGS} ${DEFINE} fastmail.c ../src/opt_utils.o \
X	-o ../bin/fastmail
X
X../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o ../src/string2.o
X	${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o ../src/string2.o \
X	../src/opt_utils.o -o ../bin/readmsg
X
X../bin/arepdaemon: arepdaemon.c
X	${CC} ${CFLAGS} ${DEFINE} arepdaemon.c -o ../bin/arepdaemon
X
X../bin/autoreply: autoreply.c ../src/opt_utils.o
X	${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \
X	-o ../bin/autoreply
X
X../bin/checkalias: 
X	@echo ': Use /bin/sh' > ../bin/checkalias
X	@echo 'if [ "$$*" = "" ]; then' >> ../bin/checkalias
X	@echo '  echo Usage: checkalias alias \[or aliases\]' >>  \
X	      ../bin/checkalias
X	@echo '  exit 1' >> ../bin/checkalias
X	@echo 'fi' >> ../bin/checkalias
X	@echo ' '  >> ../bin/checkalias
X	@echo 'exec elm -c $$*' >> ../bin/checkalias
X	@chmod +x ../bin/checkalias
X
X../bin/messages: 
X	@echo ': Use /bin/sh' 				 > ../bin/messages
X	@echo 'if [ "$$2" != "" ]; then' 		>> ../bin/messages
X	@echo '  echo Usage: messages \{folder-name\}'  >> ../bin/messages
X	@echo '  exit 1' 				>> ../bin/messages
X	@echo 'fi' 					>> ../bin/messages
X	@echo ' '  					>> ../bin/messages
X	@echo 'if [ "$$1" = "" ]; then' 		>> ../bin/messages
X	@echo '  fname=$$MAIL' 				>> ../bin/messages
X	@echo '  optional="in your mailbox"'  		>> ../bin/messages
X	@echo 'else'		 			>> ../bin/messages
X	@echo '  fname=$$1'				>> ../bin/messages
X	@echo '  optional="in folder $$1"' 		>> ../bin/messages
X	@echo 'fi'	       				>> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'mcount=`egrep "^From " $$fname | wc -l`' >> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'if [ $$mcount = 1 ];then'		>> ../bin/messages
X	@echo '  echo There is $$mcount message $$optional' >> ../bin/messages
X	@echo 'else'					>> ../bin/messages
X	@echo '  echo There are $$mcount messages $$optional' >> ../bin/messages
X	@echo 'fi'					>> ../bin/messages
X	@echo ' '					>> ../bin/messages
X	@echo 'exit 0'					>> ../bin/messages
X	@chmod +x ../bin/messages
X
X../bin/trim-headers:
X	@cp trim-headers ../bin/trim-headers
X	@chmod +x ../bin/trim-headers
X
X../src/validname.o: ../src/validname.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils)
X
X../src/opt_utils.o: ../src/opt_utils.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils)
X
X../src/getopt.o: ../src/getopt.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils)
X
X../src/string2.o: ../src/string2.c ../hdrs/defs.h
X	@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils)
X
Xclean:
X	${RM} *.o ${OBJS} ../bin/utils
X
Xlint:
X	lint -p -I../hdrs *.c > LINT.OUT
END_OF_utils/Makefile.mstr
if test 4192 -ne `wc -c <utils/Makefile.mstr`; then
    echo shar: \"utils/Makefile.mstr\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"utils/autoreply.c\" \(4689 characters\)
if test -f utils/autoreply.c ; then 
  echo shar: Will not over-write existing file \"utils/autoreply.c\"
else
sed "s/^X//" >utils/autoreply.c <<'END_OF_utils/autoreply.c'
X/**			autoreply.c			**/
X
X/** This is the front-end for the autoreply system, and performs two 
X    functions: it either adds the user to the list of people using the
X    autoreply function (starting the daemon if no-one else) or removes
X    a user from the list of people.
X
X    Usage:  autoreply filename
X	    autoreply "off"
X	or  autoreply		[to find current status]
X    
X    (C) 1986, Dave Taylor
X**/
X
X#include <stdio.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include "defs.h"
X
Xstatic char ident[] = { WHAT_STRING };
X
X#define  tempdir	"/tmp/arep"		/* file prefix          */
X#define  autoreply_file	"/etc/autoreply.data"   /* autoreply data file  */
X
Xextern   int errno;				/* system error code    */
Xchar     username[NLEN];			/* login name of user   */
X
Xmain(argc, argv)
Xint    argc;
Xchar *argv[];
X{
X	char filename[SLEN];
X
X	if (argc > 2) {
X	  printf("Usage: %s <filename>\tto start autoreply,\n", argv[0]);
X	  printf("       %s off\t\tto turn off autoreply\n", argv[0]);
X	  printf("   or  %s    \t\tto check current status\n", argv[0]);
X	  exit(1);
X	}
X
X	(void) cuserid(username);
X
X	if (argc == 1 || strcmp(argv[1], "off") == 0) 
X	  remove_user((argc == 1));
X	else {
X	  strcpy(filename, argv[1]);
X	  if (access(filename,READ_ACCESS) != 0) {
X	    printf("Error: Can't read file '%s'\n", filename);
X	    exit(1);
X	  }
X	  
X	  if (filename[0] != '/') /* prefix home directory */
X	    sprintf(filename,"%s/%s", getenv("HOME"), argv[1]);
X
X	  add_user(filename);
X	}
X
X	exit(0);
X}
X
Xremove_user(stat_only)
Xint stat_only;
X{
X	/** Remove the user from the list of currently active autoreply 
X	    people.  If 'stat_only' is set, then just list the name of
X	    the file being used to autoreply with, if any. **/
X
X	FILE *temp, *repfile;
X	char  tempfile[SLEN], user[SLEN], filename[SLEN];
X	int   c, copied = 0, found = 0;
X	long  filesize, bytes();
X
X	if (! stat_only) {
X	  sprintf(tempfile, "%s.%06d", tempdir, getpid());
X
X	  if ((temp = fopen(tempfile, "w")) == NULL) {
X	    printf("Error: couldn't open tempfile '%s'.  Not removed\n",
X		    tempfile);
X	    exit(1);
X	  }
X	}
X
X	if ((repfile = fopen(autoreply_file, "r")) == NULL) {
X	  if (stat_only) {
X	    printf("You're not currently autoreplying to mail.\n");
X	    exit(0);
X	  }
X	  printf("No-one is autoreplying to their mail!\n");
X	  exit(0);
X	}
X
X	/** copy out of real replyfile... **/
X
X	while (fscanf(repfile, "%s %s %ld", user, filename, &filesize) != EOF) 
X
X	  if (strcmp(user, username) != 0) {
X	    if (! stat_only) {
X	      copied++;
X	      fprintf(tempfile, "%s %s %ld\n", user, filename, filesize);
X	    }
X	  }
X	  else {
X	    if (stat_only) {
X	      printf("You're currently autoreplying to mail with the file %s\n",		      filename); 
X	      exit(0);
X	    }
X	    found++;
X	  }
X
X	fclose(temp);
X	fclose(repfile);
X
X	if (! found) {
X	  printf("You're not currently autoreplying to mail%s\n",
X		  stat_only? "." : "!");
X	  if (! stat_only)
X	    unlink(tempfile);
X	  exit(! stat_only);
X	}
X
X	/** now copy tempfile back into replyfile **/
X
X	if (copied == 0) {	/* removed the only person! */
X	  unlink(autoreply_file);
X	}
X	else {			/* save everyone else   */
X	  
X	  if ((temp = fopen(tempfile,"r")) == NULL) {
X	    printf("Error: couldn't reopen tempfile '%s'.  Not removed.\n",
X		    tempfile);
X	    unlink(tempfile);
X	    exit(1);
X	  }
X
X	  if ((repfile = fopen(autoreply_file, "w")) == NULL) {
X	    printf(
X          "Error: couldn't reopen autoreply file for writing!  Not removed.\n");
X	    unlink(tempfile);
X	    exit(1);
X	  }
X
X	  while ((c = getc(temp)) != EOF)
X	    putc(c, repfile);
X
X	  fclose(temp);
X	  fclose(repfile);
X	
X	}
X	unlink(tempfile);
X
X	if (found > 1)
X	  printf("Warning: your username appeared %d times!!   Removed all\n", 
X		  found);
X	else
X	  printf("You've been removed from the autoreply table.\n");
X}
X
Xadd_user(filename)
Xchar *filename;
X{
X	/** add the user to the autoreply file... **/
X
X	FILE *repfile;
X	char  mailfile[SLEN];
X	long  bytes();
X
X	if ((repfile = fopen(autoreply_file, "a")) == NULL) {
X	  printf("Error: couldn't open the autoreply file!  Not added\n");
X	  exit(1);
X	}
X	
X	sprintf(mailfile,"%s/%s", mailhome, username);
X
X	fprintf(repfile,"%s %s %ld\n", username, filename, bytes(mailfile));
X
X	fclose(repfile);
X
X	printf("You've been added to the autoreply system.\n");
X}
X
X
Xlong
Xbytes(name)
Xchar *name;
X{
X	/** return the number of bytes in the specified file.  This
X	    is to check to see if new mail has arrived....  **/
X
X	int ok = 1;
X	extern int errno;	/* system error number! */
X	struct stat buffer;
X
X	if (stat(name, &buffer) != 0)
X	  if (errno != 2)
X	   exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
X	  else
X	    ok = 0;
X	
X	return(ok ? buffer.st_size : 0L);
X}
END_OF_utils/autoreply.c
if test 4689 -ne `wc -c <utils/autoreply.c`; then
    echo shar: \"utils/autoreply.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 19\).
cp /dev/null ark3isdone
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