[comp.sources.bugs] Mush 6.4 to 6.5 Patch Kit, Part 1 of 6

schaefer@ogccse.ogc.edu (Barton E. Schaefer) (04/29/89)

Mail User's Shell 6.4 to 6.5 Upgrade Kit -- Part 1 of 6
---------------------------------------------------------------------------
IMPORTANT PATCHING INSTRUCTIONS:

    This patch kit was created by running diff against the source files
    posted in comp.sources.unix Volume 18, Issues 23-41.
    
    The first patch enclosed is for file "main.c".  It has been given a
    Prereq: directive to test the PATCHDATE in "main.c".  If this fails,
    you should abort the entire patch process, because you have the wrong
    revision of mush 6.4.  This should happen only if you do not have the
    comp.sources.unix sources noted above.  Contact either Dan Heller
    (dheller@cory.berkeley.edu, island!argv@cad.berkeley.edu) or Bart
    Schaefer (schaefer@cse.ogc.edu) for additional patches to bring your
    version up to date.  Be sure to include the PATCHDATE date from
    "main.c" in your request.

    The first part of this patch will create a file "kit.check", the
    contents of which are tested by a Prereq: in each succeeding part of
    the patch.  This will help to ensure that your patches are applied in
    the right order.  Order is critical only for parts 1, 5, and 6 but you
    should try to apply them in order anyway.  Part 5 adds a number of
    aesthetic toolmode changes to the version created by parts 1-4; Part 6
    fixes some bugs reported too late to squeeze into the rest.

    The file "help.c" is obsoleted by these patches.  After applying part
    4, you may remove it.

    If you are an MMDF site using HOMEMAIL, you may have already applied
    a portion of the patch for "file.c" -- a partial patch was posted to
    comp.sources.bugs.  If you do not have a copy of the original source
    for "file.c", you will need to use "patch -N" for part 1.  If you
    aren't sure whether or not you have previously applied that patch, go
    ahead and use "patch -N" -- there should be no problem.

    Summary:
	Use "patch -N" to apply part 1 of this patch.
	Abort if patch thinks you have the wrong version.
	If you abort, contact us, and include your PATCHDATE.
	After applying part 5 of the kit, remove "help.c".

    A set of patch notes detailing changes to each file will be created by
    part 4 of this kit.  The notes do not cover the suntools improvements
    of part 5.  If you aren't interested in these details, you will find a
    shorter summary in README-6.5, which includes some brief comments on
    the suntools update.  The "PATCHNOTES" file is included only with this
    kit and should not be considered part of the 6.5 release.

				    Dan Heller <island!argv@cad.berkeley.edu>
				    Bart Schaefer <schaefer@cse.ogc.edu>

===========================================================================
Prereq: "3/12/89"
*** mush-6.4/main.c	Fri Mar 24 10:02:54 1989
--- main.c	Wed Apr 12 10:14:31 1989
***************
*** 3,9 ****
  #include "mush.h"
  #include "options.h"
  
! #define PATCHDATE "3/12/89" /* Here because EVERYTHING depends on mush.h */
  
  #if defined(sun) && defined(M_DEBUG)
  cpu()
--- 3,9 ----
  #include "mush.h"
  #include "options.h"
  
! #undef PATCHDATE /* Here because EVERYTHING depends on mush.h */
  
  #if defined(sun) && defined(M_DEBUG)
  cpu()
***************
*** 33,38 ****
--- 33,44 ----
      char	    **args;
      struct mush_flags Flags;
  
+ #ifndef INTERNAL_MALLOC
+     extern char *stackbottom;	/* used by xfree() */
+ 
+     stackbottom = (char *) &argc;
+ #endif /* INTERNAL_MALLOC */
+ 
  #ifdef LCKDFLDIR
      lckdfldir = LCKDFLDIR;
  #endif /* LCKDFLDIR */
***************
*** 120,130 ****
      set_cwd();  /* call _after_ sourcing files */
  
  #ifdef SUNTOOL
!     if (istool)
! 	if (ison(glob_flags, REDIRECT))
! 	    puts("You can't redirect input to a tool."), exit(1);
! 	else
! 	    make_tool(args), turnon(glob_flags, DO_SHELL);
  #endif /* SUNTOOL */
  
      /* now we're ready for I/O */
--- 126,136 ----
      set_cwd();  /* call _after_ sourcing files */
  
  #ifdef SUNTOOL
!     if (istool) {
! 	make_tool(args);
! 	turnon(glob_flags, DO_SHELL);
! 	turnoff(glob_flags, REDIRECT); /* -- SunOS-4.0 has a problem here */
!     }
  #endif /* SUNTOOL */
  
      /* now we're ready for I/O */
*** mush-6.4/README	Fri Mar 24 09:57:37 1989
--- README	Tue Apr 18 09:26:32 1989
***************
*** 43,51 ****
      -DDEFINITION	/* in your makefile */
  
  If the definition is of the form MACRO="string", then use:
-     -DMACRO=string
      #define MACRO string
  
  ---------------
  Which makefile to use:
  
--- 43,56 ----
      -DDEFINITION	/* in your makefile */
  
  If the definition is of the form MACRO="string", then use:
      #define MACRO string
+     -DMACRO=string
  
+ Note that if you use definitions in the makefile, you should remove the
+ corresponding definitions from config.h -- if you do not, the config.h
+ definitions will override the -D definitions.  The compiler will usually
+ print a warning message if this happens, but the result will still be wrong.
+ 
  ---------------
  Which makefile to use:
  
***************
*** 53,62 ****
  
      makefile.sun applies only to suns and creates a binary called "mush."
      If the binary ends in "tool", then the graphics (suntools) mode will be
!     used by default on invocation. Otherwise, you must specify -t for
!     toolmode on sun workstations.  The SUNTOOL define must is in the
      makefile.sun in order to compile the suntools version.  You don't need
!     to be running sunview; old sunwindows (2.0+) may be used.
  
      If you know that you're not going to use the suntools mode then you
      should use makefile.bsd so that SUNTOOL won't be defined and unnecessary
--- 58,68 ----
  
      makefile.sun applies only to suns and creates a binary called "mush."
      If the binary ends in "tool", then the graphics (suntools) mode will be
!     used by default on invocation.  Otherwise, you must specify -t for
!     toolmode on sun workstations.  The SUNTOOL define is used in the
      makefile.sun in order to compile the suntools version.  You don't need
!     to be running sunview; old sunwindows (2.0+) may be used.  Be sure to
!     follow the notes in the makefile.sun for SunOS-4.0 machines.
  
      If you know that you're not going to use the suntools mode then you
      should use makefile.bsd so that SUNTOOL won't be defined and unnecessary
***************
*** 68,76 ****
  
  If you are using XENIX:
  
!     The files makefile.x286 and makefile.x386 were created especially for
!     XENIX machines.  makefile.x286 is for Intel's 80286 processor and the
!     makefile.x386 is for the 80386 processor.  The xenix makefiles are
      tuned for SCO's version of xenix.  This does not mean that it won't
      work under other xenix versions -- however, some changes may have to
      be made by hand.  If your xenix release is sco-xenix 2.2 or higher
--- 74,81 ----
  
  If you are using XENIX:
  
!     There is one makefile for xenix: makefile.xenix.  However, SCO-xenix
!     runs on either 80286 or 80386 architectures.  This makefiles has been
      tuned for SCO's version of xenix.  This does not mean that it won't
      work under other xenix versions -- however, some changes may have to
      be made by hand.  If your xenix release is sco-xenix 2.2 or higher
***************
*** 80,85 ****
--- 85,96 ----
      anyway, even if you're on an older xenix system (that supports termio),
      then you may define USG anyway.
  
+     Follow the hints in the makefile.xenix for compiling for 286 systems
+     or 386 systems.  It is *very likely* that the CFLAGS will have to be
+     modified -- specifically, the model size and the stack size options.
+     You should be very familiar with your xenix to know how to tune this
+     properly.
+ 
  If you are on a system-v Bell labs machine:
  
      makefile.sys.v is for unix machines that are not running any flavor of
***************
*** 86,91 ****
--- 97,107 ----
      BSD and probably running a system-v flavor of unix -- this defines USG
      so that termio will be used.
  
+     MicroPort sys-v users should probably remove the -O compiler option
+     from the makefile, and may have trouble with the msg_bit() macro
+     defined in mush.h.  It should be fairly trivial to generate an
+     equivalent function.
+ 
  When you decide on an appropriate makefile, _copy_ it to a new file called
  Makefile.
  ---------------
***************
*** 134,154 ****
  
  #defines specifically for your MTA:
  
- OLD_MAILER:
-     Some MTA's, especially older ones like /bin/mail or execmail (xenix), do
-     not conform to RFC822 and provide the required headers: From: and Date:.
-     To remedy, either #define OLD_MAILER in config.h or add the -D option
-     OLD_MAILER in the appropriate makefile: -DOLD_MAILER.  What this does is
-     make sure that there is a From: and Date: header in outgoing messages and
-     in folders (such as "set record").  Sendmail should not define this.
- 
  UUCP:
!     If your machine talks to other computers via uucp _and_ you have the
!     macro OLD_MAILER defined,  then you may want to define UUCP.  This will
!     change the From: line to have your return address look like "host!user"
!     rather than "user@host" (which is the default).  If you don't have
!     OLD_MAILER defined, this define does nothing.
  
  NO_COMMAS:
      If your mailer does *NOT* like commas between addresses (pre-3.0 smail,
      xenix and sys-v machines), then you should define NO_COMMAS.  Otherwise,
--- 150,163 ----
  
  #defines specifically for your MTA:
  
  UUCP:
!     If defined, the From: line created specifies the user's address in
!     UUCP format (host!user).  Otherwise, arpa-style format is used (user@host)
  
+ MTA_EXIT:
+     The exit code of a successful delivery of a message by your MTA.
+     This is typically 0, but MMDF sites should define 9 (see config.h-dist).
+ 
  NO_COMMAS:
      If your mailer does *NOT* like commas between addresses (pre-3.0 smail,
      xenix and sys-v machines), then you should define NO_COMMAS.  Otherwise,
***************
*** 171,176 ****
--- 180,196 ----
      config.h file.  If you don't have it (sys-v), then this should not be
      defined.
  
+ PICKY_MAILER
+     Most RFC822 compliant mailers (sendmail) will add the headers From:
+     and Date: on outgoing mail.  If the user or UA sends these headers,
+     most MTAs will not append them automatically.  However, there are
+     certain MTAs which will not allow this -- these "picky mailers" will
+     precede such headers with a '>' and make the headers very ugly and
+     somewhat redundant or contradictory.  It's hard to determine whether
+     or not your MTA will do this without actually sending mail to yourself.
+     However, it is advised to set this *unless* your mailer is not RFC822-
+     compliant (used to be defined by OLD_MAILER in previous mush releases).
+ 
  ---------------
  Signals:
  SIGRET:
***************
*** 188,196 ****
--- 208,247 ----
      you guess wrong, you will get compiler "warnings" on lines that read:
  	on_intr();
  	off_intr();
+ ---------------
+ Memory allocation:
  
+ INTERNAL_MALLOC:
+     Mush depends on the xfree() function to detect invalid pointers, so
+     that they will not be incorrectly passed to free().  Some system
+     organizations make this very difficult, if not impossible.  80286-based
+     machines in certain memory models, AT&T 3b2s and 3b15s, and others have
+     these difficulties; VAX, Sun, Sequent, Apollo, and most 680x0 and many
+     80386-based machines do not.  Changes have been made to xfree() to
+     handle the AT&T machines, but if you aren't sure about your machine,
+     or if you get unexpected segmentation faults, define INTERNAL_MALLOC.
+     SysV users may want to define this anyway, because the internal malloc
+     is faster than the default malloc(3).
+ 
+     By default, INTERNAL_MALLOC is undefined.
+ 
  ---------------
+ misc defines:
+ ---------------
+ TIMEZONE:
+     If this is defined, the string it is defined to is used as your timezone
+     regardless of what the system thinks your timezone is.  This is intended
+     for systems which have no functions for determining the timezone.  On
+     newer Gould BSD 4.3 systems, it is safe to use
+ 	    #define TIMEZONE T->tm_zone
+     On other systems, it is better to define TIMEZONE as a string, e.g.
+ 	    #define TIMEZONE "PST"	/* Or "-0800" for MH style */
  
+ DAYLITETZ:
+     This should be defined to your Daylight Savings Time timezone string if
+     and only if you also define TIMEZONE (above).  Do not define this if you
+     use the Gould tm_zone.
+ 
  VPRINTF:
      This should be defined if your system has the vprintf functions. You
      *have* these functions if you are running:
***************
*** 222,228 ****
  	This is true for xenix and System-V Unix.
      If you don't have REGCMP defined, then the routines re_comp() and re_exec()
      are used (this is the default for mush).
!     
      Note that some systems do not have either set of routines in the default
      libraries.  You must find the library to use and add it to the list of
      libraries to use.  If this is the case, your link will fail with the
--- 273,279 ----
  	This is true for xenix and System-V Unix.
      If you don't have REGCMP defined, then the routines re_comp() and re_exec()
      are used (this is the default for mush).
! 
      Note that some systems do not have either set of routines in the default
      libraries.  You must find the library to use and add it to the list of
      libraries to use.  If this is the case, your link will fail with the
*** mush-6.4/README-6.4	Fri Mar 24 09:57:42 1989
--- README-6.4	Tue Apr 18 09:26:35 1989
***************
*** 288,294 ****
  no longer a recognized name.
  [Bart Schaefer, Dan Heller]
  ---------
! The show_deleted variable now controls whether or you you can display
  deleted messages in addition to whether to display their headers for a
  headers command.  All other mush commands affect all messages regardless
  of whether or not they are deleted.  Commands that wish to not affect
--- 288,294 ----
  no longer a recognized name.
  [Bart Schaefer, Dan Heller]
  ---------
! The show_deleted variable now controls whether or not you can display
  deleted messages in addition to whether to display their headers for a
  headers command.  All other mush commands affect all messages regardless
  of whether or not they are deleted.  Commands that wish to not affect
*** mush-6.4/README-6.5	Tue Apr 18 10:13:15 1989
--- README-6.5	Tue Apr 18 09:49:08 1989
***************
*** 0 ****
--- 1,86 ----
+ Changes/bugfixes in Mush 6.5 from 6.4:
+ --------------------------------------
+ 
+ Changed VERSION to 6.5 and date to 4/03/89.
+ 
+ Provision has been made for a compile-time defined TIMEZONE, for sytems
+ that lack a timezone() call or other means of getting the time zone.
+ See the installation instructions in README for details.  Thanks to
+ Wytze van der Raay of Gould EUSC for suggestions.
+ 
+ A new preprocessor definition INTERNAL_MALLOC has been created (and a
+ new file, malloc.c, added) for systems which experienced problems with
+ mush's memory deallocation function xfree().  See README for details.
+ 
+ The headers command has been changed to make certain that a full screen
+ of header summaries is always shown -- that is, if all messages on the
+ current page are deleted, and show_deleted is not set, mush will scan
+ backwards to find undeleted messages to summarize.  Also, the -H option
+ of headers was inadvertently lost but has been restored.
+ 
+ Extensive changes have been made to support header editing.  This
+ means that when the variable $edit_hdrs is set, the outgoing mail
+ headers will be added to the editor file when composing a message.
+ Headers can be modified or added in the editor.  Using $edit_hdrs
+ places some restrictions on tilde escapes; in particular, the ONLY
+ way to modify headers with $edit_hdrs set is through the editor.
+ These changes obsoleted the OLD_MAILER definition, so it was removed.
+ 
+ Although OLD_MAILER is gone, some newer MTAs will not accept From: and
+ Date: headers generated by the user agent (mush).  For these mailers,
+ a new definition PICKY_MAILER has been added to suppress these headers,
+ thus allowing the picky MTA to add them itself.  See README.
+ 
+ Write errors when sending mail are now correctly caught and dealt
+ with.  If write to the MTA fails, sending aborts and a dead.letter
+ is created.
+ 
+ The exit status of the MTA is now monitored, and a dead.letter is
+ created when the MTA returns an error.  This doesn't necessarily
+ mean the mail wasn't sent, and you may get error mail from the MTA.
+ 
+ Setting the $verbose variable during composition is now handled
+ correctly.
+ 
+ Added new definition MTA_EXIT.  It should be set to an integer
+ representing a successful exit status from your MTA (typically 0,
+ except for MMDF which is 9).
+ 
+ Improved the behavior of "quit" (q) in curses mode so thatwhen the folder
+ needs to be updated, it is no longer needlessly reread before exiting.
+ 
+ Interrupting the delay loop for an exclusive lock on a file (because
+ mail is probably being delivered) would terminate the loop incorrectly.
+ User notification is also improved.  Explicit unlocking added to
+ close_lock() for BSD due to Ultrix fclose problems.
+ 
+ Documented:  The long-undocumented -e option; the new edit_hdrs setting;
+ the "update" command separately from the "folder" command.
+ 
+ Piping of deleted messages is now possible if $show_deleted is set.
+ 
+ The README has more updated installation instructions for Sun and
+ Xenix systems.
+ 
+ Changed edit_menu.c, folders.c, hdr_procs.c, rite.c, select.c, viewopts.c,
+ and commands.c to make gcc happy.
+ 
+ A folder name collision bug that could occur when changing directories has
+ been corrected.  The folder name displayed when a folder is loaded (and at
+ the top of the screen in curses mode) is now shortened when possible to a
+ mush abbreviation form such as "+record" or "~/mbox".
+ 
+ ---------
+ MMDF-specific changes:
+ 
+ Changed the way locking is defined for MMDF, to better support
+ the variety of MMDF locking protocols.
+ 
+ Corrected compilation errors for MMDF/HOMEMAIL systems.
+ 
+ Changed the VERBOSE_ARG for MMDF from W to Ww.
+ 
+ MMDF/HOMEMAIL systems could lose mail if the "spool" mailbox was
+ updated and unlinked while new mail was being delivered.  The lock
+ is now released after the file has been removed (if it is being
+ removed) to prevent this.
*** mush-6.4/addrs.c	Fri Mar 24 10:15:05 1989
--- addrs.c	Wed Apr 12 10:28:53 1989
***************
*** 5,11 ****
  /*
   * Check to see if all addressees in list1 is in list2.
   * The lists must be as clean as the driven snow (no comments, aliases
!  * must have been expanded, all are separated by commas or whitespace.
   *
   * "user" matches "user" and "user@localhost"
   * "*user" matches "user" at any address whatsoever."
--- 5,11 ----
  /*
   * Check to see if all addressees in list1 is in list2.
   * The lists must be as clean as the driven snow (no comments, aliases
!  * must have been expanded, all are separated by whitespace (for mk_argv).
   *
   * "user" matches "user" and "user@localhost"
   * "*user" matches "user" at any address whatsoever."
***************
*** 64,77 ****
  		 * Note that "!" with no host indicates *all*
  		 * local users!!!
  		 */
! 		if (addrv[a][0] != '!') {
! 		   if (!lcase_strncmp(addrv[a], listv[l], -1) || !addrv[a][1])
! 			ret_val = 1;
! 		} else if (addrv[a][0] == '*') {
  		    /* "*user" == "user" or "*" == login */
  		    if (!addrv[a][1] && !lcase_strncmp(listv[l], login) ||
  			!lcase_strncmp(listv[l], addrv[a]+1, -1))
  			ret_val = 1;
  		} else for (h = 0; ourname && ourname[h]; h++)
  		    if (!lcase_strncmp(addrv[a]+1,
  			ourname[h], -1)) {
--- 64,77 ----
  		 * Note that "!" with no host indicates *all*
  		 * local users!!!
  		 */
! 		if (addrv[a][0] == '*') {
  		    /* "*user" == "user" or "*" == login */
  		    if (!addrv[a][1] && !lcase_strncmp(listv[l], login) ||
  			!lcase_strncmp(listv[l], addrv[a]+1, -1))
  			ret_val = 1;
+ 		} else if (addrv[a][0] != '!') {
+ 		   if (!lcase_strncmp(addrv[a], listv[l], -1) || !addrv[a][1])
+ 			ret_val = 1;
  		} else for (h = 0; ourname && ourname[h]; h++)
  		    if (!lcase_strncmp(addrv[a]+1,
  			ourname[h], -1)) {
***************
*** 368,377 ****
  route_addresses(to, cc, route_path)
  char *to, *cc, *route_path;
  {
!     char pre_path[256], addr[256];
      register char *next, *p;
!     int pre_len = 0;
  
      if (!route_path)
  	return;
      if (*route_path) {
--- 368,378 ----
  route_addresses(to, cc, route_path)
  char *to, *cc, *route_path;
  {
!     char pre_path[256], sender[HDRSIZ], tmp[256];
      register char *next, *p;
!     int c;
  
+     Debug("route_addresses()\n");
      if (!route_path)
  	return;
      if (*route_path) {
***************
*** 382,399 ****
  
      pre_path[0] = 0;
      /* Get the address of the sender (which is always listed first) */
!     if (!(next = get_name_n_addr(to, NULL, addr)))
  	return;
      /* check to see if there is only one addr on To: line and no Cc: header */
!     if (!*next && (!cc || !*cc))
  	return;
  
!     /* fix up the sender's address; improve_uucp_paths to optimize pre_path */
!     improve_uucp_paths(addr, sizeof addr, NULL);
! 
!     if (p = rindex(addr, '!')) {
  	*p = 0;
- 	pre_len = Strcpy(pre_path, addr); /* the uucp route he used */
  	Debug("Routing thru \"%s\"\n", pre_path);
      }
  
--- 383,411 ----
  
      pre_path[0] = 0;
      /* Get the address of the sender (which is always listed first) */
!     if (!(next = get_name_n_addr(to, NULL, NULL)))
  	return;
+     c = *next, *next = 0;
+     (void) strcpy(sender, to);
+     *next = c;
+     /* fix up the sender's address; improve_uucp_paths to optimize pre_path */
+     improve_uucp_paths(sender, sizeof sender, NULL);
+ 
      /* check to see if there is only one addr on To: line and no Cc: header */
!     if (!*next && (!cc || !*cc)) {
! 	(void) strcpy(to, sender);
  	return;
+     }
+     /* otherwise, get the pre_path */
+     if (p = get_name_n_addr(sender, NULL, tmp))
+ 	c = p - sender; /* save the original length */
+     if (*tmp)
+ 	(void) bang_form(pre_path, tmp);
+     else
+ 	pre_path[0] = 0;
  
!     if (p = rindex(pre_path, '!')) {
  	*p = 0;
  	Debug("Routing thru \"%s\"\n", pre_path);
      }
  
***************
*** 401,406 ****
--- 413,422 ----
  	 next++;
      improve_uucp_paths(next, HDRSIZ - (int)(next - to), pre_path);
      improve_uucp_paths(cc, HDRSIZ, pre_path);
+     p = sender + c;
+     *p++ = ',', *p++ = ' ';
+     (void) strcpy(p, next);
+     (void) strcpy(to, sender);
  }
  
  /*
***************
*** 736,742 ****
      char **list; /* a list of addresses for comparison */
      int list_cnt = 0, l;
      register char c, *p, *b = buf, *start = to;
-     extern char *calloc();
  
      Debug("rm_redundant_addrs()\n");
      list = (char **) calloc(256, sizeof(char *));
--- 752,757 ----
*** mush-6.4/bind.c	Fri Mar 24 10:06:11 1989
--- bind.c	Wed Apr 12 10:43:03 1989
***************
*** 582,594 ****
  long func;
  {
      register struct cmd_map *tmp;
-     struct cmd_map *calloc();
  
      if (!str || !*str)
  	return;
  
      /* now make a new option struct and set fields */
!     if (!(tmp = calloc((unsigned)1, sizeof(struct cmd_map)))) {
  	error("calloc");
  	return;
      }
--- 582,593 ----
  long func;
  {
      register struct cmd_map *tmp;
  
      if (!str || !*str)
  	return;
  
      /* now make a new option struct and set fields */
!     if (!(tmp = (struct cmd_map *)calloc((unsigned)1,sizeof(struct cmd_map)))) {
  	error("calloc");
  	return;
      }
*** mush-6.4/cmd_help	Fri Mar 24 10:13:02 1989
--- cmd_help	Tue Apr 18 09:26:40 1989
***************
*** 302,308 ****
  and increment the current message pointer to that message.
  %%
  
! %own_hdrs%
  This command is used to set, unset or view your personalized
  message headers.  These headers are included in all your
  outgoing mail.
--- 302,308 ----
  and increment the current message pointer to that message.
  %%
  
! %my_hdr%
  This command is used to set, unset or view your personalized
  message headers.  These headers are included in all your
  outgoing mail.
*** mush-6.4/commands.c	Fri Mar 24 10:14:32 1989
--- commands.c	Wed Apr 12 10:20:11 1989
***************
*** 730,736 ****
  char **argv;
  {
      int n = 0;
!     char *Cmds[sizeof cmds/sizeof(struct cmd)], *p, *malloc(), buf[30];
  
      qsort((char *)cmds, sizeof(cmds)/sizeof(struct cmd)-1,
  			sizeof(struct cmd), sorter);
--- 730,736 ----
  char **argv;
  {
      int n = 0;
!     char *Cmds[sizeof cmds/sizeof(struct cmd)], *p, buf[30];
  
      qsort((char *)cmds, sizeof(cmds)/sizeof(struct cmd)-1,
  			sizeof(struct cmd), sorter);
***************
*** 798,804 ****
  	char **new_environ = (char **)malloc((i+2) * sizeof(char *));
  	/* add 1 for the new item, and 1 for null-termination */
  	if (!new_environ) {
! 	    free(newstr);
  	    return -1;
  	}
  	spaces = 1;
--- 798,804 ----
  	char **new_environ = (char **)malloc((i+2) * sizeof(char *));
  	/* add 1 for the new item, and 1 for null-termination */
  	if (!new_environ) {
! 	    xfree(newstr);
  	    return -1;
  	}
  	spaces = 1;
***************
*** 880,885 ****
--- 880,886 ----
      int edited = 0;
      char buf[MAXPATHLEN], *dir, *edit_cmd[3];
      u_long flags = 0L;
+     char *cmd = *argv;
      FILE *fp;
  
      if (istool)
***************
*** 927,933 ****
  #endif /* MMDF */
  	wprint("(%d lines)\n", copy_msg(i, fp, flags));
  
! 	if (!(edit_cmd[0] = do_set(set_options, "visual")) || !*edit_cmd[0])
  	    edit_cmd[0] = DEF_EDITOR;
  	edit_cmd[1] = buf;
  	edit_cmd[2] = NULL;
--- 928,935 ----
  #endif /* MMDF */
  	wprint("(%d lines)\n", copy_msg(i, fp, flags));
  
! 	if (!(edit_cmd[0] = do_set(set_options,
! 	    (*cmd == 'v')? "visual" : "editor")) || !*edit_cmd[0])
  	    edit_cmd[0] = DEF_EDITOR;
  	edit_cmd[1] = buf;
  	edit_cmd[2] = NULL;
***************
*** 956,961 ****
--- 958,964 ----
      char buf[256];
      u_long flg = 0L;
      extern FILE *ed_fp;
+     int show_deleted = !!do_set(set_options, "show_deleted");
  
      /* Increment argv only if argv[0] is the mush command "pipe" */
      if (x && p && (!strcmp(p, "pipe") || !strcmp(p, "Pipe"))) {
***************
*** 996,1002 ****
      for (x = 0; x < msg_cnt; x++)
  	if (msg_bit(list, x)) {
  	    current_msg = x;
! 	    if (ison(msg[x].m_flags, DELETE)) {
  		print("Message %d deleted; ", x+1);
  		if (iscurses)
  		    print_more("skipping it.");
--- 999,1005 ----
      for (x = 0; x < msg_cnt; x++)
  	if (msg_bit(list, x)) {
  	    current_msg = x;
! 	    if (!show_deleted && ison(msg[x].m_flags, DELETE)) {
  		print("Message %d deleted; ", x+1);
  		if (iscurses)
  		    print_more("skipping it.");
*** mush-6.4/config.h-dist	Fri Mar 24 09:58:35 1989
--- config.h-dist	Wed Apr 12 10:13:26 1989
***************
*** 10,35 ****
  #define ALTERNATE_HOME	"/tmp"       /* Path must be read/write to EVERYONE */
  #define EDFILE  	".edXXXXXX"  /* file/pathname added to user's "home" */
  
! /* mail delivery system */
  #ifdef MMDF
  #define MAIL_DELIVERY	"exec MMDFBIN/submit -mlnr"
! #define VERBOSE_ARG	"W"
  #else /* MMDF */
! #define MAIL_DELIVERY	"/usr/lib/sendmail -i"
  #define VERBOSE_ARG	"-v"    /* undef if none exists */
  #define METOO_ARG	"-m"    /* man sendmail for more info. */
  #endif /* MMDF */
  
- /* Headers that will NOT be included when forwarding mail */
- #define IGNORE_ON_FWD	"status"
- 
- #define	MAXMSGS		1000	/* maximum number of messages we can read */
- #define HDRSIZ BUFSIZ	/* This should not be < BUFSIZ! (but can be >) */
- 
- #define VPRINTF		/* If your system supports the vprintf() functions,
- 			 * True for sys-v and later sun versions (3.0+ ?).
- 			 */
- 
  /* If your mail transfer agent uses something *besides* "From " to separate
   * adjacent messages in a folder, define MSG_SEPARATOR to be this string.
   * If that string is 4 ^A's, then the string would be "\001\001\001\001"
--- 10,56 ----
  #define ALTERNATE_HOME	"/tmp"       /* Path must be read/write to EVERYONE */
  #define EDFILE  	".edXXXXXX"  /* file/pathname added to user's "home" */
  
! /*
!  * Define INTERNAL_MALLOC and recompile if you have trouble with mush
!  * core-dumping due to malloc/free errors.  Also, if you run a System 5
!  * variant, you might notice a performance improvement if you define this
!  * variable.  It uses the malloc library written by Larry Wall for "perl".
!  */
! /* #define INTERNAL_MALLOC */
! 
! /*
!  * Define TIMEZONE if your system has neither the SysV external variable
!  * tzname nor the BSD timezone() function.  The example below is for
!  * Gould BSD4.3 systems; others should define it as a string, e.g. "PST"
!  * If TIMEZONE is defined, DAYLITETZ can also be defined, e.g. "PDT"
!  */
! /* #define TIMEZONE T->tm_zone */
! 
! /* mail delivery system macros and defines... */
! 
! /*
!  * If you are using MMDF, define MMDF here.
!  */
! /* #define MMDF */
  #ifdef MMDF
+ /*
+  * If MMDF delivers mail the user's home directory, define HOMEMAIL.
+  * Also check the definition of the delivery file name MAILFILE, below.
+  */
+ /* #define HOMEMAIL */
  #define MAIL_DELIVERY	"exec MMDFBIN/submit -mlnr"
! #define VERBOSE_ARG	"Ww"
! #define MTA_EXIT	9	/* exit status for successful submit */
  #else /* MMDF */
! /*
!  * If you are not using MMDF, check these definitions.
!  */
! #define MAIL_DELIVERY	"/usr/lib/sendmail -i" /* "-i" works like "-oi" */
  #define VERBOSE_ARG	"-v"    /* undef if none exists */
  #define METOO_ARG	"-m"    /* man sendmail for more info. */
+ #define MTA_EXIT	0	/* exit status for successful mail delivery */
  #endif /* MMDF */
  
  /* If your mail transfer agent uses something *besides* "From " to separate
   * adjacent messages in a folder, define MSG_SEPARATOR to be this string.
   * If that string is 4 ^A's, then the string would be "\001\001\001\001"
***************
*** 37,45 ****
   */
  /* #define MSG_SEPARATOR "From " */
  #ifdef MMDF
- #ifndef OLD_MAILER
- #define OLD_MAILER
- #endif /* OLD_MAILER */
  /*
   * These values should be identical (respectively) to the contents of
   * delim1 and delim2 in MMDFSRC/conf/yoursite/conf.c (sans newline).
--- 58,63 ----
***************
*** 47,66 ****
  #define MSG_SEPARATOR	"\001\001\001\001\n"
  #define END_MSG_SEP	"\001\001\001\001\n"
  /*
!  * You only need to define LCKDFLDIR if you have MMDF configured to use a
!  * locking module which accesses the global MMDF variable "lckdfldir".
   * Most of you WILL NOT need this, since you probably use one of the more
!  * sophisticated locking modules provided with MMDF.
   */
! /* #define LCKDFLDIR	"/usr/spool/mmdf/lockfiles" */
  
  /*
!  * IMPORTANT NOTE: If you are trying to use mush with MMDF, you need to
!  * remove most of the LOCFUN declarations in the MMDF locking module which
!  * is in use at your site and recompile the MMDF library.  The only function
!  * which need not appear in the new libmmdf.a is lk_name().
   */
! #endif /* MMDF */
  
  #define LS_COMMAND	"ls"
  #define FORTUNE		"/usr/games/fortune"
--- 65,113 ----
  #define MSG_SEPARATOR	"\001\001\001\001\n"
  #define END_MSG_SEP	"\001\001\001\001\n"
  /*
!  * You only need to define LCKDFLDIR if you have MMDF configured to use the
!  * locking routines in lib/util/lk_lock.c (ie., link(2)-based locking).
   * Most of you WILL NOT need this, since you probably use one of the more
!  * sophisticated locking modules provided with MMDF.  You'll also need to
!  * remove the LOCFUN declarations of lk_lock() and lk_unlock() in lk_lock.c
!  * and recompile the MMDF library.  Finally, remember to alter the Makefile
!  * so as to access the MMDF library at the link step.
   */
! /* #define LCKDFLDIR	"/usr/spool/mmdf/lockfiles" (for example) */
! #endif /* MMDF */
  
+ /* If your mailer does not understand commas between addresses, you should
+  * define NO_COMMAS.  This includes pre-3.0 smail and default MTAs used on
+  * xenix, and sys-v systems.
+  * This does NOT apply to MMDF or sendmail.
+  */
+ /* #define NO_COMMAS */
+ 
  /*
!  * Most RFC822 compliant mailers (sendmail) will add the headers From:
!  * and Date: on outgoing mail.  If the user or UA sends these headers,
!  * most MTAs will not append them automatically.  However, there are
!  * certain MTAs which will not allow this -- these "picky mailers" will
!  * precede such headers with a '>' and make the headers very ugly and
!  * somewhat redundant or contradictory.  It is advisable to set this
!  * *UNLESS* your MTA is not RFC822 compiant -- therefore you should NOT
!  * set this (xenix, sys-v).
   */
! /* #define PICKY_MAILER */
! 
! /* Headers that will NOT be included when forwarding mail */
! #define IGNORE_ON_FWD	"status"	/* comma or space separated list */
! 
! #define	MAXMSGS		1000	/* maximum number of messages we can read */
! #define HDRSIZ BUFSIZ	/* This should not be < BUFSIZ! (but can be >) */
! 
! /* If your system supports the vprintf() functions, True for sys-v and
!  * later sun versions (3.0+ ?).  Typically not true for BSD systems, but
!  * that will probably change in the future.
!  */
! #if defined(SYSV) || defined(sun)
! #define VPRINTF
! #endif /* SYSV || sun */
  
  #define LS_COMMAND	"ls"
  #define FORTUNE		"/usr/games/fortune"
*** mush-6.4/curses.c	Fri Mar 24 10:13:29 1989
--- curses.c	Wed Apr 12 10:41:20 1989
***************
*** 293,299 ****
  	    argc = Getstr(file, LINES-40, 0);
  	    clr_bot_line();
  	    if (argc < 0)
! 		return 0;
  	    if (argc > 0)
  		argv[1] = file, argc = 2;
  	    else
--- 293,299 ----
  	    argc = Getstr(file, LINES-40, 0);
  	    clr_bot_line();
  	    if (argc < 0)
! 		break;
  	    if (argc > 0)
  		argv[1] = file, argc = 2;
  	    else
***************
*** 300,308 ****
  		argc = 1;
  	    argv[argc] = NULL;
  	    turnon(glob_flags, PRE_CURSES);
! 	    if (c == C_SOURCE)
  		(void) source(argc, argv);
! 	    else
  		(void) save_opts(argc, argv);
  	    turnoff(glob_flags, PRE_CURSES);
  	}
--- 300,310 ----
  		argc = 1;
  	    argv[argc] = NULL;
  	    turnon(glob_flags, PRE_CURSES);
! 	    if (c == C_SOURCE) {
  		(void) source(argc, argv);
! 		mac_flush(); /* can't change things in mid-macro */
! 		redo = isoff(glob_flags, CNTD_CMD);
! 	    } else
  		(void) save_opts(argc, argv);
  	    turnoff(glob_flags, PRE_CURSES);
  	}
***************
*** 483,488 ****
--- 485,491 ----
  	when C_QUIT : case C_UPDATE : {
  	    u_long do_update = ison(glob_flags, DO_UPDATE);
  	    clr_bot_line();
+ 	    redo = (c == C_UPDATE);
  	    if (!vrfy_update(&redo))
  		if (c == C_UPDATE)
  		    break;
***************
*** 528,535 ****
  		     * then we need to reset the updatability of current folder
  		     */
  		    c = (ison(glob_flags, DO_UPDATE))? TRUE : FALSE;
! 		    if (strcmp(file, "-?"))
  			(void) vrfy_update(&redo);
  		    move(LINES-1, 0), refresh();
  		    if (cmd_line(sprintf(buf, "folder ! -N %s", file),
  			     msg_list) == -1) {
--- 531,540 ----
  		     * then we need to reset the updatability of current folder
  		     */
  		    c = (ison(glob_flags, DO_UPDATE))? TRUE : FALSE;
! 		    if (strcmp(file, "-?")) {
! 			redo = 1; /* so vrfy_update() won't quit */
  			(void) vrfy_update(&redo);
+ 		    }
  		    move(LINES-1, 0), refresh();
  		    if (cmd_line(sprintf(buf, "folder ! -N %s", file),
  			     msg_list) == -1) {
***************
*** 753,760 ****
  		putchar('\n');
  	    return 0;
  	}
! 	if (cmd_line(strcpy(buf, "update"), msg_list) != -1 &&
! 	    ison(glob_flags, CNTD_CMD))
  	    *redo = 1, turnoff(glob_flags, CNTD_CMD);
      }
      turnoff(glob_flags, DO_UPDATE);
--- 758,765 ----
  		putchar('\n');
  	    return 0;
  	}
! 	if (cmd_line(strcpy(buf, *redo? "update" : "quit"), msg_list) != -1
! 		&& ison(glob_flags, CNTD_CMD))
  	    *redo = 1, turnoff(glob_flags, CNTD_CMD);
      }
      turnoff(glob_flags, DO_UPDATE);
*** mush-6.4/dates.c	Fri Mar 24 10:02:50 1989
--- dates.c	Wed Apr 12 10:38:29 1989
***************
*** 202,229 ****
  char buf[];
  {
      struct tm 	  *T;
- #ifdef SYSV
-     long	  x;
-     extern char *tzname[];
      char *tz;
  
      (void) time(&x);
      T = localtime(&x);
!     tz = tzname[T->tm_isdst];
! #else /* SYSV */
! #ifdef BSD
      extern char     *timezone();
      struct timeval  mytime;
      struct timezone myzone;
-     char *tz;
  
      (void) gettimeofday(&mytime, &myzone);
      T = localtime(&mytime.tv_sec);
      tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime));
- #else
-     char *tz = "";
- #endif /* BSD */
  #endif /* !SYSV */
  
      return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
  	day_names[T->tm_wday],	/* day name */
--- 202,237 ----
  char buf[];
  {
      struct tm 	  *T;
      char *tz;
+ #if defined(SYSV) || defined(TIMEZONE)
+     long	  x;
  
      (void) time(&x);
      T = localtime(&x);
! #ifndef TIMEZONE
!     {
! 	extern char *tzname[];
! 	tz = tzname[T->tm_isdst];
!     }
! #endif /* TIMEZONE */
! #else /* SYSV || TIMEZONE */
      extern char     *timezone();
      struct timeval  mytime;
      struct timezone myzone;
  
      (void) gettimeofday(&mytime, &myzone);
      T = localtime(&mytime.tv_sec);
      tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime));
  #endif /* !SYSV */
+ 
+ #ifdef TIMEZONE
+ #ifdef DAYLITETZ
+     if (T->tm_isdst)
+ 	tz = DAYLITETZ;
+     else
+ #endif /* DAYLITETZ */
+     tz = TIMEZONE;
+ #endif /* TIMEZONE */
  
      return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
  	day_names[T->tm_wday],	/* day name */
*** mush-6.4/edit_menu.c	Fri Mar 24 09:58:36 1989
--- edit_menu.c	Wed Apr 12 10:40:13 1989
***************
*** 76,82 ****
  	return;
      }
      buf[0] = *escape;
!     switch(action) {
  	case EDIT_IT  : (void) strcpy(p, "v");
  	when PAGE     : (void) strcpy(p, "p");
  	when INC      : (void) strcpy(p, "i");
--- 76,82 ----
  	return;
      }
      buf[0] = *escape;
!     switch ((int) action) {
  	case EDIT_IT  : (void) strcpy(p, "v");
  	when PAGE     : (void) strcpy(p, "p");
  	when INC      : (void) strcpy(p, "i");
*** mush-6.4/kit.check	Tue Apr 18 17:29:04 1989
--- kit.check	Tue Apr 18 17:29:04 1989
***************
*** 0 ****
--- 1 ----
+  Part1 
-- 
Bart Schaefer       "And if you believe that, you'll believe anything."
							-- DangerMouse
CSNET / Internet                schaefer@cse.ogc.edu
UUCP                            ...{sun,tektronix,verdix}!ogccse!schaefer