[comp.sources.bugs] Official Patch #3 for Mush 6.5

schaefer@ogccse.ogc.edu (Barton E. Schaefer) (05/19/89)

Before I launch into this, another note on the mailing list and so on.
Please do not send Dan or I requests to be put on the mailing list.  They
should go directly to
	mush-users-request@garp.mit.edu
I am still willing to send earlier patches to those who don't have them.
Dan will soon have a complete copy of the sources available at island;
requests for the whole shebang should go to
	island!argv@cad.berkeley.edu
You may have to wait a few days.

I apologize for the inconsistent way that changes are getting summarized in
the introductions to these patches.  Sometimes I have more time to make notes
as I put the patch together than other times ....

addrs.c:
    Defining UUCP will now result in some more extensive unscrambling of
    mangled RFC822 routes in From_ lines.  Fixed some minor confusion in
    bang_form() in the process.
commands.c:
    Autoprint doesn't if the delete command is being piped to another
    command.
curses.c:
    If you quit with 'q' and new mail comes in, you are asked if you want
    to quit anyway.  Answering "no" now works correctly.
dates.c:
    Handle date strings with 12-hour time plus am/pm indicator (thanks
    Mike Khaw).
execute.c:
    Trouble with the longjmp() from sigchldcatcher() resolved (thanks to
    Larry Virden and several others).  I sincerely hope this is the last
    I'm going to hear of this. :-(  I'm beginning to dream about getting
    mail reporting longjmp botches.
folders.c:
    The first "folder" command [issued from the init code in main()]
    now sets oldfolder correctly.
lock.c:
    Moved the setgid() call in in dot_lock() to the right place.
mail.c:
    Test of $autoedit was in the wrong place.
    With $edit_hdrs, $in_reply_to is no longer ignored (thanks to
    Bill Chung).
    Paging with `~p internal' is no longer impossible.
mush.1:
    Version and date in .TH and help explanations for toolmode fixed.
    Numerous typos caught by Larry Virden.
setopts.c:
    add_option() (that's the "set" command) no longer strips quotes from
    the value incorrectly.
viewopts.c:
    add_opts() could misuse "set", and called do_command() with the wrong
    argument type.  Toolmode users are still out of luck if they want to
    set an option to a value with double quotes in it.

---------------------------------------------------------------------------

Prereq: "5/12/89"
*** /tmp/,RCSt1015473	Thu May 18 21:09:02 1989
--- main.c	Thu May 18 14:03:40 1989
***************
*** 3,9 ****
  #include "mush.h"
  #include "options.h"
  
! #define PATCHDATE "5/12/89" /* Here because EVERYTHING depends on mush.h */
  
  #if defined(sun) && defined(M_DEBUG)
  cpu()
--- 3,9 ----
  #include "mush.h"
  #include "options.h"
  
! #define PATCHDATE "5/19/89" /* Here because EVERYTHING depends on mush.h */
  
  #if defined(sun) && defined(M_DEBUG)
  cpu()
*** /tmp/,RCSt1015473	Thu May 18 21:08:27 1989
--- README	Tue May 16 16:04:32 1989
***************
*** 16,27 ****
  A Mail Transport Agent (MTA) is the program which mush communicates with
  that actually -delivers- mail.
  
! Redistribution of this 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 mail and the
! startup message.  Future releases will extract the release version from
! the message headers of mush-originated messages to aid in implementing
! features and providing backwards compatibility with previous versions.
  
  With that out of the way...
  
--- 16,35 ----
  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
! mail and the startup message.  Future releases may extract the release
! version from the message headers of mush-originated messages to aid in
! implementing features and providing backwards compatibility with previous
! versions.  Modification of the source for personal use is permitted.
! Modifications sent to the authors are humbly accepted and it is their
! perogative to make the mods official.  Only the "official" sources may be
! redistributed and no sale of the code or any part thereof is permitted
! without written consent from the authors.  Further, no part of the code
! may be used in any other product, free or otherwise, without consent from
! the authors.
  
  With that out of the way...
  
*** /tmp/,RCSt1015473	Thu May 18 21:08:34 1989
--- addrs.c	Thu May 18 21:08:22 1989
***************
*** 178,183 ****
--- 178,188 ----
   * parses to
   * 	sys2!user%sys3@sys1
   * i.e., the route is simply dropped.
+  *
+  * If UUCP is defined, a little more work is done with @: routes.  The
+  * mangled address given above will unwind to
+  *	some.dumb.place!any.other.place!sys1!sys2!sys3!user
+  * thanks to intelligence in bang_form().
   */
  char *
  unscramble_addr(addr, naddr)
***************
*** 221,226 ****
--- 226,232 ----
  		return NULL;
  	    if (*(r + 1) == '\0')
  		return NULL;
+ #ifndef UUCP
  	    /*
  	     * Back up to the rightmost @-tagged domain
  	     *  (see note below about unwinding)
***************
*** 228,237 ****
  	    *r = '\0';
  	    i = rindex(i, '@');
  	    *r = ':';
  	}
  	/* Remember how much we've skipped, and copy the rest. */
  	at = i;
! 	(void) strcpy(t,i);
  	/* Strip from a trailing angle brace, if present. */
  	if (anglebrace) {
  	    if (r = any(t, "> \t")) {
--- 234,245 ----
  	    *r = '\0';
  	    i = rindex(i, '@');
  	    *r = ':';
+ #endif /* !UUCP */
  	}
  	/* Remember how much we've skipped, and copy the rest. */
  	at = i;
! 	(void) strncpy(t, i, sizeof t);
! 	t[sizeof t - 1] = 0;
  	/* Strip from a trailing angle brace, if present. */
  	if (anglebrace) {
  	    if (r = any(t, "> \t")) {
***************
*** 259,264 ****
--- 267,276 ----
       *   2) addr was a well-formed, <> enclosed RFC822 address
       */
      if (t[0] == '@') {
+ #ifdef UUCP
+ 	if (!bang_form(s, t))
+ 	    return NULL;
+ #else /* UUCP */
  	if (r = index(t, ':'))
  	    r++;
  	else
***************
*** 277,282 ****
--- 289,295 ----
  	    *(--r) = '\0';
  	    (void) strcat(s, t);
  	}
+ #endif /* UUCP */
      } else
  	(void) strcpy(s, t);
      /*
***************
*** 318,331 ****
       * Look backwards for the first `@'; this gives us the
       * primary domain of the RFC822 address
       */
!     if ((t = rindex(s, '@')) && t != s) {
! 	/* Copy the RFC822 domain as the UUCP head */
! 	d += Strcpy(d, t + 1);
! 	*d++ = '!';
! 	*t = '\0';
! 	r = bang_form(d, s);
! 	*t = '@';
!     } else if (*s == '@') {
  	/* An RFC-822 "@domain1,@domain2:" routing */
  	if (t = any(++s, ",:")) {
  	    char c = *t;
--- 331,337 ----
       * Look backwards for the first `@'; this gives us the
       * primary domain of the RFC822 address
       */
!     if (*s == '@') {
  	/* An RFC-822 "@domain1,@domain2:" routing */
  	if (t = any(++s, ",:")) {
  	    char c = *t;
***************
*** 336,341 ****
--- 342,354 ----
  	    r = bang_form(d, t);
  	} else
  	    r = NULL;
+     } else if ((t = rindex(s, '@')) && t != s) {
+ 	/* Copy the RFC822 domain as the UUCP head */
+ 	d += Strcpy(d, t + 1);
+ 	*d++ = '!';
+ 	*t = '\0';
+ 	r = bang_form(d, s);
+ 	*t = '@';
      } else if (t = index(s, '!')) {
  	/* A normal UUCP path */
  	*t = '\0';
*** /tmp/,RCSt1015473	Thu May 18 21:08:40 1989
--- commands.c	Tue May 16 15:35:20 1989
***************
*** 607,613 ****
  	ison(msg[current_msg].m_flags, SAVED)))
  	next_msg();
  
!     if (prnt_next && !undel && !iscurses)
  	if (old_msg != current_msg && isoff(msg[current_msg].m_flags, DELETE))
  	    display_msg(current_msg, (long)0);
  	else
--- 607,613 ----
  	ison(msg[current_msg].m_flags, SAVED)))
  	next_msg();
  
!     if (prnt_next && !undel && !iscurses && isoff(glob_flags, DO_PIPE))
  	if (old_msg != current_msg && isoff(msg[current_msg].m_flags, DELETE))
  	    display_msg(current_msg, (long)0);
  	else
*** /tmp/,RCSt1015473	Thu May 18 21:08:45 1989
--- curses.c	Sun May 14 17:28:41 1989
***************
*** 498,511 ****
  	    if (!vrfy_update(&redo))
  		if (c == C_UPDATE)
  		    break;
! 		else
! 		    turnoff(glob_flags, DO_UPDATE);
! 	    if (c == C_QUIT) {
! 		if (do_update)
! 		    putchar('\n');
! 		cleanup(0);
! 		redo = 1;
! 	    } else if (isoff(glob_flags, CNTD_CMD))
  		(void) cmd_line(sprintf(buf, "\\headers %d", current_msg+1),
  				msg_list);
  	}
--- 498,504 ----
  	    if (!vrfy_update(&redo))
  		if (c == C_UPDATE)
  		    break;
! 	    if (isoff(glob_flags, CNTD_CMD))
  		(void) cmd_line(sprintf(buf, "\\headers %d", current_msg+1),
  				msg_list);
  	}
*** /tmp/,RCSt1015473	Thu May 18 21:08:46 1989
--- dates.c	Thu May 18 20:54:02 1989
***************
*** 76,81 ****
--- 76,82 ----
       */
      static char month[64];
      char Wkday[4];
+     char a_or_p;
      int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
  
      skipspaces(0);
***************
*** 85,90 ****
--- 86,92 ----
       *   day_name month_name day_number time year_number
       *   day_name month_name day_number year_number time
       *   day_name day_number month_name year_number time
+      *   day_number month_name year_number 12_hour_time a_or_p
       *   day_number month_name year_number time
       *   day_number month_name year_number time-timezone (day)
       *                                       ^no colon separator
***************
*** 98,103 ****
--- 100,111 ----
       */
      if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5)
  	goto gotit;
+     if (sscanf(p, "%d %s %d %d:%d:%*d %cm",
+ 				&Day,month,&Year,&Hours,&Mins,&a_or_p) == 6) {
+ 	if (a_or_p == 'p')
+ 	    Hours += 12;
+ 	goto gotit;
+     }
      if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  	goto gotit;
      if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5)
*** /tmp/,RCSt1015473	Thu May 18 21:08:48 1989
--- execute.c	Thu May 18 08:27:16 1989
***************
*** 57,81 ****
      turnon(glob_flags, IGN_SIGS);
  
      echo_on();
!     if ((exec_pid = vfork()) == 0) {
! 	(void) signal(SIGINT, SIG_DFL);
! 	(void) signal(SIGQUIT, SIG_DFL);
! 	(void) signal(SIGPIPE, SIG_DFL);
! 	(void) closefileds(3);	/* close all descriptors above 2 */
! 	execvp(*argv, argv);
! 	if (errno == ENOENT)
! 	    print("%s: command not found.\n", *argv);
! 	else
! 	    error(*argv);
! 	_exit(-1);
!     }
!     /* Parent's got to do something; sigchldcatcher may also be waiting.
!      * This loop will usually get broken by the longjmp() (except tool),
!      * but in certain circumstances signchldcatcher isn't yet active.
!      */
!     if (!setjmp(execjbuf))
  	while ((pid = wait(&status)) != -1 && pid != exec_pid)
  	    Debug("The exec loop caught a signal? (pid = %d)\n", pid);
      /* reset our ttymodes */
      echo_off();
      (void) signal(SIGINT, oldint);
--- 57,82 ----
      turnon(glob_flags, IGN_SIGS);
  
      echo_on();
!     if (!setjmp(execjbuf)) {
! 	if ((exec_pid = vfork()) == 0) {
! 	    (void) signal(SIGINT, SIG_DFL);
! 	    (void) signal(SIGQUIT, SIG_DFL);
! 	    (void) signal(SIGPIPE, SIG_DFL);
! 	    (void) closefileds(3);	/* close all descriptors above 2 */
! 	    execvp(*argv, argv);
! 	    if (errno == ENOENT)
! 		print("%s: command not found.\n", *argv);
! 	    else
! 		error(*argv);
! 	    _exit(-1);
! 	}
! 	/* Parent's got to do something; sigchldcatcher may also be waiting.
! 	 * This loop will usually get broken by the longjmp() (except tool),
! 	 * but in certain circumstances sigchldcatcher isn't yet active.
! 	 */
  	while ((pid = wait(&status)) != -1 && pid != exec_pid)
  	    Debug("The exec loop caught a signal? (pid = %d)\n", pid);
+     }
      /* reset our ttymodes */
      echo_off();
      (void) signal(SIGINT, oldint);
***************
*** 117,124 ****
  #endif /* SYSV */
  #endif /* BSD */
  #ifndef SUNTOOL
!     if (pid == exec_pid)
  	longjmp(execjbuf, 1);
  } /* { */
  #else /* SUNTOOL */
      /* The following SHOULDN'T be necessary, but it is!!! ttysw_fork()
--- 118,127 ----
  #endif /* SYSV */
  #endif /* BSD */
  #ifndef SUNTOOL
!     if (pid == exec_pid && pid > 0) {
! 	exec_pid = 0;
  	longjmp(execjbuf, 1);
+     }
  } /* { */
  #else /* SUNTOOL */
      /* The following SHOULDN'T be necessary, but it is!!! ttysw_fork()
*** /tmp/,RCSt1015473	Thu May 18 21:08:50 1989
--- folders.c	Mon May 15 09:06:40 1989
***************
*** 111,117 ****
  	/* an error occured updating the folder */
  	return -1;
      }
!     if (strcmp(mailfile, buf)) {
  	if (!updating)
  	    (void) strcpy(oldfolder, *oldfolder? mailfile : buf);
  	strdup(mailfile, buf);
--- 111,118 ----
  	/* an error occured updating the folder */
  	return -1;
      }
!     /* Assure that both oldfolder and mailfile are full paths */
!     if (strcmp(mailfile, buf) || !*oldfolder) {
  	if (!updating)
  	    (void) strcpy(oldfolder, *oldfolder? mailfile : buf);
  	strdup(mailfile, buf);
*** /tmp/,RCSt1015473	Thu May 18 21:08:54 1989
--- lock.c	Sun May 14 17:38:25 1989
***************
*** 27,37 ****
      int lockfd, cnt = 0;
      SIGRET (*oldint)(), (*oldquit)();
  
- #ifdef BSD
-     setregid(rgid, sgid);
- #else /* BSD */
-     setgid(sgid);
- #endif /* BSD */
  #ifdef SYSV
      /* Only the spoolfile needs to be dot_locked -- other files are
       * handled by lock_file, below.  To avoid collisions with 14-char
--- 27,32 ----
***************
*** 40,45 ****
--- 35,45 ----
      if (strcmp(spoolfile, filename) != 0)
  	return 0;
  #endif
+ #ifdef BSD
+     setregid(rgid, sgid);
+ #else /* BSD */
+     setgid(sgid);
+ #endif /* BSD */
  #ifdef M_XENIX
      (void) sprintf(buf, "/tmp/%.10s.mlk", login);
  #else /* M_XENIX */
*** /tmp/,RCSt1015473	Thu May 18 21:08:58 1989
--- mail.c	Thu May 18 15:12:28 1989
***************
*** 60,73 ****
      turnon(flgs, NO_IGNORE); /* if we include a message, include all hdrs */
      clear_msg_list(inc_list);
  
-     if (do_set(set_options, "autoedit"))
- 	turnon(flgs, EDIT);
- #ifdef VERBOSE_ARG
-     if (do_set(set_options, "verbose"))
- 	turnon(flgs, VERBOSE);
- #endif /* VERBOSE_ARG */
-     if (do_set(set_options, "autosign"))
- 	turnon(flgs, SIGN);
      /* If piped to mail, include the messages piped */
      if (ison(glob_flags, IS_PIPE) ||
  	(lower(firstchar) == 'r' && do_set(set_options, "autoinclude"))) {
--- 60,65 ----
***************
*** 164,169 ****
--- 156,169 ----
  		    return -1;
  	    }
      }
+     if (isoff(flgs, FORWARD) && do_set(set_options, "autoedit"))
+ 	turnon(flgs, EDIT);
+ #ifdef VERBOSE_ARG
+     if (do_set(set_options, "verbose"))
+ 	turnon(flgs, VERBOSE);
+ #endif /* VERBOSE_ARG */
+     if (do_set(set_options, "autosign"))
+ 	turnon(flgs, SIGN);
      *in_reply_to = *To = *Subject = *Cc = *Bcc = 0;
      if (lower(firstchar) == 'r') {
  	char *old_fmt = hdr_format, *pcc = NULL;
***************
*** 646,652 ****
      skipspaces(0);
      switch (line[1]) {
  	case 'v' : case 'p': case 'e' : case '|' : {
! 	    if (!*p || *p == 'i' && !p[1])
  		switch (line[1]) {
  		    case 'p' :
  			if (!*p && !(p = do_set(set_options, "pager")))
--- 646,652 ----
      skipspaces(0);
      switch (line[1]) {
  	case 'v' : case 'p': case 'e' : case '|' : {
! 	    if (!*p || *p == 'i')
  		switch (line[1]) {
  		    case 'p' :
  			if (!*p && !(p = do_set(set_options, "pager")))
***************
*** 654,660 ****
  			if (!*p || !strcmp(p, "internal"))
  			    p = NULL;
  		    when 'v' :
! 			if (p = do_set(set_options, "visual"))
  			    break;
  			/* else fall through */
  		    default :
--- 654,660 ----
  			if (!*p || !strcmp(p, "internal"))
  			    p = NULL;
  		    when 'v' :
! 			if (*p && p[1] || (p = do_set(set_options, "visual")))
  			    break;
  			/* else fall through */
  		    default :
***************
*** 1569,1576 ****
  		for (i = 0; i < size; i++) {
  		    p = opts->value;
  		    skipspaces(0);
! 		    if (*p)
! 			fprintf(files[i], "%s %s\n", opts->option, p);
  		}
  	}
  
--- 1569,1575 ----
  		for (i = 0; i < size; i++) {
  		    p = opts->value;
  		    skipspaces(0);
! 		    fprintf(files[i], "%s %s\n", opts->option, p);
  		}
  	}
  
***************
*** 1598,1615 ****
  	/* if not for the editor and the user doesn't use edit_hdrs,
  	 * add his own_hdrs by hand here. (also take care of in-reply-to)
  	 */
! 	if (isoff(flags, EDIT_HDRS) && own_hdrs &&
! 	    !do_set(set_options, "no_hdrs")) {
! 	    struct options *opts;
! 	    for (opts = own_hdrs; opts; opts = opts->next)
! 		for (i = 0; i < size; i++) {
! 		    p = opts->value;
! 		    skipspaces(0);
! 		    /* user can't set his own from: and date: headers */
! 		    if (*p && lcase_strncmp(opts->option, "from:", 5) &&
! 			lcase_strncmp(opts->option, "date:", 5))
! 			fprintf(files[i], "%s %s\n", opts->option, p);
! 		}
  	    if (*in_reply_to)
  		for (i = 0; i < size; i++)
  		    fprintf(files[i], "In-Reply-To: %s\n", in_reply_to);
--- 1597,1615 ----
  	/* if not for the editor and the user doesn't use edit_hdrs,
  	 * add his own_hdrs by hand here. (also take care of in-reply-to)
  	 */
! 	if (isoff(flags, EDIT_HDRS) && !do_set(set_options, "no_hdrs")) {
! 	    if (own_hdrs) {
! 		struct options *opts;
! 		for (opts = own_hdrs; opts; opts = opts->next)
! 		    for (i = 0; i < size; i++) {
! 			p = opts->value;
! 			skipspaces(0);
! 			/* user can't set his own from: and date: headers */
! 			if (*p && lcase_strncmp(opts->option, "from:", 5) &&
! 			    lcase_strncmp(opts->option, "date:", 5))
! 			    fprintf(files[i], "%s %s\n", opts->option, p);
! 		    }
! 	    }
  	    if (*in_reply_to)
  		for (i = 0; i < size; i++)
  		    fprintf(files[i], "In-Reply-To: %s\n", in_reply_to);
*** /tmp/,RCSt1015473	Thu May 18 21:09:11 1989
--- mush.1	Thu May 18 14:03:20 1989
***************
*** 8,14 ****
  .if n .ds - --
  .if t .ds - \(em
  .nh
! .TH MUSH 1 "Oct 24, 1988" "Version 6.4"
  .UC 4
  .SH NAME
  The Mail User's Shell \- Shell for electronic mail.
--- 8,14 ----
  .if n .ds - --
  .if t .ds - \(em
  .nh
! .TH MUSH 1 "May 12, 1989" "Version 6.5"
  .UC 4
  .SH NAME
  The Mail User's Shell \- Shell for electronic mail.
***************
*** 375,381 ****
  .PP
  In text mode, most help is gotten by typing \-? as an argument to a
  command.
! Amost every command has the \-? option.
  When this option is specified, most commands will attempt to read from
  a help file a brief explanation of the functionality of the command.
  If necessary, a pointer to other sources of information will
--- 375,381 ----
  .PP
  In text mode, most help is gotten by typing \-? as an argument to a
  command.
! Almost every command has the \-? option.
  When this option is specified, most commands will attempt to read from
  a help file a brief explanation of the functionality of the command.
  If necessary, a pointer to other sources of information will
***************
*** 391,398 ****
  RIGHT mouse button (the \*Qmenu button\*U) and a number of items will appear
  in a menu.
  The last command in the menu list will be one labelled \*Qhelp\*U.
! Selecting this menu item will display a \*Qhelp box\*U in the center of the
! console and wait for input to remove the box.
  .PP
  .BR "Sorting mail" .
  .PP
--- 391,397 ----
  RIGHT mouse button (the \*Qmenu button\*U) and a number of items will appear
  in a menu.
  The last command in the menu list will be one labelled \*Qhelp\*U.
! Selecting this menu item will display help information in the message window.
  .PP
  .BR "Sorting mail" .
  .PP
***************
*** 1215,1221 ****
  command in your initialization file is a no-no, so you can alias your
  login shell mail command to include the -C option.
  If you use the Bourne Shell, you're going to have to type it out all the time.
! Mush will to attempt to know not to run a shell if you're just sending mail to
  someone, so the
  .I csh
  command line sequences:
--- 1214,1220 ----
  command in your initialization file is a no-no, so you can alias your
  login shell mail command to include the -C option.
  If you use the Bourne Shell, you're going to have to type it out all the time.
! Mush will attempt to know not to run a shell if you're just sending mail to
  someone, so the
  .I csh
  command line sequences:
***************
*** 1226,1232 ****
  % mail fred
  .sp
  will mail to fred and not enter the shell.
! However, if you just said, "mail"
  with no arguments, you'll enter the shell in curses mode if you have mail.
  If you don't, you'll be told so, and the shell will not start.
  If you want to enter curses mode even if
--- 1225,1231 ----
  % mail fred
  .sp
  will mail to fred and not enter the shell.
! However, if you just said \*Qmail\*U
  with no arguments, you'll enter the shell in curses mode if you have mail.
  If you don't, you'll be told so, and the shell will not start.
  If you want to enter curses mode even if
***************
*** 1548,1554 ****
  At the end of each list of menu entries for panel items is an item
  labelled \*Qhelp\*U.
  When this item is chosen, help for that command
! is displayed in the center of the console.
  .PP
  When composing letters, the interface is the same for the tool mode,
  the line mode and the curses mode.
--- 1547,1553 ----
  At the end of each list of menu entries for panel items is an item
  labelled \*Qhelp\*U.
  When this item is chosen, help for that command
! is displayed in the message window.
  .PP
  When composing letters, the interface is the same for the tool mode,
  the line mode and the curses mode.
***************
*** 2109,2114 ****
--- 2108,2116 ----
  ignore Received Date Message-Id
  .sp
  will ignore the three specified fields.
+ Additional
+ .B ignore
+ commands are cumulative.
  The command
  .B unignore
  is used to reverse the effects of
***************
*** 2590,2596 ****
  .RB ( R )
  command, only the original author's address can be obtained from
  the message headers.
! There is no way determine the best path to the
  other recipients of the message from message headers aside from taking
  their addresses directly from the \*QTo:\*U and \*QCc:\*U lines.
  .sp
--- 2592,2598 ----
  .RB ( R )
  command, only the original author's address can be obtained from
  the message headers.
! There is no way to determine the best path to the
  other recipients of the message from message headers aside from taking
  their addresses directly from the \*QTo:\*U and \*QCc:\*U lines.
  .sp
***************
*** 2632,2638 ****
  that of the author of the message being saved.  If more than one message
  is being saved, the subject or author name used is that of the smallest
  message number (since message lists have no order of precedence).  With
! these two options, a directly name may be given to specify a directory
  other than the current directory.
  .sp
  If the file exists and is writable, the specified command
--- 2634,2640 ----
  that of the author of the message being saved.  If more than one message
  is being saved, the subject or author name used is that of the smallest
  message number (since message lists have no order of precedence).  With
! these two options, a directory name may be given to specify a directory
  other than the current directory.
  .sp
  If the file exists and is writable, the specified command
***************
*** 2691,2700 ****
  .TP
  .BR unset " variable"
  .rs
! With no arguments, prints all variable values.
! Otherwise, sets option.
! Arguments are of the form \*Qoption=value\*U (whitespace is allowed).
! Boolean expressions need not have \*Q=value\*U associated in the command.
  .sp
  The special command
  .sp
--- 2693,2708 ----
  .TP
  .BR unset " variable"
  .rs
! With no arguments,
! .B set
! prints all variable values.
! Otherwise, it sets the named
! .IR variable .
! Arguments are of the form \*Qvariable=value\*U (whitespace is allowed).
! Boolean options such as
! .I autoedit
! need not have \*Q=value\*U associated in the command (see the VARIABLES
! section for details).
  .sp
  The special command
  .sp
***************
*** 2720,2733 ****
  .ti +2
  pick \-s Status Reports | set reports
  .sp
! The variable, reports, now contains a message list which can be used
! as the message list argument to any commands which accepts one.
  .sp
  .ti +2
  mail \-i $reports boss
  .sp
! This command will mail to \*Qboss\*U and include all the messages held
! in the \fIreports\fP variable.
  .TP
  .BR sh " [command]"
  Invokes an interactive version of the shell.
--- 2728,2743 ----
  .ti +2
  pick \-s Status Reports | set reports
  .sp
! The variable
! .I reports
! now contains a message list which can be used
! as the message list argument to any command which accepts a list.
  .sp
  .ti +2
  mail \-i $reports boss
  .sp
! This command will mail to \*Qboss\*U and include the text of all the
! messages held in the \fIreports\fP variable.
  .TP
  .BR sh " [command]"
  Invokes an interactive version of the shell.
***************
*** 2734,2740 ****
  The shell spawned is described by the variable
  .BR shell .
  If the optional argument
! .B command
  is given, then that command is executed under the Bourne Shell.
  If the special character `&' is at the end of any shell command,
  then the command will be executed in background.
--- 2744,2750 ----
  The shell spawned is described by the variable
  .BR shell .
  If the optional argument
! .I command
  is given, then that command is executed under the Bourne Shell.
  If the special character `&' is at the end of any shell command,
  then the command will be executed in background.
*** /tmp/,RCSt1015473	Thu May 18 21:09:28 1989
--- setopts.c	Mon May 15 15:00:09 1989
***************
*** 17,39 ****
  	return 1;
      /* check for one of three forms:
       * option=value    option = value  option= value
-      * value can be in quotes to preserve whitespace
       */
      if (*++argv && !strcmp(*argv, "=")) {
  	if (value = *++argv) /* example: "set foo = " */
  	    ++argv;
      } else if (value = index(option, '=')) {
! 	/* option=value  strip into option="option" value="value"; (quotes?) */
  	register char c, *p2;
! 	*value = 0; /* option is now a null terminated `option' */
! 	if ((c = *++value) == '"' || c == '\'') {
! 	    *value++ = 0;
! 	    if (!(p2 = index(value, c))) {
! 		print("No matching %c for %s.\n", c, option);
! 		return 0;
! 	    } else
! 		*p2 = 0;
! 	} else if (!c) {  /* example: "set crt=" */
  	    if (!*argv) {
  		print("No value for %s.\n", option);
  		return 0;
--- 17,31 ----
  	return 1;
      /* check for one of three forms:
       * option=value    option = value  option= value
       */
      if (*++argv && !strcmp(*argv, "=")) {
  	if (value = *++argv) /* example: "set foo = " */
  	    ++argv;
      } else if (value = index(option, '=')) {
! 	/* option=value  strip into option="option" value="value" */
  	register char c, *p2;
! 	*value++ = 0; /* option is now a null terminated `option' */
! 	if (!*value) {  /* example: "set crt=" */
  	    if (!*argv) {
  		print("No value for %s.\n", option);
  		return 0;
*** /tmp/,RCSt1015473	Thu May 18 21:09:30 1989
--- sort.c	Thu May 18 12:22:34 1989
***************
*** 181,197 ****
      }
      p1 = subject_to(msg1 - msg, buf1);
      p2 = subject_to(msg2 - msg, buf2);
-     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg, p1, msg2-msg, p2);
      if (p1) {
  	p1 += 4;
  	while (isspace(*p1))
  	    p1++;
!     }
      if (p2) {
  	p2 += 4;
  	while (isspace(*p2))
  	    p2++;
!     }
      if (ignore_case)
  	return lcase_strncmp(p1, p2, -1) * order;
      return strcmp(p1, p2) * order;
--- 181,199 ----
      }
      p1 = subject_to(msg1 - msg, buf1);
      p2 = subject_to(msg2 - msg, buf2);
      if (p1) {
  	p1 += 4;
  	while (isspace(*p1))
  	    p1++;
!     } else
! 	p1 = buf1; /* subject_to() makes it an empty string */
      if (p2) {
  	p2 += 4;
  	while (isspace(*p2))
  	    p2++;
!     } else
! 	p2 = buf2; /* subject_to() makes it an empty string */
!     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg, p1, msg2-msg, p2);
      if (ignore_case)
  	return lcase_strncmp(p1, p2, -1) * order;
      return strcmp(p1, p2) * order;
*** /tmp/,RCSt1015473	Thu May 18 21:09:33 1989
--- viewopts.c	Wed May 17 14:00:35 1989
***************
*** 276,284 ****
      int argc;
      u_long save_bang = ison(glob_flags, IGN_BANG);
  
!     (void) sprintf(buf, "set %s=\"%s\"", viewopts[start_cnt+line].v_opt, p);
      turnon(glob_flags, IGN_BANG);
!     if (argv = make_command(buf, DUBL_NULL, &argc))
  	(void) do_command(argc, argv, msg_list);
      if (!save_bang)
  	turnoff(glob_flags, IGN_BANG);
--- 276,284 ----
      int argc;
      u_long save_bang = ison(glob_flags, IGN_BANG);
  
!     (void) sprintf(buf, "\\set %s=\"%s\"", viewopts[start_cnt+line].v_opt, p);
      turnon(glob_flags, IGN_BANG);
!     if (argv = make_command(buf, TRPL_NULL, &argc))
  	(void) do_command(argc, argv, msg_list);
      if (!save_bang)
  	turnoff(glob_flags, IGN_BANG);
-- 
Bart Schaefer       "And if you believe that, you'll believe anything."
							-- DangerMouse
CSNET / Internet                schaefer@cse.ogc.edu
UUCP                            ...{sequent,tektronix,verdix}!ogccse!schaefer

argv%eureka@Sun.COM (Dan Heller) (05/20/89)

UUCP requests for sources should go to dheller@cory.berkeley.edu --
PLEASE don't mail them to island!argv because I will not send them
from there.  If you do, I have to forward your request to cory and
deal with it then.

dan <island!argv@cad.berkeley.edu>