[mod.sources] v09i006: ELM Mail System, Part06/19

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

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

#! /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 6 (of 19)."
# Contents:  hdrs/defs.h hdrs/sysdefs.h hdrs/sysdefs.master
#   hdrs/sysdefs.old src/file.c src/initialize.uts src/limit.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"hdrs/defs.h\" \(7730 characters\)
if test -f hdrs/defs.h ; then 
  echo shar: Will not over-write existing file \"hdrs/defs.h\"
else
sed "s/^X//" >hdrs/defs.h <<'END_OF_hdrs/defs.h'
X/**		defs.h			**/
X
X/**  define file for ELM mail system.  **/
X
X/**  (C) Copyright 1985 Dave Taylor    **/
X
X#include "sysdefs.h"	/* system/configurable defines */
X
X#define VERSION		"1.5" /* Version number!  WHAT_STRING should agree */
X
X#define WHAT_STRING	"@(#) Version 1.5, January, 1987"
X
X#define KLICK		10
X
X#define SLEN		256	    /* long for ensuring no overwrites... */
X#define SHORT		5	    /* super short strings!		  */
X#define NLEN		20	    /* name length for aliases            */
X#define SHORT_SLEN      40
X#define STRING		100	/* reasonable string length for most..      */
X#define LONG_SLEN	250	/* for mail addresses from remote machines! */
X#define LONG_STRING	500	/* even longer string for group expansion   */
X#define VERY_LONG_STRING 2500	/* huge string for group alias expansion    */
X
X#define BREAK		'\0'  		/* default interrupt    */
X#define BACKSPACE	'\b'     	/* backspace character  */
X#define TAB		'\t'            /* tab character        */
X#define RETURN		'\r'     	/* carriage return char */
X#define LINE_FEED	'\n'     	/* line feed character  */
X#define FORMFEED	'\f'     	/* form feed (^L) char  */
X#define COMMA		','		/* comma character      */
X#define SPACE		' '		/* space character      */
X#define DOT		'.'		/* period/dot character */
X#define BANG		'!'		/* exclaimation mark!   */
X#define AT_SIGN		'@'		/* at-sign character    */
X#define PERCENT		'%'		/* percent sign char.   */
X#define COLON		':'		/* the colon ..		*/
X#define BACKQUOTE	'`'		/* backquote character  */
X#ifdef TILDE
X# undef TILDE
X#endif
X#define TILDE		'~'		/* escape character~    */
X#define ESCAPE		'\033'		/* the escape		*/
X
X#define NO_OP_COMMAND	'\0'		/* no-op for timeouts   */
X
X#define STANDARD_INPUT  0		/* file number of stdin */
X
X#ifndef TRUE
X#define TRUE		1
X#define FALSE		0
X#endif
X
X#define NO		0
X#define YES		1
X#define MAYBE		2		/* a definite define, eh?  */
X#define FORM		3		/*      <nevermind>        */
X#define PREFORMATTED	4		/* forwarded form...       */
X
X#define PAD		0		/* for printing name of    */
X#define FULL		1		/*   the sort we're using  */
X
X#define OUTGOING	0		/* defines for lock file   */
X#define INCOMING	1		/* creation..see lock()    */
X
X#define SH		0		/* defines for system_call */
X#define USER_SHELL	1		/* to work correctly!      */
X
X#define EXECUTE_ACCESS	01		/* These five are 	   */
X#define WRITE_ACCESS	02		/*    for the calls	   */
X#define READ_ACCESS	04		/*       to access()       */
X#define ACCESS_EXISTS	00		/*           <etc>         */
X#define EDIT_ACCESS	06		/*  (this is r+w access)   */
X
X#define BIG_NUM		999999		/* big number!             */
X#define BIGGER_NUM	9999999 	/* bigger number!          */
X
X#define START_ENCODE	"[encode]"
X#define END_ENCODE	"[clear]"
X
X#define DONT_SAVE	"[no save]"
X
X#define alias_file	".aliases"
X#define group_file	".groups"
X#define system_file	".systems"
X
X/** some defines for the 'userlevel' variable... **/
X
X#define RANK_AMATEUR	0
X#define AMATEUR		1
X#define OKAY_AT_IT	2
X#define GOOD_AT_IT	3
X#define EXPERT		4
X#define SUPER_AT_IT	5
X
X/** some defines for the "status" field of the header record **/
X
X#define TAGGED		1		/* these are bit masks */
X#define DELETED		2
X#define EXPIRED		4
X#define ACTION		8
X#define NEW		16
X#define PRIORITY	32
X#define FORM_LETTER	64
X#define VISIBLE		128
X
X#define UNDELETE	0		/* purely for ^U function... */
X
X/** some months... **/
X
X#define JANUARY		0			/* months of the year */
X#define FEBRUARY	1
X#define MARCH		2
X#define APRIL		3
X#define MAY		4
X#define JUNE		5
X#define JULY		6
X#define AUGUST		7
X#define SEPTEMBER	8
X#define OCTOBER		9
X#define NOVEMBER	10
X#define DECEMBER	11
X
X#define equal(s,w)	(strcmp(s,w) == 0)
X#define min(a,b)	a < b? a : b
X#define ctrl(c)	        c - 'A' + 1	/* control character mapping */
X#define plural(n)	n == 1 ? "" : "s"
X#define lastch(s)	s[strlen(s)-1]
X#define no_ret(s)	if (lastch(s) == '\n') lastch(s) = '\0' 
X#define first_word(s,w) (strncmp(s,w, strlen(w)) == 0)
X#define ClearLine(n)	MoveCursor(n,0); CleartoEOLN()
X#define whitespace(c)	(c == ' ' || c == '\t')
X#define quote(c)	(c == '"' || c == '\'') 
X#define onoff(n)	(n == 0 ? "OFF" : "ON")
X
X/** The next function is so certain commands can be processed from the showmsg
X    routine without rewriting the main menu in between... **/
X
X#define special(c)	(c == 'j' || c == 'k')
X
X/** and a couple for dealing with status flags... **/
X
X#define ison(n,mask)	(n & mask)
X#define isoff(n,mask)	(~ison(n, mask))
X
X#define setit(n,mask)		n |= mask
X#define clearit(n, mask)	n &= ~mask
X
X/** a few for the usage of function keys... **/
X
X#define f1	1
X#define f2	2
X#define f3	3
X#define f4	4
X#define f5	5
X#define f6	6
X#define f7	7
X#define f8	8
X
X#define MAIN	0
X#define ALIAS   1
X#define YESNO	2
X#define CHANGE  3
X#define READ	4
X
X#define MAIN_HELP    0
X#define ALIAS_HELP   1
X#define OPTIONS_HELP 2
X
X/** some possible sort styles... **/
X
X#define REVERSE		-		/* for reverse sorting           */
X#define SENT_DATE	1		/* the date message was sent     */
X#define RECEIVED_DATE	2		/* the date message was received */
X#define SENDER		3		/* the name/address of sender    */
X#define SIZE		4		/* the # of lines of the message */
X#define SUBJECT		5		/* the subject of the message    */
X#define STATUS		6		/* the status (deleted, etc)     */
X
X/* some stuff for our own malloc call - pmalloc */
X
X#define PMALLOC_THRESHOLD	256	/* if greater, then just use malloc */
X#define PMALLOC_BUFFER_SIZE    2048	/* internal [memory] buffer size... */
X
X/* wouldn't it be nice to have variable argument macros... */
X
X#define dprint0(n,s)	     if (debug >= n) { \
X				fprintf(debugfile, s); fflush(debugfile); }
X
X#define dprint1(n,s,a)	     if (debug >= n) { \
X				fprintf(debugfile, s, a);  fflush(debugfile); }
X
X#define dprint2(n,s,a,b)     if (debug >= n) { \
X			        fprintf(debugfile, s, a, b); fflush(debugfile);}
X
X#define dprint3(n,s,a,b,c)   if (debug >= n) { fprintf(debugfile, \
X				s, a, b, c); fflush(debugfile); }
X
X#define dprint4(n,s,a,b,c,d)  if (debug >= n) { fprintf(debugfile, \
X				s, a, b, c, d); fflush(debugfile); }
X
X#define dprint5(n,s,a,b,c,d,e) if (debug >= n) { fprintf(debugfile, \
X			        s, a, b, c, d, e); fflush(debugfile); }
X
X#define dprint6(n,s,a,b,c,d,e,f) if (debug >= n) { fprintf(debugfile, \
X			        s, a, b, c, d, e, f); fflush(debugfile); }
X
X/* I guess this corrects it, though.  Wretched stuff though! */
X
X/* some random records... */
X
Xstruct date_rec {
X	int  month;		/** this record stores a **/
X	int  day;		/**   specific date and  **/
X	int  year;		/**     time...		 **/
X	int  hour;
X	int  minute;
X       };
X
Xstruct header_rec {
X	int  lines;		/** # of lines in the message  **/
X	int  status;		/** Urgent, Deleted, Expired?  **/
X	int  index_number;	/** relative loc in file...    **/
X	long offset;		/** offset in bytes of message **/
X	struct date_rec received; /** when elm received here   **/
X	char from[STRING];	/** who sent the message?      **/
X	char to[STRING];	/** who it was sent to	       **/
X	char dayname[8];	/**  when the                  **/
X	char month[10];		/**        message             **/
X	char day[3];		/**          was 	       **/
X	char year[5];		/**            sent            **/
X	char time[NLEN];	/**              to you!       **/
X	char subject[STRING];   /** The subject of the mail    **/
X       };
X
Xstruct alias_rec {
X	char   name[NLEN];	/* alias name 			     */
X	long   byte;		/* offset into data file for address */
X       };
X
Xstruct lsys_rec {
X	char   name[NLEN];	/* name of machine connected to      */
X	struct lsys_rec *next;	/* linked list pointer to next       */
X       };
X
Xstruct addr_rec {
X	 char   address[NLEN];	/* machine!user you get mail as      */
X	 struct addr_rec *next;	/* linked list pointer to next       */
X	};
X
X#ifdef SHORTNAMES	/* map long names to shorter ones */
X# include <shortnames.h>
X#endif
END_OF_hdrs/defs.h
if test 7730 -ne `wc -c <hdrs/defs.h`; then
    echo shar: \"hdrs/defs.h\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"hdrs/sysdefs.h\" \(7274 characters\)
if test -f hdrs/sysdefs.h ; then 
  echo shar: Will not over-write existing file \"hdrs/sysdefs.h\"
else
sed "s/^X//" >hdrs/sysdefs.h <<'END_OF_hdrs/sysdefs.h'
X/**			sysdefs.h			**/
X
X/**  System level, configurable, defines for the ELM mail system.  **/
X
X/**  (C) Copyright 1986 Dave Taylor                                **/
X
X/** Define the following if you think that the information in messages
X    that have "Reply-To:" and/or "From:" fields with addresses will
X    contain valid addressing information.  If this isn't defined, the
X    calculated return address will ALWAYS be used instead.  (note that
X    this doesn't necessarily preclude the use of G)roup replies).
X**/
X
X/** #define USE_EMBEDDED_ADDRESSES **/	
X
X
X#define FIND_DELTA	10		/* byte region where the binary search
X					   on the path alias file is fruitless 
X                                           (can't be within this boundary)    */
X
X#define MAX_SALIASES	503	/* number of system aliases allowed      */
X#define MAX_UALIASES	251	/* number of user aliases allowed 	 */
X#define MAX_IN_WEEDLIST 150	/* max headers to weed out               */
X
X#define MAX_HOPS	35	/* max hops in return addr to E)veryone  */
X
X#define MAX_ATTEMPTS	6	/* #times to attempt lock file creation */
X
X/** see leavembox.c to determine if this should be defined or not....The 
X    default is to NOT have it defined.
X**/
X
X/** #define REMOVE_AT_LAST **/
X
X#define DEFAULT_BATCH_SUBJECT  "no subject (file transmission)"
X
X/** If you want to have the mailer know about valid mailboxes on the
X    host machine (assumes no delivery agent aliases) then you should
X    undefine this (the default is to have it defined)...
X**/
X
X#define NOCHECK_VALIDNAME
X
X/** If your machine doesn't have virtual memory (specifically the vfork() 
X    command) then you should define the following....		
X**/
X
X/** #define NO_VM **/
X
X/** If you're running sendmail, or another transport agent that can 
X    handle the blind-carbon-copy list define the following
X**/
X
X#define ALLOW_BCC
X
X/** If you have pathalias, can we get to it as a DBM file??? **/
X
X/** #define USE_DBM **/
X
X/** If you want the mailer to check the pathalias database BEFORE it
X    looks to see if a specified machine is in the L.sys database (in
X    some cases routing is preferable to direct lines) then you should
X    define the following...
X**/
X
X/** #define LOOK_CLOSE_AFTER_SEARCH **/
X
X
X/** If you'd rather the program automatically used the 'uuname' command
X    to figure out what machines it talks to (instead of trying to get
X    it from L.sys first) then define the following...
X**/
X
X#define USE_UUNAME
X
X/** If you don't want the program to even TOUCH the addresses handed to 
X    it - deferring all expansion to sendmail/smail, then define the following;
X**/
X
X/** #define DONT_TOUCH_ADDRESSES **/
X
X/** Perhaps you'd also like the program not to try to minimize the addresses
X    stored when you 'alias current message'.  If so, define the following
X**/
X
X/** #define DONT_OPTIMIZE_RETURN **/
X
X/** If you'd like "newmail" to automatically go into background when you
X    start it up (instead of the "newmail &" junk with the process id output,
X    then define the following...
X**/
X
X#define AUTO_BACKGROUND
X
X/** If you'd rather your mail transport agent (ie sendmail) put the From:
X    line into the message, define the following...
X**/
X
X#define DONT_ADD_FROM
X
X/** If your machine prefers the Internet notation of user@host for the
X    From: line and addresses, define the following...(the default is to 
X    use this rather than the USENET notation - check your pathalias file!)
X
X**/
X
X#define INTERNET_ADDRESS_FORMAT
X
X/** If you're on a machine that prefers UUCP to Internet addresses, then
X    define the following (the basic change is that on a machine that
X    receives messages of the form <path>!user@<localhost> the displayed
X    address will be <path>!user instead of user@<localhost>.
X
X    BOGUS_INTERNET is the address that your local system appends to 
X    messages occasionally.  The algorithm is simply to REMOVE the
X    BOGUS_INTERNET string.  This is horrible.  *sigh*
X
X**/
X
X#define PREFER_UUCP
X#define BOGUS_INTERNET	"@hplabs.HP.COM"
X
X/** If you're running ACSNET and/or want to have your domain name
X    attached to your hostname on outbound mail then you can define
X    the following (default are not defined)
X**/
X
X/** #define USE_DOMAIN **/
X#define DOMAIN		"<enter your domain here>"
X
X/** If you are going to be running the mailer with setgid mail (or
X    something similar) you'll need to define the following to ensure
X    that the users mailbox in the spool directory has the correct
X    group (NOT the users group)
X**/
X
X#define SAVE_GROUP_MAILBOX_ID
X
X/** If you want a neat feature that enables scanning of the message
X    body for entries to add to the users ".calendar" (or whatever)
X    file, define this.
X**/
X
X#define ENABLE_CALENDAR
X#define dflt_calendar_file	"calendar"	/* in HOME directory */
X
X/** If you want to implement 'site hiding' in the mail, then you'll need to
X    uncomment the following lines and set them to reasonable values.  See 
X    the configuration guide for more details....
X**/
X
X/****************************************************************************
X
X#undef    DONT_ADD_FROM		
X
X#define   SITE_HIDING
X#define   HIDDEN_SITE_NAME	"fake-machine-name"
X#define   HIDDEN_SITE_USERS	"/usr/mail/lists/hidden_site_users"
X
X****************************************************************************/
X
X/** Do we have the 'gethostname()' call?  If not, define the following **/
X/** #define NEED_GETHOSTNAME **/
X
X/** are you stuck on a machine that has short names?  If so, define the
X    following **/
X
X/** #define SHORTNAMES **/
X
X#define NOTES_HEADER		"/***** "
X#define NOTES_FOOTER		"/* ---------- */"
X
X#ifdef BSD
X# define system_hash_file	"/usr/spool/mail/.alias_hash"
X# define system_data_file	"/usr/spool/mail/.alias_data"
X#else
X# define system_hash_file	"/usr/mail/.alias_hash"
X# define system_data_file	"/usr/mail/.alias_data"
X#endif
X
X#define pathfile		"/usr/lib/nmail.paths"
X#define domains			"/usr/lib/domains"
X
X#define Lsys			"/usr/lib/uucp/L.sys"
X
X/** where to put the output of the elm -d command... (in home dir) **/
X#define DEBUG		"ELM:debug.info"
X#define OLDEBUG		"ELM:debug.last"
X
X#define temp_file	"/tmp/snd."
X#define temp_form_file	"/tmp/form."
X#define temp_mbox	"/tmp/mbox."
X#define temp_print      "/tmp/print."
X#define temp_uuname	"/tmp/uuname."
X#define mailtime_file	".last_read_mail"
X#define readmsg_file	".readmsg"
X
X#define emacs_editor	"/usr/local/bin/emacs"
X
X#ifdef BSD
X# define default_editor	"/usr/ucb/vi"
X# define mailhome	"/usr/spool/mail/"
X#else
X# define default_editor	"/usr/bin/vi"
X# define mailhome	"/usr/mail/"
X#endif
X
X# define default_pager	"builtin"
X
X#define sendmail	"/usr/lib/sendmail"
X#define smflags		"-oi -oem"	/* ignore dots and mail back errors */
X#define mailer		"/bin/rmail"
X#ifdef BSD
X# define mailx		"/usr/ucb/Mail"
X#else
X# define mailx		"/usr/bin/mailx"
X#endif
X
X#define helphome	"/usr/local/lib"
X#define helpfile	"elm-help"
X
X#define ELMRC_INFO	"/usr/local/lib/elmrc-info"
X
X#define elmrcfile	"/.elmrc"
X#define mailheaders	".elmheaders"
X#define dead_letter	"Cancelled.mail"
X
X#define unedited_mail	"emergency.mbox"
X
X#define newalias	"newalias -q 1>&2 > /dev/null"
X#define readmsg		"readmsg"
X
X#define remove		"/bin/rm -f"		/* how to remove a file */
X#define cat		"/bin/cat"		/* how to display files */
X#define uuname		"uuname"		/* how to get a uuname  */
END_OF_hdrs/sysdefs.h
if test 7274 -ne `wc -c <hdrs/sysdefs.h`; then
    echo shar: \"hdrs/sysdefs.h\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"hdrs/sysdefs.master\" \(7256 characters\)
if test -f hdrs/sysdefs.master ; then 
  echo shar: Will not over-write existing file \"hdrs/sysdefs.master\"
else
sed "s/^X//" >hdrs/sysdefs.master <<'END_OF_hdrs/sysdefs.master'
X/**			sysdefs.h			**/
X
X/**  System level, configurable, defines for the ELM mail system.  **/
X
X/**  (C) Copyright 1986 Dave Taylor                                **/
X
X/** Define the following if you think that the information in messages
X    that have "Reply-To:" and/or "From:" fields with addresses will
X    contain valid addressing information.  If this isn't defined, the
X    calculated return address will ALWAYS be used instead.  (note that
X    this doesn't necessarily preclude the use of G)roup replies).
X**/
X
X#define USE_EMBEDDED_ADDRESSES	
X
X
X#define FIND_DELTA	10		/* byte region where the binary search
X					   on the path alias file is fruitless 
X                                           (can't be within this boundary)    */
X
X#define MAX_SALIASES	>503<	/* number of system aliases allowed      */
X#define MAX_UALIASES	>251<	/* number of user aliases allowed 	 */
X#define MAX_IN_WEEDLIST 150	/* max headers to weed out               */
X
X#define MAX_HOPS	35	/* max hops in return addr to E)veryone  */
X
X#define MAX_ATTEMPTS	>6<	/* #times to attempt lock file creation */
X
X/** see leavembox.c to determine if this should be defined or not....The 
X    default is to NOT have it defined.
X**/
X
X#define REMOVE_AT_LAST
X
X#define DEFAULT_BATCH_SUBJECT  "no subject (file transmission)"
X
X/** If you want to have the mailer know about valid mailboxes on the
X    host machine (assumes no delivery agent aliases) then you should
X    undefine this (the default is to have it defined)...
X**/
X
X#define NOCHECK_VALIDNAME
X
X/** If your machine doesn't have virtual memory (specifically the vfork() 
X    command) then you should define the following....		
X**/
X
X/** #define NO_VM **/
X
X/** If you're running sendmail, or another transport agent that can 
X    handle the blind-carbon-copy list define the following
X**/
X
X/** #define ALLOW_BCC **/
X
X/** If you have pathalias, can we get to it as a DBM file??? **/
X
X/** #define USE_DBM **/
X
X/** If you want the mailer to check the pathalias database BEFORE it
X    looks to see if a specified machine is in the L.sys database (in
X    some cases routing is preferable to direct lines) then you should
X    define the following...
X**/
X
X#define LOOK_CLOSE_AFTER_SEARCH
X
X
X/** If you'd rather the program automatically used the 'uuname' command
X    to figure out what machines it talks to (instead of trying to get
X    it from L.sys first) then define the following...
X**/
X
X#define USE_UUNAME
X
X/** If you don't want the program to even TOUCH the addresses handed to 
X    it - deferring all expansion to sendmail/smail, then define the following;
X**/
X
X/** #define DONT_TOUCH_ADDRESSES **/
X
X/** Perhaps you'd also like the program not to try to minimize the addresses
X    stored when you 'alias current message'.  If so, define the following
X**/
X
X/** #define DONT_OPTIMIZE_RETURN **/
X
X/** If you'd like "newmail" to automatically go into background when you
X    start it up (instead of the "newmail &" junk with the process id output,
X    then define the following...
X**/
X
X#define AUTO_BACKGROUND
X
X/** If you'd rather your mail transport agent (ie sendmail) put the From:
X    line into the message, define the following...
X**/
X
X#define DONT_ADD_FROM
X
X/** If your machine prefers the Internet notation of user@host for the
X    From: line and addresses, define the following...(the default is to 
X    use this rather than the USENET notation - check your pathalias file!)
X
X**/
X
X#define INTERNET_ADDRESS_FORMAT
X
X/** If you're on a machine that prefers UUCP to Internet addresses, then
X    define the following (the basic change is that on a machine that
X    receives messages of the form <path>!user@<localhost> the displayed
X    address will be <path>!user instead of user@<localhost>.
X
X    BOGUS_INTERNET is the address that your local system appends to 
X    messages occasionally.  The algorithm is simply to REMOVE the
X    BOGUS_INTERNET string.  This is horrible.  *sigh*
X
X**/
X
X#define PREFER_UUCP
X#define BOGUS_INTERNET	"@hplabs.HP.COM"
X
X/** If you're running ACSNET and/or want to have your domain name
X    attached to your hostname on outbound mail then you can define
X    the following (default are not defined)
X**/
X
X#define USE_DOMAIN
X#define DOMAIN		"<enter your domain here>"
X
X/** If you are going to be running the mailer with setgid mail (or
X    something similar) you'll need to define the following to ensure
X    that the users mailbox in the spool directory has the correct
X    group (NOT the users group)
X**/
X
X#define SAVE_GROUP_MAILBOX_ID
X
X/** If you want a neat feature that enables scanning of the message
X    body for entries to add to the users ".calendar" (or whatever)
X    file, define this.
X**/
X
X#define ENABLE_CALENDAR
X#define dflt_calendar_file	"calendar"	/* in HOME directory */
X
X/** If you want to implement 'site hiding' in the mail, then you'll need to
X    uncomment the following lines and set them to reasonable values.  See 
X    the configuration guide for more details....
X**/
X
X/****************************************************************************
X
X#undef    DONT_ADD_FROM		
X
X#define   SITE_HIDING
X#define   HIDDEN_SITE_NAME	"fake-machine-name"
X#define   HIDDEN_SITE_USERS	"/usr/mail/lists/hidden_site_users"
X
X****************************************************************************/
X
X/** Do we have the 'gethostname()' call?  If not, define the following **/
X/** #define NEED_GETHOSTNAME **/
X
X/** are you stuck on a machine that has short names?  If so, define the
X    following **/
X
X/** #define SHORTNAMES **/
X
X#define NOTES_HEADER		"/***** "
X#define NOTES_FOOTER		"/* ---------- */"
X
X#ifdef BSD
X# define system_hash_file	"/usr/spool/mail/.alias_hash"
X# define system_data_file	"/usr/spool/mail/.alias_data"
X#else
X# define system_hash_file	"/usr/mail/.alias_hash"
X# define system_data_file	"/usr/mail/.alias_data"
X#endif
X
X#define pathfile		"/usr/lib/nmail.paths"
X#define domains			"/usr/lib/domains"
X
X#define Lsys			"/usr/lib/uucp/L.sys"
X
X/** where to put the output of the elm -d command... (in home dir) **/
X#define DEBUG		"ELM:debug.info"
X#define OLDEBUG		"ELM:debug.last"
X
X#define temp_file	"/tmp/snd."
X#define temp_form_file	"/tmp/form."
X#define temp_mbox	"/tmp/mbox."
X#define temp_print      "/tmp/print."
X#define temp_uuname	"/tmp/uuname."
X#define mailtime_file	".last_read_mail"
X#define readmsg_file	".readmsg"
X
X#define emacs_editor	"/usr/local/bin/emacs"
X
X#ifdef BSD
X# define default_editor	"/usr/ucb/vi"
X# define mailhome	"/usr/spool/mail/"
X#else
X# define default_editor	"/usr/bin/vi"
X# define mailhome	"/usr/mail/"
X#endif
X
X# define default_pager	"builtin"
X
X#define sendmail	"/usr/lib/sendmail"
X#define smflags		"-oi -oem"	/* ignore dots and mail back errors */
X#define mailer		"/bin/rmail"
X#ifdef BSD
X# define mailx		"/usr/ucb/Mail"
X#else
X# define mailx		"/usr/bin/mailx"
X#endif
X
X#define helphome	"/usr/local/lib"
X#define helpfile	"elm-help"
X
X#define ELMRC_INFO	"/usr/local/lib/elmrc-info"
X
X#define elmrcfile	"/.elmrc"
X#define mailheaders	".elmheaders"
X#define dead_letter	"Cancelled.mail"
X
X#define unedited_mail	"emergency.mbox"
X
X#define newalias	"newalias -q 1>&2 > /dev/null"
X#define readmsg		"readmsg"
X
X#define remove		"/bin/rm -f"		/* how to remove a file */
X#define cat		"/bin/cat"		/* how to display files */
X#define uuname		"uuname"		/* how to get a uuname  */
END_OF_hdrs/sysdefs.master
if test 7256 -ne `wc -c <hdrs/sysdefs.master`; then
    echo shar: \"hdrs/sysdefs.master\" unpacked with wrong size!?
fi
chmod +x hdrs/sysdefs.master
# end of overwriting check
fi
echo shar: Extracting \"hdrs/sysdefs.old\" \(7274 characters\)
if test -f hdrs/sysdefs.old ; then 
  echo shar: Will not over-write existing file \"hdrs/sysdefs.old\"
else
sed "s/^X//" >hdrs/sysdefs.old <<'END_OF_hdrs/sysdefs.old'
X/**			sysdefs.h			**/
X
X/**  System level, configurable, defines for the ELM mail system.  **/
X
X/**  (C) Copyright 1986 Dave Taylor                                **/
X
X/** Define the following if you think that the information in messages
X    that have "Reply-To:" and/or "From:" fields with addresses will
X    contain valid addressing information.  If this isn't defined, the
X    calculated return address will ALWAYS be used instead.  (note that
X    this doesn't necessarily preclude the use of G)roup replies).
X**/
X
X/** #define USE_EMBEDDED_ADDRESSES **/	
X
X
X#define FIND_DELTA	10		/* byte region where the binary search
X					   on the path alias file is fruitless 
X                                           (can't be within this boundary)    */
X
X#define MAX_SALIASES	503	/* number of system aliases allowed      */
X#define MAX_UALIASES	251	/* number of user aliases allowed 	 */
X#define MAX_IN_WEEDLIST 150	/* max headers to weed out               */
X
X#define MAX_HOPS	35	/* max hops in return addr to E)veryone  */
X
X#define MAX_ATTEMPTS	6	/* #times to attempt lock file creation */
X
X/** see leavembox.c to determine if this should be defined or not....The 
X    default is to NOT have it defined.
X**/
X
X/** #define REMOVE_AT_LAST **/
X
X#define DEFAULT_BATCH_SUBJECT  "no subject (file transmission)"
X
X/** If you want to have the mailer know about valid mailboxes on the
X    host machine (assumes no delivery agent aliases) then you should
X    undefine this (the default is to have it defined)...
X**/
X
X#define NOCHECK_VALIDNAME
X
X/** If your machine doesn't have virtual memory (specifically the vfork() 
X    command) then you should define the following....		
X**/
X
X/** #define NO_VM **/
X
X/** If you're running sendmail, or another transport agent that can 
X    handle the blind-carbon-copy list define the following
X**/
X
X#define ALLOW_BCC
X
X/** If you have pathalias, can we get to it as a DBM file??? **/
X
X/** #define USE_DBM **/
X
X/** If you want the mailer to check the pathalias database BEFORE it
X    looks to see if a specified machine is in the L.sys database (in
X    some cases routing is preferable to direct lines) then you should
X    define the following...
X**/
X
X/** #define LOOK_CLOSE_AFTER_SEARCH **/
X
X
X/** If you'd rather the program automatically used the 'uuname' command
X    to figure out what machines it talks to (instead of trying to get
X    it from L.sys first) then define the following...
X**/
X
X#define USE_UUNAME
X
X/** If you don't want the program to even TOUCH the addresses handed to 
X    it - deferring all expansion to sendmail/smail, then define the following;
X**/
X
X/** #define DONT_TOUCH_ADDRESSES **/
X
X/** Perhaps you'd also like the program not to try to minimize the addresses
X    stored when you 'alias current message'.  If so, define the following
X**/
X
X/** #define DONT_OPTIMIZE_RETURN **/
X
X/** If you'd like "newmail" to automatically go into background when you
X    start it up (instead of the "newmail &" junk with the process id output,
X    then define the following...
X**/
X
X#define AUTO_BACKGROUND
X
X/** If you'd rather your mail transport agent (ie sendmail) put the From:
X    line into the message, define the following...
X**/
X
X#define DONT_ADD_FROM
X
X/** If your machine prefers the Internet notation of user@host for the
X    From: line and addresses, define the following...(the default is to 
X    use this rather than the USENET notation - check your pathalias file!)
X
X**/
X
X#define INTERNET_ADDRESS_FORMAT
X
X/** If you're on a machine that prefers UUCP to Internet addresses, then
X    define the following (the basic change is that on a machine that
X    receives messages of the form <path>!user@<localhost> the displayed
X    address will be <path>!user instead of user@<localhost>.
X
X    BOGUS_INTERNET is the address that your local system appends to 
X    messages occasionally.  The algorithm is simply to REMOVE the
X    BOGUS_INTERNET string.  This is horrible.  *sigh*
X
X**/
X
X#define PREFER_UUCP
X#define BOGUS_INTERNET	"@hplabs.HP.COM"
X
X/** If you're running ACSNET and/or want to have your domain name
X    attached to your hostname on outbound mail then you can define
X    the following (default are not defined)
X**/
X
X/** #define USE_DOMAIN **/
X#define DOMAIN		"<enter your domain here>"
X
X/** If you are going to be running the mailer with setgid mail (or
X    something similar) you'll need to define the following to ensure
X    that the users mailbox in the spool directory has the correct
X    group (NOT the users group)
X**/
X
X#define SAVE_GROUP_MAILBOX_ID
X
X/** If you want a neat feature that enables scanning of the message
X    body for entries to add to the users ".calendar" (or whatever)
X    file, define this.
X**/
X
X#define ENABLE_CALENDAR
X#define dflt_calendar_file	"calendar"	/* in HOME directory */
X
X/** If you want to implement 'site hiding' in the mail, then you'll need to
X    uncomment the following lines and set them to reasonable values.  See 
X    the configuration guide for more details....
X**/
X
X/****************************************************************************
X
X#undef    DONT_ADD_FROM		
X
X#define   SITE_HIDING
X#define   HIDDEN_SITE_NAME	"fake-machine-name"
X#define   HIDDEN_SITE_USERS	"/usr/mail/lists/hidden_site_users"
X
X****************************************************************************/
X
X/** Do we have the 'gethostname()' call?  If not, define the following **/
X/** #define NEED_GETHOSTNAME **/
X
X/** are you stuck on a machine that has short names?  If so, define the
X    following **/
X
X/** #define SHORTNAMES **/
X
X#define NOTES_HEADER		"/***** "
X#define NOTES_FOOTER		"/* ---------- */"
X
X#ifdef BSD
X# define system_hash_file	"/usr/spool/mail/.alias_hash"
X# define system_data_file	"/usr/spool/mail/.alias_data"
X#else
X# define system_hash_file	"/usr/mail/.alias_hash"
X# define system_data_file	"/usr/mail/.alias_data"
X#endif
X
X#define pathfile		"/usr/lib/nmail.paths"
X#define domains			"/usr/lib/domains"
X
X#define Lsys			"/usr/lib/uucp/L.sys"
X
X/** where to put the output of the elm -d command... (in home dir) **/
X#define DEBUG		"ELM:debug.info"
X#define OLDEBUG		"ELM:debug.last"
X
X#define temp_file	"/tmp/snd."
X#define temp_form_file	"/tmp/form."
X#define temp_mbox	"/tmp/mbox."
X#define temp_print      "/tmp/print."
X#define temp_uuname	"/tmp/uuname."
X#define mailtime_file	".last_read_mail"
X#define readmsg_file	".readmsg"
X
X#define emacs_editor	"/usr/local/bin/emacs"
X
X#ifdef BSD
X# define default_editor	"/usr/ucb/vi"
X# define mailhome	"/usr/spool/mail/"
X#else
X# define default_editor	"/usr/bin/vi"
X# define mailhome	"/usr/mail/"
X#endif
X
X# define default_pager	"builtin"
X
X#define sendmail	"/usr/lib/sendmail"
X#define smflags		"-oi -oem"	/* ignore dots and mail back errors */
X#define mailer		"/bin/rmail"
X#ifdef BSD
X# define mailx		"/usr/ucb/Mail"
X#else
X# define mailx		"/usr/bin/mailx"
X#endif
X
X#define helphome	"/usr/local/lib"
X#define helpfile	"elm-help"
X
X#define ELMRC_INFO	"/usr/local/lib/elmrc-info"
X
X#define elmrcfile	"/.elmrc"
X#define mailheaders	".elmheaders"
X#define dead_letter	"Cancelled.mail"
X
X#define unedited_mail	"emergency.mbox"
X
X#define newalias	"newalias -q 1>&2 > /dev/null"
X#define readmsg		"readmsg"
X
X#define remove		"/bin/rm -f"		/* how to remove a file */
X#define cat		"/bin/cat"		/* how to display files */
X#define uuname		"uuname"		/* how to get a uuname  */
END_OF_hdrs/sysdefs.old
if test 7274 -ne `wc -c <hdrs/sysdefs.old`; then
    echo shar: \"hdrs/sysdefs.old\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/file.c\" \(6634 characters\)
if test -f src/file.c ; then 
  echo shar: Will not over-write existing file \"src/file.c\"
else
sed "s/^X//" >src/file.c <<'END_OF_src/file.c'
X/**		file.c		**/
X
X/** File I/O routines, mostly the save to file command...
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(), *error_description(), *strcpy(), *getenv();
Xunsigned long sleep();
X
Xint
Xsave(redraw)
Xint *redraw;
X{
X	/** Save all tagged messages + current in a file.  If no messages
X	    are tagged, save the current message instead!  This routine
X	    will return ZERO if the operation failed.
X	    'redraw' is set to TRUE iff we use the '?' and mess up
X	    the screen.  Pretty reasonable, eh?
X	**/
X
X	register int tagged = 0, i, oldstat, appending = 0;
X	register int iterations = 0, continue_looping;
X	char filename[SLEN], address[LONG_SLEN], buffer[SLEN];
X	FILE *save_file;
X
X	oldstat = header_table[current-1].status;	/* remember */
X
X	for (i=0; i < message_count; i++)
X	  if (ison(header_table[i].status, TAGGED))
X	    tagged++;
X
X	if (tagged == 0) {
X	  tagged = 1;
X	  setit(header_table[current-1].status, TAGGED);
X	}
X
X	dprint2(4,"%d message%s tagged for saving (save)\n", tagged,
X		plural(tagged));
X
X	do {
X
X	  continue_looping = 0;	/* clear the flag, ho hum... */
X
X	  if (iterations++) {
X	    printf("File message%s in: ", plural(tagged));
X	    fflush(stdout);
X	  }
X	  else
X	    PutLine1(LINES-2, 0, "File message%s in: ", plural(tagged));
X
X	  if (save_by_name) {
X	    /** build default filename to save to **/
X	    get_return(address);
X	    get_return_name(address, buffer, TRUE);
X	    sprintf(filename, "=%s", buffer);
X	  }
X	  else
X	    filename[0] = '\0';
X
X	  if (iterations > 1) {
X	    optionally_enter(filename, -1, -1, FALSE);
X	  } 
X	  else {
X	    if (tagged > 1)
X	      optionally_enter(filename, LINES-2, 19, FALSE);
X	    else	
X	      optionally_enter(filename, LINES-2, 18, FALSE);
X	  }
X  
X	  if (iterations == 1)
X	    MoveCursor(LINES-1,0);
X
X	  if (strlen(filename) == 0) {  /** <return> means 'cancel', right? **/
X	    header_table[current-1].status = oldstat;	/* BACK! */
X	    return(0);
X	  }
X	 
X	  if (strcmp(filename,"?") == 0) {
X	    *redraw = TRUE;	/* set the flag so we know what to do later */
X	    list_folders();
X	    continue_looping++;
X	  }
X	} while (continue_looping);
X
X	if (! expand_filename(filename)) {
X	  dprint1(2,"Error: Failed on expansion of filename %s (save)\n", 
X		   filename);
X	  header_table[current-1].status = oldstat;	/* BACK! */
X	  return(0);	/* failed expanding name! */
X	}
X
X	if (access(filename,ACCESS_EXISTS)) 	/* already there!! */
X	  appending = 1;
X	  
X#ifdef BSD4.1
X	if ((errno = ((can_open(filename, "a") & ~0x0200) >>8))) {
X#else
X	if ((errno = can_open(filename, "a"))) {
X#endif
X	  error1("Wrong permissions to save message to file %s!", filename);
X	  dprint2(2,"Error: access permission on file %s denied (%s)! (save)\n",
X		  filename, error_name(errno));
X	  header_table[current-1].status = oldstat;	/* BACK! */
X	  return(0);
X	}
X
X	dprint1(4,"Saving mail to file '%s'...\n", filename);
X
X	if ((save_file = fopen(filename,"a")) == NULL) {
X	  dprint1(2, "Error: couldn't append to specified file %s (save)\n", 
X		   filename);
X	  error1("Couldn't append to file %s!", filename);
X	  header_table[current-1].status = oldstat;	/* BACK! */
X	  return(0); 
X	}
X
X	for (i=0; i < message_count; i++) 	/* save each tagged msg */
X	  if (header_table[i].status & TAGGED)
X	    save_message(i, filename, save_file, (tagged > 1), appending++);
X
X	fclose(save_file);
X
X	chown(filename, userid, groupid);	/* owned by user */
X	if (tagged > 1)
X	  error1("Message%s saved", plural(tagged));
X	return(1);
X}
X
Xint
Xsave_message(number, filename, fd, pause, appending)
Xint number, pause, appending;
Xchar *filename;
XFILE *fd;
X{
X	/** Save an actual message to a file.  This is called by 
X	    "save()" only!  The parameters are the message number,
X	    and the name and file descriptor of the file to save to.
X	    If 'pause' is true, a sleep(2) will be done after the
X	    saved message appears on the screen...
X	    'appending' is only true if the file already exists 
X	**/
X
X	register int save_current;
X	
X	dprint1(4, "\tSaving message %d to file...\n", number);
X
X	save_current = current;
X	current = number+1;
X	copy_message("", fd, FALSE, FALSE);
X	current = save_current;
X
X	if (resolve_mode)
X	  setit(header_table[number].status, DELETED); /* deleted, but ...   */
X	clearit(header_table[number].status, TAGGED);  /* not tagged anymore */
X	clearit(header_table[number].status, NEW);     /* it's not new now!  */
X
X	if (! appending)	/* don't ask */
X	  error2("Message %d appended to file %s", number+1, filename);
X	else
X	  error2("Message %d saved to file %s", number+1, filename);
X
X	show_new_status(number);	/* update screen, if needed */
X
X	if (pause) sleep(2);
X}
X
Xint
Xexpand_filename(filename)
Xchar *filename;
X{
X	/** Expands '~' and '=' to specified file names, also will try to 
X	    expand shell variables if encountered.. '+' and '%' are synonymous 
X	    with '=' (folder dir)... **/
X
X	char buffer[SLEN], varname[SLEN], env_value[SLEN], *ptr;
X	register int i = 1, index = 0;
X	char *getenv();
X
X	ptr = filename;
X	while (*ptr == ' ') ptr++;	/* leading spaces GONE! */
X	strcpy(filename, ptr);
X
X	/** New stuff - make sure no illegal char as last **/
X
X	if (lastch(filename) == '\n' || lastch(filename) == '\r')
X	  lastch(filename) = '\0';
X	  
X	if (filename[0] == '~') {
X	  sprintf(buffer, "%s%s%s", home, 
X		(filename[1] != '/' && lastch(folders) != '/')? "/" : "",
X	  	(char *) filename + 1);
X	  strcpy(filename, buffer);
X	}
X	else if (filename[0] == '=' || filename[0] == '+' || 
X	 	 filename[0] == '%') {
X	  if (strlen(folders) == 0) {
X	    dprint2(3,"Error: maildir not defined - can't expand '%c' (%s)\n",
X		     filename[0], "expand_filename");
X	    error1("MAILDIR not defined.  Can't expand '%c'", filename[0]);
X	    return(0);
X	  }
X	  sprintf(buffer, "%s%s%s", folders, 
X		(filename[1] != '/' && lastch(folders) != '/')? "/" : "",
X		(char *) filename + 1);
X	  strcpy(filename, buffer);
X	}
X	else if (filename[0] == '$') {	/* env variable! */
X	  while (isalnum(filename[i]))
X	    varname[index++] = filename[i++];
X	  varname[index] = '\0';
X
X	  env_value[0] = '\0';			/* null string for strlen! */
X	  if (getenv(varname) != NULL)
X	    strcpy(env_value, getenv(varname));
X
X	  if (strlen(env_value) == 0) {
X	    dprint2(3,"Error: Can't expand environment variable $%s (%s)\n",
X		    varname, "expand_filename");
X	    error1("Don't know what the value of $%s is!", varname);
X	    return(0);
X	  }
X
X	  sprintf(buffer, "%s%s%s", env_value, 
X		  (filename[i] != '/' && lastch(env_value) != '/')? "/" : "",
X		  (char *) filename + i);
X	  strcpy(filename, buffer);
X	}
X	  
X	return(1);
X}
END_OF_src/file.c
if test 6634 -ne `wc -c <src/file.c`; then
    echo shar: \"src/file.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/initialize.uts\" \(7197 characters\)
if test -f src/initialize.uts ; then 
  echo shar: Will not over-write existing file \"src/initialize.uts\"
else
sed "s/^X//" >src/initialize.uts <<'END_OF_src/initialize.uts'
XFrom hpccc!mcgregor@hplabs.ARPA Fri May  9 16:05:10 1986
XReceived: from hplabs.ARPA by hpldat ; Fri, 9 May 86 16:05:01 pdt
XMessage-Id: <8605092305.AA00689@hpldat>
XReceived: by hplabs.ARPA ; Fri, 9 May 86 16:01:29 pdt
XFrom: Scott McGregor <hpccc!mcgregor@hplabs.ARPA>
XTo: taylor@hplabs
XDate: Fri, 9 May 86 15:23:16 PDT
XSubject: initialize.c
XX-Mailer: msg [version 3.3a]
X
X/**		initialize.c		**/
X
X/***** Initialize - read in all the defaults etc etc 
X       (C) Copyright 1985 Dave Taylor
X*****/
X
X#include "headers.h"
X
X#ifdef BSD
X#  include <sgtty.h>
X#else
X#  include <termio.h>
X#endif
X
X#include <pwd.h>
X
X#ifdef BSD
X#  include <sys/time.h>
X#else
X#  include <time.h>
X#endif
X
X#include <signal.h>
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X
X
Xextern int errno;		/* system error number on failure */
X
Xchar *error_name(), *error_description();
X
Xchar *expand_logname(), *getenv(), *getlogin();
X
Xinitialize(InitScreen_to)
Xint InitScreen_to;
X{
X	struct passwd *pass, *getpwnam();
X
X	register int i;
X	int      quit_signal(), term_signal(), ill_signal(),
X		 fpe_signal(),  bus_signal(),  segv_signal(),
X	         alarm_signal();
X	char     buffer[SLEN], *cp;
X	
X	userid  = getuid();
X	groupid = getgid();	
X
X	strcpy(home,((cp = getenv("HOME")) == NULL)? "" : cp);
X	strcpy(shell,((cp = getenv("SHELL")) == NULL)? "" : cp);
X
X	if (debug) {		/* setup for dprintf statements! */
X	  char filename[SLEN];
X	  sprintf(filename, "%s/%s", home, DEBUG);
X	  if ((debugfile = fopen(filename, "w")) == NULL) {
X	    debug = 0;	/* otherwise 'leave' will try to log! */
X	    leave(fprintf(stderr,"Could not open file %s for debug output!\n",
X		  filename));
X	  }
X	  if (InitScreen_to) {
X		  InitScreen();
X	  }
X	  chown(filename, userid, groupid); /* file owned by user */
X
X	  fprintf(debugfile, "Debug output of the MSG program.  Version %s\n\n",
X		  VERSION);
X	}
X#ifndef UTS
X	signal(SIGINT,  SIG_IGN);
X	signal(SIGQUIT, quit_signal);		/* Quit signal 	            */
X	signal(SIGTERM, term_signal); 		/* Terminate signal         */
X	signal(SIGILL,  ill_signal);		/* Illegal instruction      */
X	signal(SIGFPE,  fpe_signal);		/* Floating point exception */
X	signal(SIGBUS,  bus_signal);		/* Bus error  		    */
X	signal(SIGSEGV, segv_signal);		/* Segmentation Violation   */
X#endif
X	signal(SIGALRM, alarm_signal);		/* Process Timer Alarm	    */
X
X	if (isa3270()) {
X	  isatube++;
X	  dprint0(1, "** We're using a 3270 tube!! **\n");
X	}
X
X#ifndef UTS
X	get_connections();	      /* who do we talk to directly?? */
X#endif
X	open_domain_file();		/* if we got it, we want it!  */
X
X	get_term_chars();
X	
X	gethostname(hostname, sizeof(hostname));
X	if ((cp = getlogin()) == NULL)
X	  cuserid(username);
X	else
X	  strcpy(username, cp);
X
X	/* now let's get the full username.. */
X
X	if ((pass = getpwnam(username)) == NULL) {
X	  error("Couldn't read password entry??");
X	  strcpy(full_username, username);
X	}
X	else {
X	  for (i=0; pass->pw_gecos[i] != '\0' && pass->pw_gecos[i] != ',';
X	       i++)
X	      if (pass->pw_gecos[i] == '&') {
X	        full_username[i] = '\0';
X	        strcat(full_username, expand_logname());
X	        i = strlen(full_username) - 2;
X	      }
X	      else
X	        full_username[i] = pass->pw_gecos[i];
X	  full_username[i] = '\0'; 
X	}
X
X	if ((cp = getenv("EDITOR")) == NULL)
X	  strcpy(editor,default_editor);
X	else
X	  strcpy(editor, cp);
X
X	if (! mail_only) {
X	  mailbox[0] = '\0';
X	  strcpy(prefixchars, "> "); 	/* default message prefix */
X	}
X
X	read_rc_file();		/* reading the .msgrc next... */
X
X	/** now try to expand the specified filename... **/
X
X	if (strlen(infile) > 0) {
X	  (void) expand_filename(infile);
X	  if ((errno = can_access(infile, READ_ACCESS))) {
X	    dprint2(1,"Error: given file %s as mailbox - unreadable (%s)!\n", 
X		     infile, error_name(errno));
X	    fprintf(stderr,"Can't open mailbox '%s' for reading!\n", infile);
X	    exit(1);
X	  }
X	}
X
X	/** check to see if the user has defined a LINES or COLUMNS
X	    value different to that in the termcap entry (for
X	    windowing systems, of course!) **/
X
X	if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
X	  sscanf(cp, "%d", &LINES);
X	  LINES -= 1;	/* kludge for HP Window system? ... */
X	}
X
X	if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
X	  sscanf(cp, "%d", &COLUMNS);
X
X	/** fix the shell if needed **/
X
X	if (shell[0] != '/') {
X	   sprintf(buffer, "/bin/%s", shell);
X	   strcpy(shell, buffer);
X	}
X
X	if (! mail_only) {
X	  mailbox_defined = (mailbox[0] != '\0'); 
X
X	  /* get the cursor control keys... */
X
X	  if ((cp = return_value_of("ku")) == NULL || strlen(cp) != 2)
X	    cursor_control = FALSE;
X	  else {
X	    strcpy(up, cp);
X	    if ((cp = return_value_of("kd")) == NULL || strlen(cp) != 2)
X	      cursor_control = FALSE;
X	    else {
X	      strcpy(down, cp);
X	      cursor_control = TRUE;
X	      transmit_functions(ON);
X	    }
X	  }
X
X	  strcpy(start_highlight, "->");
X	  end_highlight[0] = '\0';
X
X	  if (!arrow_cursor) {	/* try to use inverse bar instead */
X	    if ((cp = return_value_of("so")) != NULL) {
X	      strcpy(start_highlight, cp);
X	      if ((cp = return_value_of("se")) == NULL)
X	        strcpy(start_highlight, "->");
X	      else {
X	        strcpy(end_highlight, cp);
X	        has_highlighting = TRUE;
X	      }
X	    }
X	  }
X	}
X
X	if (read_aliases)
X  	  read_alias_files();
X
X	if (! mail_only) {
X	  if (mini_menu)
X	    headers_per_page = LINES - 13;
X	  else
X	    headers_per_page = LINES -  8;	/* 5 more headers! */
X
X	  newmbox(1,FALSE, TRUE);	/* read in the mailbox! */
X	}
X
X	init_findnode();	/* set up the path alias stuff */
X
X	dprint0(2,"\n-- end of initialization phase --\n");
X
X	dprint3(2,"\thostname = %s\n\tusername = %s\n\tfull_username = \"%s\"\n",
X	         hostname, username, full_username);
X
X	dprint3(2,"\thome = %s\n\teditor = %s\n\tmailbox = %s\n",
X		 home, editor, mailbox);
X
X	dprint3(2,"\tinfile = %s\n\tfolder-dir = %s\n\tprintout = \"%s\"\n",
X		 infile, folders, printout);
X	
X	dprint3(2,"\tsavefile = %s\n\tprefix = \"%s\"\n\tshell = %s\n",
X		savefile, prefixchars, shell);
X	
X	dprint0(1,"-- beginning execution phase --\n\n");
X}
X
Xget_term_chars()
X{
X	/** This routine sucks out the special terminal characters
X	    ERASE and KILL for use in the input routine.  The meaning 
X            of the characters are (dare I say it?) fairly obvious... **/
X
X#ifdef BSD
X	struct sgttyb term_buffer;
X
X# define TCGETA	TIOCGETP
X
X#else 
X	struct termio term_buffer;
X#endif
X
X	if (ioctl(STANDARD_INPUT, TCGETA, &term_buffer) == -1) {
X	  dprint1(1,"Error: %s encountered on ioctl call (get_term_chars)\n", 
X		   error_name(errno));
X	  /* set to defaults for terminal driver */
X	  backspace = BACKSPACE;
X	  kill_line = ctrl('U');
X	}
X	else {
X#ifdef BSD
X	  backspace = term_buffer.sg_erase;
X	  kill_line = term_buffer.sg_kill;
X#else
X	  backspace = term_buffer.c_cc[VERASE];
X	  kill_line = term_buffer.c_cc[VKILL];
X#endif
X	}
X}
X
Xchar *expand_logname()
X{
X	/** Return logname in a nice format (for expanding "&" in the
X	    /etc/passwd file) **/
X
X	static char buffer[SLEN];
X	register int i;
X
X	if (strlen(username) == 0)
X	  buffer[0] = '\0';
X	else {
X	  buffer[0] = toupper(username[0]);
X
X	  for (i=1; username[i] != '\0'; i++)
X	    buffer[i] = tolower(username[i]);
X
X	  buffer[i] = '\0';
X	}
X
X	return( (char *) buffer);	
X}
X
END_OF_src/initialize.uts
if test 7197 -ne `wc -c <src/initialize.uts`; then
    echo shar: \"src/initialize.uts\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/limit.c\" \(6658 characters\)
if test -f src/limit.c ; then 
  echo shar: Will not over-write existing file \"src/limit.c\"
else
sed "s/^X//" >src/limit.c <<'END_OF_src/limit.c'
X/**			limit.c			**/
X
X/** This stuff is inspired by MH and dmail and is used to 'select'
X    a subset of the existing mail in the folder based on one of a
X    number of criteria.  The basic tricks are pretty easy - we have
X    as status of VISIBLE associated with each header stored in the
X    (er) mind of the computer (!) and simply modify the commands to
X    check that flag...the global variable `selected' is set to the
X    number of messages currently selected, or ZERO if no select.
X
X       (C) Copyright 1986, Dave Taylor
X**/
X
X#include "headers.h"
X
X#define TO		1
X#define FROM		2
X
Xchar *shift_lower();
X
Xint
Xlimit()
X{
X	/** returns non-zero if we did enough to redraw the screen **/
X	
X	char criteria[STRING], first[STRING], rest[STRING];
X	int  last_current;
X
X	if (selected) {
X	  PutLine1(LINES-2, 0, 
X		"Already have selection criteria - add more? (y/n) n%c",
X		BACKSPACE);
X	  ReadCh(criteria[0]);
X	  if (tolower(criteria[0]) == 'y') 
X	    PutLine0(LINES-3, COLUMNS-30, "Adding criteria...");
X	  else {
X	    selected = 0;
X	    PutLine0(LINES-3, COLUMNS-30, "Use '?' for help");
X	  }
X	  
X	}
X
X	PutLine1(LINES-2, 0, "Enter criteria: ");
X	CleartoEOLN();
X
X	criteria[0] = '\0';
X	optionally_enter(criteria, LINES-2, 16, FALSE);
X	
X	if (strlen(criteria) == 0) return(0);
X
X	split_word(criteria, first, rest);
X	
X	if (equal(first, "all")) {
X	   selected = 0;
X	   return(TRUE);
X	}
X
X	last_current = current;
X	current = -1;
X
X	if (equal(first, "subj") || equal(first, "subject"))
X	  selected = limit_selection(SUBJECT, rest, selected);
X	else if (equal(first, "to"))
X	  selected = limit_selection(TO, rest, selected);
X	else if (equal(first, "from"))
X	  selected = limit_selection(FROM, rest, selected);
X	else {
X	  selected = 0;
X	  error1("Don't understand \"%s\" as a selection criteria!", first);
X	  sleep(2);
X	}
X
X	if (! selected)
X	  current = last_current;
X	else
X	  current = visible_to_index(1)+1;	/* map it and shift up 1 */
X
X	if (! selected)
X	  set_error("no items selected");
X	else {
X	  sprintf(first, "%d items selected", selected);
X	  set_error(first);
X	}
X	
X	return(selected);
X}
X
Xint
Xlimit_selection(based_on, pattern, additional_criteria)
Xint based_on, additional_criteria;
Xchar *pattern;
X{
X	/** Given the type of criteria, and the pattern, mark all
X	    non-matching headers as ! VISIBLE.  If additional_criteria,
X	    don't mark as visible something that isn't currently!
X	**/
X
X	register int index, count = 0;
X
X	dprint3(2,"\n\n\n**limit on %d - '%s' - (%s) **\n\n",
X		   based_on, pattern, additional_criteria?"add'tl":"base");
X
X	if (based_on == SUBJECT) {
X	  for (index = 0; index < message_count; index++)
X	    if (! in_string(shift_lower(header_table[index].subject), pattern))
X	      header_table[index].status &= ~VISIBLE;
X	    else if (additional_criteria && 	
X		     header_table[index].status | VISIBLE)
X	      header_table[index].status &= ~VISIBLE;	/* shut down! */
X	    else { /* mark it as readable */
X	      header_table[index].status |= VISIBLE;
X	      count++;
X	      dprint3(5,"  Message %d (%s from %s) marked as visible\n",
X			index, header_table[index].subject,
X			header_table[index].from);
X	    }
X	}
X	else if (based_on == FROM) {
X	  for (index = 0; index < message_count; index++)
X	    if (! in_string(shift_lower(header_table[index].from), pattern))
X	      header_table[index].status &= ~VISIBLE;
X	    else if (additional_criteria && 	
X		     header_table[index].status | VISIBLE)
X	      header_table[index].status &= ~VISIBLE;	/* shut down! */
X	    else { /* mark it as readable */
X	      header_table[index].status |= VISIBLE;
X	      count++;
X	      dprint3(5,"  Message %d (%s from %s) marked as visible\n",
X			index, header_table[index].subject,
X			header_table[index].from);
X	    }
X	}
X	else if (based_on == TO) {
X	  for (index = 0; index < message_count; index++)
X	    if (! in_string(shift_lower(header_table[index].to), pattern))
X	      header_table[index].status &= ~VISIBLE;
X	    else if (additional_criteria && 	
X		     header_table[index].status | VISIBLE)
X	      header_table[index].status &= ~VISIBLE;	/* shut down! */
X	    else { /* mark it as readable */
X	      header_table[index].status |= VISIBLE;
X	      count++;
X	      dprint3(5,"  Message %d (%s from %s) marked as visible\n",
X			index, header_table[index].subject,
X			header_table[index].from);
X	    }
X	}
X
X	dprint1(4,"\n** returning %d selected **\n\n\n", count);
X
X	return(count);
X}
X
Xint
Xnext_visible(index)
Xint index;
X{
X	/** Given 'index', this routine will return the actual index into the
X	    array of the NEXT visible message, or '-1' if none are visible 
X	**/
X	int remember_for_debug;
X
X	remember_for_debug = index;
X
X	index--;	/* shift from 'current' to actual index  */
X	index++;	/* make sure we don't bump into ourself! */
X
X	while (index < message_count) {
X	  if (header_table[index].status & VISIBLE) {
X	    dprint2(9,"[Next visible: given %d returning %d]\n", 
X		       remember_for_debug, index+1);
X	    return(index+1);
X	  }
X	  index++;
X	}
X
X	return(-1);
X}
X
Xint
Xprevious_visible(index)
Xint index;
X{
X	/** Just like 'next-visible', but backwards FIRST... */
X	
X	int remember_for_debug;
X
X	remember_for_debug = index;
X
X	index -= 2;	/* shift from 'current' to actual index, and skip us! */
X
X	while (index > -1) {
X	  if (header_table[index].status & VISIBLE) {
X	    dprint2(9,"[previous visible: given %d returning %d]",
X		    remember_for_debug, index+1);
X	    return(index+1);
X	  }
X	  index--;
X	}
X
X	return(-1);
X}
X
Xint
Xcompute_visible(message)
Xint message;
X{
X	/** return the 'virtual' index of the specified message in the
X	    set of messages - that is, if we have the 25th message as
X	    the current one, but it's #2 based on our limit criteria,
X	    this routine, given 25, will return 2.
X	**/
X
X	register int index, count = 0;
X
X	if (! selected) return(message);
X
X	if (message < 0) message = 0;	/* normalize */
X
X	for (index = 0; index <= message; index++)
X	   if (header_table[index].status & VISIBLE) 
X	     count++;
X
X	dprint2(4, "[compute-visible: displayed message %d is actually %d]\n",
X		count, message);
X
X	return(count);
X}
X
Xint
Xvisible_to_index(message)
Xint message;
X{
X	/** Given a 'virtual' index, return a real one.  This is the
X	    flip-side of the routine above, and returns (message_count+1)
X	    if it cannot map the virtual index requested (too big) 
X	**/
X
X	register int index = 0, count = 0;
X
X	for (index = 0; index < message_count; index++) {
X	   if (header_table[index].status & VISIBLE) 
X	     count++;
X	   if (count == message) {
X	     dprint2(4,"visible-to-index: (up) index %d is displayed as %d\n",
X		     message, index);
X	     return(index);
X	   }
X	}
X
X	dprint1(4, "index %d is NOT displayed!\n", message);
X
X	return(message_count+1);
X}
END_OF_src/limit.c
if test 6658 -ne `wc -c <src/limit.c`; then
    echo shar: \"src/limit.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of archive 6 \(of 19\).
cp /dev/null ark6isdone
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 05