[comp.mail.mush] Official 7.2.0 Patch Kit, Part02/04

schaefer@ogicse.cse.ogi.edu (Barton E. Schaefer) (11/05/90)

This is Part 2 of the Official Patch Kit for conversion of Mush 7.1.2 to
Mush 7.2.0.  See Part 1 for a complete manifest and other information.

Note that the copyright information in the README file will be slightly
modified by this patch.  This change is for purposes of clarification
only and does not change the intent of the copyright.

*** /tmp/,RCSt1009515	Sun Nov  4 20:02:03 1990
--- README	Sun Nov  4 16:57:28 1990
***************
*** 16,22 ****
  A Mail Transport Agent (MTA) is the program which mush communicates with
  that actually -delivers- mail.
  
! The Mush sources are copyright (c) 1986, 1987, 1988, 1989 by Dan Heller.
  Redistribution of the unmodified source code is permitted as long as all
  copyright notices remain intact and all other identifying notices remain
  in the code and in the binary.  This includes message headers on outgoing
--- 16,24 ----
  A Mail Transport Agent (MTA) is the program which mush communicates with
  that actually -delivers- mail.
  
! Mush is copyright (c) 1986, 1987, 1988, 1989, 1990 by Dan Heller.
! All Rights Reserved.   This software is not in the public domain.
! 
  Redistribution of the unmodified source code is permitted as long as all
  copyright notices remain intact and all other identifying notices remain
  in the code and in the binary.  This includes message headers on outgoing
***************
*** 91,97 ****
  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
--- 93,99 ----
  If you are using XENIX:
  
      There is one makefile for xenix: makefile.xenix.  However, SCO-xenix
!     runs on either 80286 or 80386 architectures.  This makefile 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
***************
*** 113,121 ****
      BSD and probably running a system-v flavor of unix -- this defines USG
      so that termio will be used.
  
!     SCO UNIX V.3.2 users will need to change the declaration of ttytype[]
!     in curses.c to be "extern unsigned char" when using terminfo-based
!     curses.  This may also be necessary with termcap-based curses.
  
      MicroPort sys-v users should probably remove the -O compiler option
      from the makefile, and may have trouble with the msg_bit() macro
--- 115,123 ----
      BSD and probably running a system-v flavor of unix -- this defines USG
      so that termio will be used.
  
!     SCO UNIX V.2.0 users should add -lx to OTHERLIBS in makefile.sys.v.
!     It may also be desirable to change MANDIR to /usr/man/man.C and
!     MANEXT to C in the makefile.
  
      MicroPort sys-v users should probably remove the -O compiler option
      from the makefile, and may have trouble with the msg_bit() macro
***************
*** 122,131 ****
      defined in mush.h.  It should be fairly trivial to generate an
      equivalent function.
  
-     Silicon Graphics Iris workstations should add -DDIRECTORY to the CFLAGS
-     in the makefile.  This prevents the portable directory routines from
-     being compiled in.
- 
  If you are using Ultrix:
  
      Start with makefile.bsd.
--- 124,129 ----
***************
*** 151,156 ****
--- 149,180 ----
      from the CFLAGS.  This will cause the portable directory access
      routines in that file to be compiled.
  
+ If you are using a hybrid BSD/SysV system:
+     You may have to use a combination of many of the defines listed
+     throughout this file.  You may also have to add additional libraries
+     to the LIBS= in the appropriate makefile.  For example, to use the
+     bsd system calls such as select(), getwd(), the directory reading
+     routines ...  you may have to define additional parameters such as
+     -DSELECT, -DGETWD, -DDIRECTORY, ...
+ 
+ Notes for some hybrid systems:
+     SGI workstations:
+     Silicon Graphics Iris workstations should add -DDIRECTORY to prevent
+     the portable directory routines from being compiled in.
+ 
+     You may optionally add -DSELECT if you want to use the BSD style
+     select() function.  If you do this, you must also add -lbsd to the
+     LIBS macro definition in the Makefile.
+     You will also need to #include <sys/times.h> in curs_io.c.
+ 
+     MIPS workstations:
+     These are also hybrid systems that may require additional hand-
+     configuration in order to work properly.  There seem to be
+     major differences between the last several releases, so your
+     milage may vary.  Currently, lock.c should be compiled with BSD
+     defined, but everything else should be SYSV.  -DGETWD should be
+     used and -lbsd may have to be added to LIBS in the Makefile.
+ 
  When you decide on an appropriate makefile, _copy_ it to a new file called
  Makefile _before_ making any of local changes.  Please read the following
  sections for addtional configuration information.  In addition to changing
***************
*** 363,368 ****
--- 387,396 ----
      try the same command using that file.  BSD machines before 4.3-tahoe
      do not have vprintf().
  
+ GETWD
+     This should be defined if your system uses the getwd() system call, as
+     opposed to getcwd(), and your system is not a BSD system (e.g. MIPS).
+ 
  ---------------
  The sprintf() function:
      If you *know* your system's sprintf returns a char *, you can remove the
***************
*** 400,406 ****
      system is a BSD system, then this is defined for you.  However, with the
      advent of hybrid bsd/sys-v systems, you may not be able to set BSD, but
      you know you still have select() --for such systems, define SELECT in
!     your makefile or in config.h.
  
      Newer xenix machines have this as so some system-v machines.  If you don't
      define one of BSD or SELECT, mush will use another function although not
--- 428,434 ----
      system is a BSD system, then this is defined for you.  However, with the
      advent of hybrid bsd/sys-v systems, you may not be able to set BSD, but
      you know you still have select() --for such systems, define SELECT in
!     your makefile or in config.h.  For example, SGI systems require this.
  
      Newer xenix machines have this as so some system-v machines.  If you don't
      define one of BSD or SELECT, mush will use another function although not
*** /tmp/,RCSt1009448	Sun Nov  4 20:01:30 1990
--- dates.c	Thu Nov  1 17:46:49 1990
***************
*** 26,34 ****
      { "UT",	  0,  0 },	{ "GMT",	  0,  0 },
      /* European Time */
      { "BST",	  1,  0 },				    /* Brit. Summer */
!     { "EET",	  0,  0 },	{ "EEST",	  1,  0 },	/* Eastern */
!     { "MET",	 -1,  0 },	{ "MEST",	  0,  0 },	/* Middle */
!     { "WET",	 -2,  0 },	{ "WEST",	 -1,  0 },	/* Western */
      /* North American Time */
      { "NST",	 -3,-30 },				    /* Newfoundland */
      { "AST",	 -4,  0 },	{ "ADT",	 -3,  0 },	/* Atlantic */
--- 26,37 ----
      { "UT",	  0,  0 },	{ "GMT",	  0,  0 },
      /* European Time */
      { "BST",	  1,  0 },				    /* Brit. Summer */
!     { "EET",	  2,  0 },	{ "EEST",	  3,  0 },	/* Eastern */
!     				{ "EET DST",	  3,  0 },
!     { "MET",	  1,  0 },	{ "MEST",	  2,  0 },	/* Middle */
!     				{ "MET DST",	  2,  0 },
!     { "WET",	  0,  0 },	{ "WEST",	  1,  0 },	/* Western */
!     				{ "WET DST",	  1,  0 },
      /* North American Time */
      { "NST",	 -3,-30 },				    /* Newfoundland */
      { "AST",	 -4,  0 },	{ "ADT",	 -3,  0 },	/* Atlantic */
***************
*** 214,261 ****
       * this is also the static buffer whose address we return.
       */
      static char month[64];
!     char Wkday[4], Zone[8];
      char a_or_p;
      int Month = 0, Day = 0, Year = 0;
!     int Uhour = 0, Umin = 0, Hours = -1, Mins = -1;
      struct tm T;
  
!     Zone[0] = 0;
      skipspaces(0);
  
      /* programmer's note -- there are too many scanfs here for some compilers
       * to put them all into one if statement.  Use goto's :-(  Also reset
       * Zone[0] after any sscanf() that could corrupt it on a partial match.
       */
  
      /* RFC822 formats and minor variations -- order important */
  
      /*   day_number month_name year_number time timezone */
!     if (sscanf(p, "%d %s %d %d:%d:%*d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone) >= 5 && Day)
  	goto gotit;
!     Zone[0] = 0;
      if (sscanf(p, "%d %s %d %d:%d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone) >= 5 && Day)
  	goto gotit;
!     Zone[0] = 0;
      /*   day_name day_number month_name year_number time timezone */
!     if (sscanf(p, "%*s %d %s %d %d:%d:%*d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone) >= 5 && Day)
  	goto gotit;
!     Zone[0] = 0;
      if (sscanf(p, "%*s %d %s %d %d:%d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone) >= 5 && Day)
  	goto gotit;
!     Zone[0] = 0;
  
      /* Ctime format (From_ lines) -- timezone almost never found */
  
      /*   day_name month_name day_number time year_number */
      if (sscanf(p, "%*s %s %d %d:%d:%*d %d %7s",
! 	    month, &Day, &Hours, &Mins, &Year, Zone) >= 5)
  	goto gotit;
!     Zone[0] = 0;
  
      /* Other common variants */
  
--- 217,268 ----
       * this is also the static buffer whose address we return.
       */
      static char month[64];
!     char Wkday[4], Zone[12], dst[4];
      char a_or_p;
      int Month = 0, Day = 0, Year = 0;
!     int Hours = -1, Mins = -1;
      struct tm T;
  
!     Zone[0] = dst[0] = 0;
      skipspaces(0);
  
      /* programmer's note -- there are too many scanfs here for some compilers
       * to put them all into one if statement.  Use goto's :-(  Also reset
       * Zone[0] after any sscanf() that could corrupt it on a partial match.
+      *
+      * Not yet handling all possible combinations of mailers using two-word
+      * time zones, e.g. MET DST instead of MEST.  Only the specific case
+      * where this was reported has been handled here.
       */
  
      /* RFC822 formats and minor variations -- order important */
  
      /*   day_number month_name year_number time timezone */
!     if (sscanf(p, "%d %s %d %d:%d:%*d %7s %3s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
  	goto gotit;
!     Zone[0] = dst[0] = 0;
      if (sscanf(p, "%d %s %d %d:%d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
  	goto gotit;
!     Zone[0] = dst[0] = 0;
      /*   day_name day_number month_name year_number time timezone */
!     if (sscanf(p, "%*s %d %s %d %d:%d:%*d %7s %3s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
  	goto gotit;
!     Zone[0] = dst[0] = 0;
      if (sscanf(p, "%*s %d %s %d %d:%d %7s",
! 	    &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
  	goto gotit;
!     Zone[0] = dst[0] = 0;
  
      /* Ctime format (From_ lines) -- timezone almost never found */
  
      /*   day_name month_name day_number time year_number */
      if (sscanf(p, "%*s %s %d %d:%d:%*d %d %7s",
! 	    month, &Day, &Hours, &Mins, &Year, Zone, dst) >= 5)
  	goto gotit;
!     Zone[0] = dst[0] = 0;
  
      /* Other common variants */
  
***************
*** 338,346 ****
  	goto gotit;
      Zone[0] = 0;
  
!     goto didnt_getit;
  
  gotit:
      if (Year > 1900)
  	Year -= 1900;
      if (!Month && (Month = month_to_n(month)) == -1) {
--- 345,359 ----
  	goto gotit;
      Zone[0] = 0;
  
!     if (ison(glob_flags, WARNING))
! 	print("Unknown date format: %s\n", p);
!     return NULL;
  
  gotit:
+     if (!lcase_strncmp(dst, "dst", -1)) {
+ 	(void) strcat(Zone, " ");
+ 	(void) strcat(Zone, dst);
+     }
      if (Year > 1900)
  	Year -= 1900;
      if (!Month && (Month = month_to_n(month)) == -1) {
***************
*** 371,380 ****
      T.tm_wday = T.tm_yday = 0;	/* not used in time2gmt() */
      T.tm_isdst = 0;		/* determined from Zone */
      return sprintf(month, "%ld%s%s", time2gmt(&T, Zone, 1), Wkday, Zone);
- didnt_getit:
-     if (ison(glob_flags, WARNING))
- 	print("Unknown date format: %s\n", p);
-     return NULL;
  }
  
  /* pass a string in the standard date format, put into string.
--- 384,389 ----
***************
*** 439,444 ****
--- 448,467 ----
      char zone[8];
  
      T = time_n_zone(zone);
+ #ifndef USA
+     {
+ 	long zoff_hr, zoff_sec = getzoff(zone);
+ 	if (zoff_sec < 0) {
+ 	    zone[0] = '-';
+ 	    zoff_sec = -zoff_sec; 
+ 	} else
+ 	    zone[0] = '+';
+ 	zoff_hr = zoff_sec / 3600;
+ 	zoff_sec -= zoff_hr * 3600;
+ 	(void) sprintf(&zone[1], "%02d%02d", zoff_hr, zoff_sec / 60);
+     }
+ #endif /* !USA */
+ 
      return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
  	day_names[T->tm_wday],	/* day name */
  	T->tm_mday,		/* day of the month */
*** /tmp/,RCSt1009579	Sun Nov  4 20:02:49 1990
--- hdr_sw.c	Sun Oct 21 19:24:47 1990
***************
*** 186,193 ****
--- 186,203 ----
  #define SAVE_MSG	(char *)'s'
  #define PRNT_MSG	(char *)'p'
  #define PRE_MSG		(char *)'P'
+ #define MARK_MSG	(char *)'m'
  #define HELP_MSG	(char *)'H'
  
+ #define MARK_TOGGLE	(char *)'T'
+ #define MARK_A		(char *)'A'
+ #define MARK_B		(char *)'B'
+ #define MARK_C		(char *)'C'
+ #define MARK_D		(char *)'D'
+ #define MARK_E		(char *)'E'
+ #define MARK_CLEAR	(char *)'c'
+ #define MARK_HELP	(char *)'h'
+ 
  /*ARGSUSED*/
  void
  hdr_io(canvas, event, arg)
***************
*** 238,244 ****
  	    do_menu(hdr_sw, event, window_get(hdr_sw, WIN_FD), n_array[line]);
  	else if (ID == MS_MIDDLE) {
  	    set_isread(n_array[line]);
! 	    msg_menu_func(DEL_MSG, n_array[line]);
  	} else {
  	    int do_do_hdrs = 0;
  	    if (current_msg != n_array[line]) {
--- 248,254 ----
  	    do_menu(hdr_sw, event, window_get(hdr_sw, WIN_FD), n_array[line]);
  	else if (ID == MS_MIDDLE) {
  	    set_isread(n_array[line]);
! 	    msg_menu_func((int)DEL_MSG, n_array[line]);
  	} else {
  	    int do_do_hdrs = 0;
  	    if (current_msg != n_array[line]) {
***************
*** 264,270 ****
  get_msg_menu()
  {
      int i;
!     Menu_item mi = NULL;
  
      static struct menu_rec msg_items[] = {
  	{ "Read",            READ_MSG  },
--- 274,280 ----
  get_msg_menu()
  {
      int i;
!     Menu_item mi = NULL, sub_mi;
  
      static struct menu_rec msg_items[] = {
  	{ "Read",            READ_MSG  },
***************
*** 273,281 ****
--- 283,302 ----
  	{ "Reply",           REPL_MSG  },
  	{ "Save",            SAVE_MSG  },
  	{ "Preserve",        PRE_MSG   },
+ 	{ "Mark",	     MARK_MSG  },
  	{ "Print",           PRNT_MSG  },
  	{ "Help",            HELP_MSG  },
      };
+     static struct menu_rec mark_msg_items[] = {
+ 	{ "Toggle Mark",    MARK_TOGGLE},
+ 	{ "Priority A",     MARK_A     },
+ 	{ "Priority B",     MARK_B     },
+ 	{ "Priority C",     MARK_C     },
+ 	{ "Priority D",     MARK_D     },
+ 	{ "Priority E",     MARK_E     },
+ 	{ "Clear Priority", MARK_CLEAR },
+ 	{ "Help",           MARK_HELP  },
+     };
  
      msg_menu = menu_create(MENU_NOTIFY_PROC, menu_return_item, NULL);
      for (i = 0; i < ArraySize(msg_items); i++) {
***************
*** 282,287 ****
--- 303,322 ----
  	mi = menu_create_item(MENU_STRING,	msg_items[i].str,
  			      MENU_CLIENT_DATA,	msg_items[i].data,
  			      NULL);
+ 	if (msg_items[i].data == MARK_MSG) {
+ 	    int j;
+ 	    /* get the menu from <Mark> and set as this item's pullright */
+ 	    Menu the_menu = menu_create(
+ 		MENU_NOTIFY_PROC, menu_return_item, NULL);
+ 	    for (j = 0; j < ArraySize(mark_msg_items); j++) {
+ 		sub_mi = menu_create_item(
+ 		    MENU_STRING,	mark_msg_items[j].str,
+ 		    MENU_CLIENT_DATA,	mark_msg_items[j].data,
+ 		    NULL);
+ 		(void) menu_set(the_menu, MENU_APPEND_ITEM, sub_mi, NULL);
+ 	    }
+ 	    menu_set(mi, MENU_PULLRIGHT, the_menu, NULL);
+ 	}
  	(void) menu_set(msg_menu, MENU_APPEND_ITEM, mi, NULL);
      }
  }
***************
*** 293,299 ****
  int fd, message;
  {
      char *action;
!     char * save_place;
      Menu_item cur_msg_item;
      static char buf[16];
  
--- 328,334 ----
  int fd, message;
  {
      char *action;
!     char *save_place;
      Menu_item cur_msg_item;
      static char buf[16];
  
***************
*** 304,309 ****
--- 339,345 ----
      if (fd) {
  	int line;
  	Rect *hdr_rect;
+ 	extern Menu hdr_save_menu;
  
  	if (!msg_menu)
  	    get_msg_menu();
***************
*** 324,338 ****
  	if (!cur_msg_item)
  	    return;
  #ifndef NO_WALK_MENUS
! 	    if ((Menu)menu_get(cur_msg_item, MENU_PARENT) == msg_menu) {
! 		action = (char *) menu_get(cur_msg_item, MENU_CLIENT_DATA);
! 	    } else {
! 		save_place = (char *)menu_get(cur_msg_item, MENU_CLIENT_DATA);
! 		action = SAVE_MSG;
! 	    }   /* endif */
! #else /* NO_WALK_MENUS */
! 	    action = (char *) menu_get(cur_msg_item, MENU_CLIENT_DATA);
  #endif /* NO_WALK_MENUS */
      } else
  	action = (char *) event;
  
--- 360,371 ----
  	if (!cur_msg_item)
  	    return;
  #ifndef NO_WALK_MENUS
! 	if ((Menu)menu_get(cur_msg_item, MENU_PARENT) == hdr_save_menu) {
! 	    save_place = (char *)menu_get(cur_msg_item, MENU_CLIENT_DATA);
! 	    action = SAVE_MSG;
! 	} else
  #endif /* NO_WALK_MENUS */
+ 	    action = (char *) menu_get(cur_msg_item, MENU_CLIENT_DATA);
      } else
  	action = (char *) event;
  
***************
*** 343,353 ****
  	    (void) panel_set(msg_num_item, PANEL_VALUE,
  					sprintf(buf, "%d", message+1), NULL);
  #ifndef NO_WALK_MENUS
! 		if (*save_place == '\0') { /* magic to mean "use Filename:" */
  		    do_file_dir(save_item, event);
! 		} else {
  		    xx_file_dir(save_item, save_place);
- 		}   /* endif */
  #else /* NO_WALK_MENUS */
  		event_id(event) = MS_LEFT;
  		do_file_dir(save_item, 0, event);
--- 376,385 ----
  	    (void) panel_set(msg_num_item, PANEL_VALUE,
  					sprintf(buf, "%d", message+1), NULL);
  #ifndef NO_WALK_MENUS
! 		if (*save_place == '\0') /* magic to mean "use Filename:" */
  		    do_file_dir(save_item, event);
! 		else
  		    xx_file_dir(save_item, save_place);
  #else /* NO_WALK_MENUS */
  		event_id(event) = MS_LEFT;
  		do_file_dir(save_item, 0, event);
***************
*** 356,363 ****
  	}
  	when HELP_MSG :
  	    help(0, "headers", tool_help);
- 	when PRNT_MSG : case PRE_MSG : case UNDEL_MSG : case DEL_MSG :
- 	    msg_menu_func(action, message);
  	when REPL_MSG : {
  	    extern Panel_item reply_item;
  	    (void) open_compose();
--- 388,393 ----
***************
*** 364,370 ****
  	    /* reply_item shouldn't be here */
  	    respond_mail(reply_item, message, NO_EVENT);
  	}
! 	otherwise :
  	    if (current_msg != message) {
  		current_msg = message;
  		(void) do_hdrs(0, DUBL_NULL, NULL);
--- 394,400 ----
  	    /* reply_item shouldn't be here */
  	    respond_mail(reply_item, message, NO_EVENT);
  	}
! 	when READ_MSG :
  	    if (current_msg != message) {
  		current_msg = message;
  		(void) do_hdrs(0, DUBL_NULL, NULL);
***************
*** 376,381 ****
--- 406,414 ----
  	    turnon(glob_flags, NEW_FRAME);
  	    more_prompt = compose_hdr(message);
  	    display_msg(message, (u_long)0);
+ 
+ 	otherwise :
+ 	    msg_menu_func((int)action, message);
      }
  }
  
***************
*** 385,405 ****
   */
  static void
  msg_menu_func(action, message)
! char *action;
  {
      int argc;
      register char **argv;
      char buf[32];
  
!     wprint("Message #%d ", message+1);
!     if (action == UNDEL_MSG || action == DEL_MSG)
! 	wprint("%sd.\n", sprintf(buf, "%selete",
! 			    (action == DEL_MSG)? "d": "und"));
!     else if (action == PRNT_MSG) {
! 	wprint("sent to printer.\n");
! 	(void) strcpy(buf, "lpr");
!     } else if (action == PRE_MSG)
! 	wprint("%sd.\n", strcpy(buf, "preserve"));
      (void) sprintf(&buf[strlen(buf)], " %d", message+1);
  
      if (argv = make_command(buf, (char ***) DUBL_NULL, &argc))
--- 418,450 ----
   */
  static void
  msg_menu_func(action, message)
! int action;
  {
      int argc;
      register char **argv;
      char buf[32];
  
!     switch (action) {
!         case PRNT_MSG :
! 	    wprint("Message #%d sent to printer.\n", message+1);
! 	    (void) strcpy(buf, "lpr");
! 	when UNDEL_MSG : case DEL_MSG :
! 	    (void) sprintf(buf, "%selete", (action == (int)DEL_MSG)?"d":"und");
!         when PRE_MSG :
! 	    (void) strcpy(buf, "preserve");
!         when MARK_MSG : case MARK_TOGGLE :
! 	    (void) sprintf(buf, "%smark",
! 		ison(msg[message].m_flags, M_PRIORITY(0))? "un" : "");
! 	when MARK_A : case MARK_B : case MARK_C : case MARK_D : case MARK_E :
! 	    (void) sprintf(buf, "mark -%c", action);
! 	when MARK_CLEAR	:
! 	    (void) strcpy(buf, "mark -");
! 	when MARK_HELP :
! 	    (void) help(0, "mark", tool_help);
! 	    return;
! 	otherwise :
! 	    print("unknown switch: %c\n", action);
!     }
      (void) sprintf(&buf[strlen(buf)], " %d", message+1);
  
      if (argv = make_command(buf, (char ***) DUBL_NULL, &argc))
*** /tmp/,RCSt1009430	Sun Nov  4 20:01:19 1990
--- mail.c	Tue Oct 23 16:27:07 1990
***************
*** 585,591 ****
  
      if (!strcmp(line, ".") && do_set(set_options, "dot"))
  	return 0;
!     if (line[0] != *escape) {
  	(void) fputs(line, ed_fp);
  	(void) fputc('\n', ed_fp);
  	(void) fflush(ed_fp);
--- 585,591 ----
  
      if (!strcmp(line, ".") && do_set(set_options, "dot"))
  	return 0;
!     if (line[0] != *escape || ison(glob_flags, QUOTE_MACRO)) {
  	(void) fputs(line, ed_fp);
  	(void) fputc('\n', ed_fp);
  	(void) fflush(ed_fp);
***************
*** 1049,1063 ****
      FILE *files[30];  /* 30 should be sufficiently large enough */
      char *names[30];
  #endif /* MAXFILES */
! #if defined(VERBOSE_ARG) && !defined(SUNTOOL)
      SIGRET (*oldchld)();
! #endif /* VERBOSE_ARG && !SUNTOOL */
      int next_file = 1; /* reserve files[0] for the mail delivery program */
      int log_file = -1; /* the index into the files array for mail logging */
      char buf[3*HDRSIZ];
      char *orig_to, *orig_cc, *orig_bcc; /* save originals to restore on error */
      char expand = !do_set(set_options, "no_expand");
!     int fork_err = 0;
  
      names[0] = names[1] = NULL; /* for free_vec() */
      /* If edit_hdrs, make sure the correct headers exist and are intact
--- 1049,1063 ----
      FILE *files[30];  /* 30 should be sufficiently large enough */
      char *names[30];
  #endif /* MAXFILES */
! #if defined(VERBOSE_ARG)
      SIGRET (*oldchld)();
! #endif /* VERBOSE_ARG */
      int next_file = 1; /* reserve files[0] for the mail delivery program */
      int log_file = -1; /* the index into the files array for mail logging */
      char buf[3*HDRSIZ];
      char *orig_to, *orig_cc, *orig_bcc; /* save originals to restore on error */
      char expand = !do_set(set_options, "no_expand");
!     int fork_pid;
  
      names[0] = names[1] = NULL; /* for free_vec() */
      /* If edit_hdrs, make sure the correct headers exist and are intact
***************
*** 1106,1116 ****
  	p = MAIL_DELIVERY;
  
  #ifdef VERBOSE_ARG
!     if (ison(flags, VERBOSE) || do_set(set_options, "verbose")) {
  	turnon(flags, VERBOSE); /* prevent fork when "verbose" has changed */
- #ifndef SUNTOOL
  	oldchld = signal(SIGCHLD, SIG_DFL); /* let pclose() do the wait() */
- #endif /* SUNTOOL */
  #ifdef MMDF
  	b = &buf[strlen(sprintf(buf, "%s%s", p, VERBOSE_ARG))];
  #else /* MMDF */
--- 1106,1115 ----
  	p = MAIL_DELIVERY;
  
  #ifdef VERBOSE_ARG
!     /* Tool mode can't do verbosity -- no window for the MTA output */
!     if (!istool && (ison(flags, VERBOSE) || do_set(set_options, "verbose"))) {
  	turnon(flags, VERBOSE); /* prevent fork when "verbose" has changed */
  	oldchld = signal(SIGCHLD, SIG_DFL); /* let pclose() do the wait() */
  #ifdef MMDF
  	b = &buf[strlen(sprintf(buf, "%s%s", p, VERBOSE_ARG))];
  #else /* MMDF */
***************
*** 1235,1241 ****
      Debug("mail command: %s\n", buf);
  
      if (isoff(flags, VERBOSE) && debug < 3)
! 	switch (fork()) {
  	    case  0:  /* the child will send the letter. ignore signals */
  #ifdef SYSV
  		if (setpgrp() == -1)
--- 1234,1240 ----
      Debug("mail command: %s\n", buf);
  
      if (isoff(flags, VERBOSE) && debug < 3)
! 	switch (fork_pid = fork()) {
  	    case  0:  /* the child will send the letter. ignore signals */
  #ifdef SYSV
  		if (setpgrp() == -1)
***************
*** 1243,1252 ****
  		if (setpgrp(0, getpid()) == -1)
  #endif /* SYSV */
  		    error("setpgrp");
! #ifndef SUNTOOL
  		(void) signal(SIGCHLD, SIG_DFL);
  		(void) signal(SIGTERM, SIG_IGN);
- #endif /* SUNTOOL */
  		(void) signal(SIGINT, SIG_IGN);
  		(void) signal(SIGHUP, SIG_IGN);
  		(void) signal(SIGQUIT, SIG_IGN);
--- 1242,1253 ----
  		if (setpgrp(0, getpid()) == -1)
  #endif /* SYSV */
  		    error("setpgrp");
! 		/* NOTE: No special case needed for tool here because
! 		 * this is the sending child -- it's going to pclose()
! 		 * and then exit(), so who cares about the notifier?
! 		 */
  		(void) signal(SIGCHLD, SIG_DFL);
  		(void) signal(SIGTERM, SIG_IGN);
  		(void) signal(SIGINT, SIG_IGN);
  		(void) signal(SIGHUP, SIG_IGN);
  		(void) signal(SIGQUIT, SIG_IGN);
***************
*** 1261,1267 ****
  		turnon(glob_flags, IGN_SIGS);
  	    when -1:
  		error("fork failed trying to send mail");
- 		fork_err++;
  		if (isoff(flags, EDIT_HDRS)) {
  		    strcpy(To, orig_to);
  		    strcpy(Cc, orig_cc);
--- 1262,1267 ----
***************
*** 1269,1276 ****
  		}
  		/* fall thru */
  	    default:
  		/* istool doesn't need ed_fp, so don't keep it around */
! 		if (istool || !fork_err && isoff(glob_flags, REDIRECT))
  		    (void) fclose(ed_fp), ed_fp = NULL_FILE;
  		free_vec(&names[1]);
  		if (isoff(flags, EDIT_HDRS))
--- 1269,1287 ----
  		}
  		/* fall thru */
  	    default:
+ 		if (fork_pid > 0) {
+ #ifdef SUNTOOL
+ 		    /* If we're a tool, we have to register a handler
+ 		     * for the fork_pid.  Otherwise, it's used only as
+ 		     * an error indicator, so reset it to zero.
+ 		     */
+ 		    if (istool)
+ 			notify_set_wait3_func(mfprint_sw, my_wait3, fork_pid);
+ #endif /* SUNTOOL */
+ 		    fork_pid = 0;
+ 		}
  		/* istool doesn't need ed_fp, so don't keep it around */
! 		if (istool || !fork_pid && isoff(glob_flags, REDIRECT))
  		    (void) fclose(ed_fp), ed_fp = NULL_FILE;
  		free_vec(&names[1]);
  		if (isoff(flags, EDIT_HDRS))
***************
*** 1280,1289 ****
  		    (void) signal(SIGQUIT, oldquit);
  		    (void) signal(SIGTERM, oldterm);
  		}
! 		return 0 - fork_err;
  	}
  
- 
  #ifdef MMDF
      *(addr_list-1) = '\0';
  #endif /* MMDF */
--- 1291,1299 ----
  		    (void) signal(SIGQUIT, oldquit);
  		    (void) signal(SIGTERM, oldterm);
  		}
! 		return fork_pid;
  	}
  
  #ifdef MMDF
      *(addr_list-1) = '\0';
  #endif /* MMDF */
***************
*** 1452,1463 ****
      } else
  	rm_edfile(0);
  
- #ifndef SUNTOOL
  #ifdef VERBOSE_ARG
!     if (ison(flags, VERBOSE))
  	(void) signal(SIGCHLD, oldchld);
  #endif /* VERBOSE_ARG */
- #endif /* SUNTOOL */
  
      if (ison(flags, VERBOSE) || debug > 2) {
  	if (isoff(glob_flags, REDIRECT))
--- 1462,1471 ----
      } else
  	rm_edfile(0);
  
  #ifdef VERBOSE_ARG
!     if (!istool && ison(flags, VERBOSE))
  	(void) signal(SIGCHLD, oldchld);
  #endif /* VERBOSE_ARG */
  
      if (ison(flags, VERBOSE) || debug > 2) {
  	if (isoff(glob_flags, REDIRECT))
***************
*** 1552,1558 ****
  	    continue;
  	if (for_editor)
  	    if (own_from)
! 		(void) fputs(own_from, files[i]), *own_from = 0;
  	    else
  		(void) fputs(From_buf, files[i]);
  	else if (isoff(flags, EDIT_HDRS)) {
--- 1560,1566 ----
  	    continue;
  	if (for_editor)
  	    if (own_from)
! 		(void) fputs(own_from, files[i]);
  	    else
  		(void) fputs(From_buf, files[i]);
  	else if (isoff(flags, EDIT_HDRS)) {
***************
*** 1560,1566 ****
  	    if (i > 0)
  #endif /* PICKY_MAILER */
  	    if (own_from)
! 		(void) fputs(own_from, files[i]), *own_from = 0;
  	    else
  		(void) fputs(From_buf, files[i]);
  	    got_from = TRUE;
--- 1568,1574 ----
  	    if (i > 0)
  #endif /* PICKY_MAILER */
  	    if (own_from)
! 		(void) fputs(own_from, files[i]);
  	    else
  		(void) fputs(From_buf, files[i]);
  	    got_from = TRUE;
***************
*** 1576,1581 ****
--- 1584,1591 ----
  		fprintf(files[i], "In-Reply-To: %s\n", in_reply_to);
  	}
      }
+     if (own_from)
+ 	*own_from = 0; /* buf[0] must be 0 below */
      /* next print user's own message headers */
      if (for_editor || isoff(flags, EDIT_HDRS))
  	if (own_hdrs && !do_set(set_options, "no_hdrs")) {
***************
*** 1710,1719 ****
  	if (i > 0) {
  #endif /* PICKY_MAILER */
  	if (!got_from)
! 	    if (own_from)
! 		(void) fputs(own_from, files[i]);
! 	    else
! 		(void) fputs(From_buf, files[i]);
  	if (!got_date)
  	    (void) fprintf(files[i], "%sDate: %s\n",
  		ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
--- 1720,1726 ----
  	if (i > 0) {
  #endif /* PICKY_MAILER */
  	if (!got_from)
! 	    (void) fputs(From_buf, files[i]);
  	if (!got_date)
  	    (void) fprintf(files[i], "%sDate: %s\n",
  		ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
*** /tmp/,RCSt1009564	Sun Nov  4 20:02:42 1990
--- makefile.hpux	Sun Oct 21 19:24:53 1990
***************
*** 16,22 ****
  OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
  	addrs.o malloc.o glob.o
  
! HELP_FILES= README README-7.0 README-7.1 mush.1 cmd_help \
  	Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  
  # If your HP-UX version is older than 6.5, you will need remove -DDIRECTORY
--- 16,22 ----
  OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
  	addrs.o malloc.o glob.o
  
! HELP_FILES= README README-7.0 README-7.1 README-7.2 mush.1 cmd_help \
  	Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  
  # If your HP-UX version is older than 6.5, you will need remove -DDIRECTORY
*** /tmp/,RCSt1009457	Sun Nov  4 20:01:35 1990
--- msgs.c	Sun Oct 21 19:24:55 1990
***************
*** 162,188 ****
  	}
  
  	if (ison(flags, UPDATE_STATUS))
! 	    if (!strncmp(line, "Status:", 7))
! 		continue; /* ignore this and other "Status" lines */
  	    else if (!on_hdr) {
! 		/* preserve NEW/UNREAD status on preserved messages */
  		p = line;
! 		p += Strcpy(p, "Status: O");
! 		if (isoff(msg[n].m_flags, UNREAD) &&
! 		    isoff(msg[n].m_flags, PRESERVE))
! 		    *p++ = 'R';
! 		if (ison(msg[n].m_flags, SAVED))
! 		    *p++ = 'S';
! 		if (ison(msg[n].m_flags, REPLIED))
! 		    *p++ = 'r';
! 		if (ison(msg[n].m_flags, PRINTED))
! 		    *p++ = 'p';
! 		if (ison(msg[n].m_flags, FORWARD))
! 		    *p++ = 'f';
! 		*p++ = '\n', *p = 0;
! 		(void) fputs(line, fp);
! 		line[0] = '\n', line[1] = '\0';
  		turnoff(flags, UPDATE_STATUS);
  	    }
  	if (on_hdr && (isoff(flags, NO_IGNORE) || ison(flags, FORWARD))) {
  	    p = any(line, " \t:");
--- 162,204 ----
  	}
  
  	if (ison(flags, UPDATE_STATUS))
! 	    if (!strncmp(line, "Status:", 7) || !strncmp(line, "Priority:", 9))
! 		continue; /* ignore "Status" and "Priority" lines */
  	    else if (!on_hdr) {
! 		int i, write_priority = 0;
  		p = line;
! 		p += Strcpy(p, "Priority:");
! 		for (i = 0; i < MAX_PRIORITY; i++)
! 		    if (ison(msg[n].m_flags, M_PRIORITY(i + 1))) {
! 			write_priority = 1;
! 			*p++ = ' ';
! 			*p++ = i + 'A';
! 		    }
! 		if (write_priority) {
! 		    *p++ = '\n', *p = 0;
! 		    (void) fputs(line, fp);
! 		}
! 		/* PRESERVE here avoids changing new message status */
! 		if (isoff(flags, PRESERVE) || /* NOT msg[n].m_flags */
! 			ison(msg[n].m_flags, OLD) ||
! 			isoff(msg[n].m_flags, UNREAD)) {
! 		    p = line;
! 		    p += Strcpy(p, "Status: O");
! 		    if (isoff(msg[n].m_flags, UNREAD))
! 			*p++ = 'R';
! 		    if (ison(msg[n].m_flags, SAVED))
! 			*p++ = 'S';
! 		    if (ison(msg[n].m_flags, REPLIED))
! 			*p++ = 'r';
! 		    if (ison(msg[n].m_flags, PRINTED))
! 			*p++ = 'p';
! 		    if (ison(msg[n].m_flags, FORWARD))
! 			*p++ = 'f';
! 		    *p++ = '\n', *p = 0;
! 		    (void) fputs(line, fp);
! 		}
  		turnoff(flags, UPDATE_STATUS);
+ 		line[0] = '\n', line[1] = '\0';
  	    }
  	if (on_hdr && (isoff(flags, NO_IGNORE) || ison(flags, FORWARD))) {
  	    p = any(line, " \t:");
***************
*** 249,256 ****
   * copy tempfile back to folder.
   * Return 1 on success, 0 on failure.
   */
! copyback(prompt)
  char *prompt;
  {
      register int	i = 0, held = 0, saved = 0;
      register u_long	flg = 0;
--- 265,273 ----
   * copy tempfile back to folder.
   * Return 1 on success, 0 on failure.
   */
! copyback(prompt, final)
  char *prompt;
+ int final;	/* Are we exiting or updating? */
  {
      register int	i = 0, held = 0, saved = 0;
      register u_long	flg = 0;
***************
*** 259,265 ****
      FILE 		*save_mail_fp = NULL_FILE;
  #endif /* SYSV */
      char		*mbox_file, action = 0;
!     int 		hold = 0, delete_it = 0, dont_unlink = FALSE;
      int			isspool, keepsave, write_err = FALSE;
      static int		first = 1;
  
--- 276,282 ----
      FILE 		*save_mail_fp = NULL_FILE;
  #endif /* SYSV */
      char		*mbox_file, action = 0;
!     int 		hold = 0, delete_it = 0, dont_unlink = !final;
      int			isspool, keepsave, write_err = FALSE;
      static int		first = 1;
  
***************
*** 385,390 ****
--- 402,410 ----
      print("Updating \"%s\"", mailfile);
  
      turnon(flg, UPDATE_STATUS);
+     /* Don't set OLD for new messages on update. */
+     if (!final)
+ 	turnon(flg, PRESERVE);
  
      keepsave = !!do_set(set_options, "keepsave");
      isspool = !strcmp(mailfile, spoolfile);
***************
*** 407,414 ****
  	    Debug("%s %d",
  		(action!='d')? "\ndeleting message:" : "", i+1), action = 'd';
  	    continue;
! 	} else if (ison(msg[i].m_flags, UNREAD) ||
! 		 ison(msg[i].m_flags, PRESERVE) || hold || !mbox) {
  	    Debug("%s %d",
  		(action!='s')? "\nsaving in spool:" : "", i+1), action = 's';
  	    if (copy_msg(i, mail_fp, flg, NULL) == -1) {
--- 427,435 ----
  	    Debug("%s %d",
  		(action!='d')? "\ndeleting message:" : "", i+1), action = 'd';
  	    continue;
! 	} else if (isoff(msg[i].m_flags, DO_UPDATE) || hold || !mbox ||
! 		ison(msg[i].m_flags, UNREAD) ||
! 		ison(msg[i].m_flags, PRESERVE)) {
  	    Debug("%s %d",
  		(action!='s')? "\nsaving in spool:" : "", i+1), action = 's';
  	    if (copy_msg(i, mail_fp, flg, NULL) == -1) {
***************
*** 664,669 ****
--- 685,700 ----
  		when 'T': case 'D': case 'Y': case 'y':
  		case 'M': case 'N': case 'W':
  		    b += Strcpy(b, Time(p, (long)0));
+ 		when '$':
+ 		{
+ 		    struct expand var;
+ 		    var.orig = p;
+ 		    if (varexp(&var)) {
+ 			b += Strcpy(b, var.exp);
+ 			xfree(var.exp);
+ 			p = var.rest - 1;
+ 		    }
+ 		}
  		otherwise: *b++ = *p;
  	    }
  	else if (*p == '!')
***************
*** 861,866 ****
--- 892,905 ----
  		    p = buf;
  		    if (!strncmp(buf, "Date:", 5))
  			strdup(msg[cnt].m_date_sent, parse_date(p+5));
+ 		    if (!strncmp(buf, "Priority:", 9)) {
+ 			for (p += 9 ; *p != '\n'; p++) {
+ 			    if (!isalpha(*p) || upper(*p) > 'A' + MAX_PRIORITY)
+ 				continue;
+ 			    turnon(msg[cnt].m_flags,
+ 				M_PRIORITY(upper(*p) - 'A' + 1));
+ 			}
+ 		    }
  		    if (get_status &&
  			    !(get_status = strncmp(p, "Status:", 7))) {
  			/* new mail should not have a Status: field! */
*** /tmp/,RCSt1009396	Sun Nov  4 20:01:07 1990
--- mush.h	Tue Oct 23 16:11:23 1990
***************
*** 32,41 ****
  #include <setjmp.h>
  #include "strings.h"
  
- #ifdef BSD
- #define fputs Fputs	/* See comments in print.c */
- #endif /* BSD */
- 
  extern char
      *malloc(),		/* allocate memory */
      *calloc(),		/* allocate and clear memory */
--- 32,37 ----
***************
*** 59,64 ****
--- 55,72 ----
  #endif /* SUN_4_0 */
  #endif /* SUNTOOL || SUN_3_5 || SUN_4_0 */
  
+ #ifdef BSD
+ #define fputs Fputs	/* See comments in print.c */
+ #endif /* BSD */
+ 
+ #if defined(BSD) || defined(GETWD)
+ extern char *getwd();
+ #define GetCwd(buf,len)	getwd(buf)
+ #else
+ extern char *getcwd();
+ #define GetCwd(buf,len) getcwd(buf,len)
+ #endif /* BSD || GETWD */
+ 
  #ifdef SUNTOOL
  #    include <suntool/sunview.h>
  #ifdef SUN_4_0
***************
*** 152,157 ****
--- 160,170 ----
  
  /* for system-V machines that run termio */
  #if defined(SYSV) && defined(USG)
+ #ifdef crmode
+ #undef crmode
+ #undef nocrmode
+ #endif /* nocrmode */
+ 
  unsigned char vmin, vtime;
  #define sg_erase  c_cc[2]
  #define sg_flags  c_lflag
***************
*** 273,278 ****
--- 286,293 ----
  #ifdef SUNTOOL
  /* stdout may be closed */
  #define printf wprint
+ #else /* !SUNTOOL */
+ #define ok_box print
  #endif /* SUNTOOL */
  
  #if defined(CURSES) || defined(SUNTOOL)
***************
*** 309,315 ****
  	if (isoff(msg[n].m_flags, REPLIED)) \
  	    turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
  #define set_isread(n)	  \
! 	if (ison(msg[n].m_flags, UNREAD)) \
  	    turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
  
  #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
--- 324,330 ----
  	if (isoff(msg[n].m_flags, REPLIED)) \
  	    turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
  #define set_isread(n)	  \
! 	if (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)) \
  	    turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
  
  #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
***************
*** 403,417 ****
  #define INDENT		ULBIT(12) /* indent included msg with string */
  #define NO_IGNORE	ULBIT(13) /* don't ignore headers */
  #define PRESERVE	ULBIT(14) /* preserve in mailbox unless deleted */
! #define M_TOP		ULBIT(14) /* just print the top of msg (same as pre) */
! #define FORWARD		ULBIT(15) /* Forward messages into the message buffer */
! #define REPLIED		ULBIT(16) /* Messages that have been replied to */
! #define NEW_SUBJECT	ULBIT(17) /* new subject regardless of $ask (mail -s) */
! #define SAVED		ULBIT(18) /* when message has been saved */
  #ifdef MSG_SEPARATOR
! #define NO_SEPARATOR	ULBIT(19) /* don't include message separator lines */
  #endif /* MSG_SEPARATOR */
  
  #define	MAXMSGS_BITS	MAXMSGS/sizeof(char)	/* number of bits for bitmap */
  
  struct msg {
--- 418,436 ----
  #define INDENT		ULBIT(12) /* indent included msg with string */
  #define NO_IGNORE	ULBIT(13) /* don't ignore headers */
  #define PRESERVE	ULBIT(14) /* preserve in mailbox unless deleted */
! #define M_TOP		ULBIT(15) /* just print the top of msg (same as pre) */
! #define FORWARD		ULBIT(16) /* Forward messages into the message buffer */
! #define REPLIED		ULBIT(17) /* Messages that have been replied to */
! #define NEW_SUBJECT	ULBIT(18) /* new subject regardless of $ask (mail -s) */
! #define SAVED		ULBIT(19) /* when message has been saved */
  #ifdef MSG_SEPARATOR
! #define NO_SEPARATOR	ULBIT(20) /* don't include message separator lines */
  #endif /* MSG_SEPARATOR */
  
+ #define M_PRIORITY(n)	ULBIT(21+(n))
+ /* It is possible to reset MAX_PRIORITY to as high as 10 */
+ #define MAX_PRIORITY	5
+ 
  #define	MAXMSGS_BITS	MAXMSGS/sizeof(char)	/* number of bits for bitmap */
  
  struct msg {
***************
*** 438,443 ****
--- 457,468 ----
  extern struct cmd ucb_cmds[];
  extern struct cmd cmds[], hidden_cmds[];
  
+ struct expand {
+     char *orig;		/* string beginning with substring to be expanded */
+     char *exp;		/* result of expansion of substring */
+     char *rest;		/* rest of the original string beyond substring */
+ };
+ 
  FILE
      *tmpf,		/* temporary holding place for all mail */
      *mask_fopen(),	/* open a file with umask 077 (permissions 600) */
***************
*** 514,520 ****
--- 539,549 ----
      exec_pid,		/* pid of a command that has been "exec"ed */
      hist_no,		/* command's history number */
      iscurses,		/* if we're running curses */
+ #if defined(SUNTOOL) || defined(lint)
      istool,		/* argv[0] == "xxxxtool", ranges from 0 to 2 */
+ #else /* !SUNTOOL */
+ #define istool 0
+ #endif /* SUNTOOL */
      n_array[128],	/* array of message numbers in the header window */
      screen,		/* number of headers window can handle */
      wrapcolumn,		/* compose mode line wrap, measured from left */
***************
*** 522,528 ****
      close_lock(), 	/* unlock and close a file opened by lock_fopen() */
  
      mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
!     folder(), folders(), merge_folders(), do_undigest(),
      save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
      save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
      do_pick(), print_help(), question_mark(), do_from(), my_stty(),
--- 551,557 ----
      close_lock(), 	/* unlock and close a file opened by lock_fopen() */
  
      mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
!     folder(), folders(), merge_folders(), do_undigest(), mark_msg(),
      save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
      save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
      do_pick(), print_help(), question_mark(), do_from(), my_stty(),
***************
*** 594,599 ****
--- 623,629 ----
  Notify_value
      do_check(),		/* check for new mail on timeout */
      destroy_proc(),	/* Destroy procedure. */
+     my_wait3(),		/* Handle wait for child exit */
      scroll_textwin(),	/* Do fancy TEXTSW scrolling */
      edit_msg_textwin();	/* Auto-positioning in compose TEXTSW */
  
***************
*** 601,608 ****
  Frame compose_frame;    /* Compose frame. */
  Textsw pager_textsw;	/* for "paging" messages and other lists.. */
  Textsw mfprint_sw;	/* Textsw in main mush frame for wprint() */
- Textsw cprint_sw;	/* Textsw in compose frame for wprint() */
- Textsw wprint_sw;	/* Current text subwindow for wprint() */
  Canvas hdr_sw; 		/* Canvas for message headers */
  Tty tty_sw; 		/* subwindow which forks a shell (usually editor) */
  
--- 631,636 ----
*** /tmp/,RCSt1009576	Sun Nov  4 20:02:47 1990
--- panels.c	Sun Oct 21 19:25:00 1990
***************
*** 51,57 ****
      close_frame(), do_options(), do_compose(), do_send(), do_sort(),
      do_edit(), delete_mail(), respond_mail(), do_help(), do_lpr(),
      do_update(), abort_mail(), do_include(), load_from_file(),
!     save_to_file(), tilde_from_menu(), fkey_interposer();
  
  extern Panel_setting
      msg_num_done(), file_dir();
--- 51,57 ----
      close_frame(), do_options(), do_compose(), do_send(), do_sort(),
      do_edit(), delete_mail(), respond_mail(), do_help(), do_lpr(),
      do_update(), abort_mail(), do_include(), load_from_file(),
!     save_to_file(), tilde_from_menu(), fkey_interposer(), do_mark();
  
  extern Panel_setting
      msg_num_done(), file_dir();
***************
*** 81,87 ****
  	PANEL_LABEL_IMAGE,
  	    panel_button_image(panel, "Help", 4, mush_font),
  	PANEL_CHOICE_STRINGS,
! 	    "General", "Help with \"help\"", "The Mouse", "Windows",
  	    "Message headers", "Message lists", "Folders", NULL,
  	PANEL_NOTIFY_PROC, 		do_help,
  	NULL);
--- 81,87 ----
  	PANEL_LABEL_IMAGE,
  	    panel_button_image(panel, "Help", 4, mush_font),
  	PANEL_CHOICE_STRINGS,
! 	    "About", "Help with \"help\"", "The Mouse", "Windows",
  	    "Message headers", "Message lists", "Folders", NULL,
  	PANEL_NOTIFY_PROC, 		do_help,
  	NULL);
***************
*** 178,184 ****
  	NULL);
      sub_hdr_item[5] = panel_create_item(panel, PANEL_CHOICE,
  	PANEL_ATTRIBUTE_LIST, 		choice_args,
! 	PANEL_LABEL_STRING,   		"Menu         ",
  	PANEL_MENU_TITLE_IMAGE,	    	&mouse_right,
  	PANEL_CHOICE_STRINGS, 		"Help", NULL,
  	PANEL_NOTIFY_PROC,    		read_mail,
--- 178,184 ----
  	NULL);
      sub_hdr_item[5] = panel_create_item(panel, PANEL_CHOICE,
  	PANEL_ATTRIBUTE_LIST, 		choice_args,
! 	PANEL_LABEL_STRING,   		"Menu   ",
  	PANEL_MENU_TITLE_IMAGE,	    	&mouse_right,
  	PANEL_CHOICE_STRINGS, 		"Help", NULL,
  	PANEL_NOTIFY_PROC,    		read_mail,
***************
*** 187,192 ****
--- 187,202 ----
      (void) panel_create_item(panel, PANEL_CHOICE,
  	PANEL_ATTRIBUTE_LIST, 		choice_args,
  	PANEL_LABEL_IMAGE,
+ 	    panel_button_image(panel, "Mark", 4, mush_font),
+ 	PANEL_CHOICE_STRINGS,
+ 	    "Toggle Mark", "Priority A", "Priority B", "Priority C",
+ 	    "Priority D", "Priority E", "Clear Priority", "Help", NULL,
+ 	PANEL_NOTIFY_PROC, 		do_mark,
+ 	NULL);
+ 
+     (void) panel_create_item(panel, PANEL_CHOICE,
+ 	PANEL_ATTRIBUTE_LIST, 		choice_args,
+ 	PANEL_LABEL_IMAGE,
  	    panel_button_image(panel, "Printer", 7, mush_font),
  	PANEL_CHOICE_STRINGS, 		"Help", NULL,
  	PANEL_NOTIFY_PROC, 		do_lpr,
***************
*** 197,204 ****
  	PANEL_LABEL_IMAGE,
  	    panel_button_image(panel, "Sort", 4, mush_font),
  	PANEL_CHOICE_STRINGS,
! 	    "By Date", "By Author", "By Size", "By Subject",
! 	    "By Subject (ignore Re:)", "By Status", "Help", NULL,
  	PANEL_NOTIFY_PROC, 		do_sort,
  	NULL);
  
--- 207,215 ----
  	PANEL_LABEL_IMAGE,
  	    panel_button_image(panel, "Sort", 4, mush_font),
  	PANEL_CHOICE_STRINGS,
! 	    "By Status", "By Author", "By Size", "By Subject",
! 	    "By Subject (ignore Re:)", "By Date",
! 	    "By Priority", "Value of $sort", "Help", NULL,
  	PANEL_NOTIFY_PROC, 		do_sort,
  	NULL);
  
*** /tmp/,RCSt1009582	Sun Nov  4 20:02:50 1990
--- tool.c	Tue Oct 30 13:28:00 1990
***************
*** 19,25 ****
      main_panel,		/* the main panel dealing with generic items */
      hdr_panel;		/* panel which contains message header specific items */
  
! Textsw cprint_sw, mfprint_sw, wprint_sw;
  Frame compose_frame;
  
  static char **choice_args, **button_args;
--- 19,25 ----
      main_panel,		/* the main panel dealing with generic items */
      hdr_panel;		/* panel which contains message header specific items */
  
! Textsw mfprint_sw;
  Frame compose_frame;
  
  static char **choice_args, **button_args;
***************
*** 32,37 ****
--- 32,41 ----
  #include "mail.icon.2"
  };
  
+ short dat_compose_icon[] = {
+ #include "compose.icon"
+ };
+ 
  short dat_coffee_cup[] = {
      0x0200,0x0100,0x0600,0x0800,0x0600,0x0100,0xFFF8,0x800C,
      0x800A,0x4012,0x401C,0x2020,0x9048,0x7FF0,0x3FE0,0x0000
***************
*** 39,44 ****
--- 43,49 ----
  
  mpr_static(mail_icon_image1, 64, 64, 1, dat_mail_icon_1);
  mpr_static(mail_icon_image2, 64, 64, 1, dat_mail_icon_2);
+ mpr_static(compose_icon_image, 64, 64, 1, dat_compose_icon);
  
  mpr_static(coffee_cup,      16, 16, 1, dat_coffee_cup);
  
***************
*** 47,53 ****
  static Cursor coffee;
  
  /* text and font will be set in mail_status() */
! Icon mail_icon;
  
  static Notify_value scroll_hdr();
  
--- 52,58 ----
  static Cursor coffee;
  
  /* text and font will be set in mail_status() */
! Icon mail_icon, compose_icon;
  
  static Notify_value scroll_hdr();
  
***************
*** 158,164 ****
  void
  close_frame()
  {
!     window_set(compose_frame, WIN_SHOW, FALSE, NULL);
  }
  
  void
--- 163,173 ----
  void
  close_frame()
  {
!     if (do_set(set_options, "compose_icon")) {
! 	icon_set(compose_icon, ICON_IMAGE, &compose_icon_image, NULL);
! 	window_set(compose_frame, FRAME_CLOSED, TRUE, NULL);
!     } else
! 	window_set(compose_frame, WIN_SHOW, FALSE, NULL);
  }
  
  void
***************
*** 175,215 ****
      }
  #endif /* SUN_3_5 */
  
!     compose_frame = window_create(tool, FRAME,
! 	FRAME_LABEL,		"Compose Letter",
! 	FRAME_SHOW_LABEL,	TRUE,
! 	FRAME_NO_CONFIRM,	TRUE,
! 	FRAME_DONE_PROC,	close_frame,
! 	WIN_SHOW,		TRUE,
! 	NULL);
  
      panel = make_compose_panel(compose_frame, choice_args, button_args);
  
- #ifdef CPRINT_SW
-     /* text subwindow for wprint() */
-     cprint_sw = window_create(compose_frame, TEXTSW,
- 	WIN_HEIGHT,			l_height() * 4,
- 	WIN_BELOW,			panel,
- 	TEXTSW_READ_ONLY,		TRUE,
- 	TEXTSW_BLINK_CARET,		FALSE,
- 	TEXTSW_LINE_BREAK_ACTION,	TEXTSW_WRAP_AT_CHAR,
- 	NULL);
-     notify_interpose_event_func(cprint_sw, scroll_textwin, NOTIFY_SAFE);
-     (void) notify_interpose_event_func(cprint_sw,
- 	fkey_interposer, NOTIFY_SAFE);
- #else /* CPRINT_SW */
-     /* not enough fd's in SunOS 3.X for the extra textsw */
-     cprint_sw = (Textsw) 0;
- #endif /* CPRINT_SW */
- 
      /* text subwindow for composing messages */
      p = do_set(set_options, "msg_win");
      msg_sw = window_create(compose_frame, TEXTSW,
- #ifdef CPRINT_SW
- 	WIN_BELOW,			cprint_sw,
- #else /* CPRINT_SW */
  	WIN_BELOW,			panel,
- #endif /* CPRINT_SW */
  	WIN_HEIGHT,			l_height() * (p? atoi(p) : 24),
  	TEXTSW_READ_ONLY,		TRUE, /* set to false later */
  	TEXTSW_BLINK_CARET,		FALSE,
--- 184,214 ----
      }
  #endif /* SUN_3_5 */
  
!     if (do_set(set_options, "compose_icon"))
! 	compose_frame = window_create(NULL, FRAME,
! 	    FRAME_LABEL,		"Compose Letter",
! 	    FRAME_SHOW_LABEL,	TRUE,
! 	    FRAME_NO_CONFIRM,	TRUE,
! 	    FRAME_DONE_PROC,	close_frame,
! 	    FRAME_ICON,		compose_icon,
! 	    WIN_SHOW,		TRUE,
! 	    NULL);
!     else
! 	compose_frame = window_create(NULL, FRAME,
! 	    FRAME_LABEL,		"Compose Letter",
! 	    FRAME_SHOW_LABEL,	TRUE,
! 	    FRAME_NO_CONFIRM,	TRUE,
! 	    FRAME_DONE_PROC,	close_frame,
! 	    FRAME_ICON,		compose_icon,
! 	    WIN_SHOW,		TRUE,
! 	    NULL);
  
      panel = make_compose_panel(compose_frame, choice_args, button_args);
  
      /* text subwindow for composing messages */
      p = do_set(set_options, "msg_win");
      msg_sw = window_create(compose_frame, TEXTSW,
  	WIN_BELOW,			panel,
  	WIN_HEIGHT,			l_height() * (p? atoi(p) : 24),
  	TEXTSW_READ_ONLY,		TRUE, /* set to false later */
  	TEXTSW_BLINK_CARET,		FALSE,
***************
*** 240,248 ****
  void
  open_compose()
  {
!     if (compose_frame)
! 	window_set(compose_frame, WIN_SHOW, TRUE, NULL);
!     else
  	make_compose_frame();
  }
  
--- 239,250 ----
  void
  open_compose()
  {
!     if (compose_frame) {
! 	if (do_set(set_options, "compose_icon"))
! 	    window_set(compose_frame, FRAME_CLOSED, FALSE, NULL);
! 	else
! 	    window_set(compose_frame, WIN_SHOW, TRUE, NULL);
!     } else
  	make_compose_frame();
  }
  
***************
*** 426,431 ****
--- 428,440 ----
  	ICON_LABEL,		"",
  	ICON_LABEL_RECT,	&lrect,
  	0);
+     if (do_set(set_options, "compose_icon"))
+ 	compose_icon = icon_create(
+ 	    ICON_WIDTH,		64,
+ 	    ICON_HEIGHT,	64,
+ 	    ICON_IMAGE,		&compose_icon_image,
+ 	    ICON_LABEL,		"",
+ 	    0);
  }
  
  /* Initialise all the cursors used. */
***************
*** 541,546 ****
--- 550,565 ----
  		error("Error loading newmail icon file:\n%s",errbuf);
  	    else
  		pr_rop(&mail_icon_image2, 0,0,64,64, PIX_SRC, icon_mpr, 0, 0);
+ 	}
+     }
+     if ((icon_file = do_set(set_options, "compose_icon")) && *icon_file) {
+ 	isdir = 0;
+ 	icon_path = getpath(icon_file, &isdir);
+ 	if (isdir == 0) {
+ 	    if (!(icon_mpr = icon_load_mpr(icon_path, errbuf)))
+ 		error("Error loading newmail icon file:\n%s",errbuf);
+ 	    else
+ 		pr_rop(&compose_icon_image, 0,0,64,64, PIX_SRC, icon_mpr, 0, 0);
  	}
      }
  }