[comp.sources.unix] v15i003: Upgrade kit for Mush release 6.2

rsalz@bbn.com (Rich Salz) (05/24/88)

Submitted-by: dheller@cory.Berkeley.EDU (Dan Heller)
Posting-number: Volume 15, Issue 3
Archive-name: mush6.2.pch

[  This adds some date sorting, and fixes IO flushing on some systems,
   as well as other stuff, no doubt.  -r$ ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README-6.2 Diffs-6.2
# Wrapped by rsalz@fig.bbn.com on Mon May 23 18:41:06 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README-6.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README-6.2'\"
else
echo shar: Extracting \"'README-6.2'\" \(3118 characters\)
sed "s/^X//" >'README-6.2' <<'END_OF_FILE'
main.c --
X    New command line argument "-F file".  The file is sourced after
X    the folder has been read in.  There have been requests to allow
X    commands which manipulate messages to be in the .mushrc, but since
X    that can't be done without being able to expand possible shell
X    arguments such as "+folder", an additional source file can be
X    executed before IO to the user happens by specifying this filename.
X    If the flag given is "-F!", then the mush will exit once it is
X    finished with the commands in the file.
X
main.c, mail.c, viewopts.c --
X    A new variable called "tmpdir" has been added.  This path describes
X    the location for all temporary files that mush creates.  If not set,
X    mush will use the user's home directory.  If neither is accessible
X    and writeable, then /tmp (defined in config.h) is used.
X
misc.c --
X    when invoking a pager, sometimes cbreak was not getting set.  It
X    wasn't easily reproducable because of a race condition set by a
X    system call.
X
pick.c --
X    There is a new option to the "pick" command called -ago.  Now you
X    can pick messages relative to today's date.
X    pick -ago 2 weeks
X    will find all messages two weeks old.  The + and - modifiers will
X    extend time searches:
X
X    pick -ago +2 days
X    will find all messages from two days ago to current.
X
X    pick -ago -1w
X
X    will find all messages fromk one week ago and back.  You can specify
X    days, weeks, months and years and the xyntax is extremely simple.
X
X    pick -ago 2 weeks 1 day
X    pick -ago 1d 2w
X    pick -ago 1 DAY, 2 WEEKS
X    pick -a 1d2w
X
X    are all equivalent.  Note that months map to 30.5 days so March may
X    be confusing.
X
X    The -d option to pick used to specify that dates preceded by '-' meant
X    "on or before" and if there was no '-', then it defaulted to "on or after."
X    It was difficult to find messages on a specific date only.  So now, the
X    change is that "on or after" is specified by preceding a '+' before the
X    date.  thus,
X
X    pick -d 5/2
X
X    *used* to find messages dated on or after May 2.  Now, it only finds
X    messages on May 2 only.  To do messages on or after May 2, specify:
X
X    pick -d +5/2
X
help.c --
X    help now sends output thru the internal pager in case the
X    help message is very long.  pick -? may be the only problem, but now
X    it's set up to handle arbitrarily long help messages.
X
mail.c --
X    New mail checks happen while editing a message.  If you are sending
X    mail to someone and new mail comes in (and you're not in your editor),
X    then it will be incorporated immediately.
X
X    You can specify the internal pager use "~p internal" while editing
X    a message.
X
X    Autosigning now precedes the singature file with "\n-- \n" for
X    compaitibility with news and other programs.
X
execute.c --
X    A "synxtax" type error would cause xenix systems to incorrectly
X    evaluate the wait() loop.  The change:
X	while ((pid = wait(&status) != -1) && ...
X    has been changed to:
X	while ((pid = wait(&status)) != -1 && ...
X
mush.1 --
X    The man page has been updated as well to reflect the above changes.
END_OF_FILE
if test 3118 -ne `wc -c <'README-6.2'`; then
    echo shar: \"'README-6.2'\" unpacked with wrong size!
fi
# end of 'README-6.2'
fi
if test -f 'Diffs-6.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Diffs-6.2'\"
else
echo shar: Extracting \"'Diffs-6.2'\" \(38618 characters\)
sed "s/^X//" >'Diffs-6.2' <<'END_OF_FILE'
X*** OLD/cmd_help	Wed Mar  2 12:05:28 1988
X--- cmd_help	Wed May 11 14:06:12 1988
X***************
X*** 174,193 ****
X  %%
X  
X  %pick%
X! use: pick [-r msg_list] [-d [-][date] ] [-s|f|t]] [-x] [-i] [-h hdr] [<pat>]
X  Search for patterns within messages. Entire messages are searched
X  for <pattern> unless -s, -f, -t, or -h is specified.
X! Only one of -s, -f, -t, -d and -h can be specified at once.
X  -r msg_list  restrict the range of messages search to msg_list
X- -d: print message headers on or after [`-' before] `date' (no patterns).
X  -h hdr   requires a header to be searched for.  Pattern searched in that hdr.
X!      `date' is of the form: month/date/year
X        Omitted fields default to today's values. Examples:
X!       pick -d 4/20     msgs on or after Apr 20, this year
X        pick -d -/2/85   on or before the 2nd, this month, 1985
X!       pick -d /        finds today's messages only.
X      At least one `/' char must be used in date.
X      There is no strong date checking; 2/30 would be considered valid
X  -s search for pattern in the "subject" headers only.
X  -f search for pattern in the "from" field (author) only.
X  -t search for pattern in the "to" field.
X--- 174,196 ----
X  %%
X  
X  %pick%
X! use: pick [-r msg_list] [-d [-][date] ] [-s|f|t]] [-x] [-i]
X! 	  [-h hdr] [-ago [n days] [n weeks] [n months] ] [<pat>]
X  Search for patterns within messages. Entire messages are searched
X  for <pattern> unless -s, -f, -t, or -h is specified.
X! Only one of -s, -f, -t, -d, -ago and -h can be specified at once.
X  -r msg_list  restrict the range of messages search to msg_list
X  -h hdr   requires a header to be searched for.  Pattern searched in that hdr.
X! -d: print headers on or [+ after] [- before] `date' (no pattern search).
X!      `date' is of the form: [+-] [month]/[date/year]
X        Omitted fields default to today's values. Examples:
X!       pick -d 4/20     messages on Apr 20, this year
X        pick -d -/2/85   on or before the 2nd, this month, 1985
X!       pick -d +5/4     on or after May 4, this year
X!       pick -d /        finds today's messages only
X      At least one `/' char must be used in date.
X      There is no strong date checking; 2/30 would be considered valid
X+ -ago search for messages relative to the current date (see manual).
X  -s search for pattern in the "subject" headers only.
X  -f search for pattern in the "from" field (author) only.
X  -t search for pattern in the "to" field.
X*** OLD/commands.c	Thu May 12 13:51:57 1988
X--- commands.c	Wed May 11 21:47:30 1988
X***************
X*** 752,758 ****
X  {
X      char **e;
X      for (e = environ; *e; e++)
X! 	if (argc < 1 || !strncmp(*e, argv[1]))
X  	    wprint("%s\n", *e);
X      return -1;
X  }
X--- 752,758 ----
X  {
X      char **e;
X      for (e = environ; *e; e++)
X! 	if (argc < 2 || !strncmp(*e, argv[1]))
X  	    wprint("%s\n", *e);
X      return -1;
X  }
X*** OLD/curs_io.c	Mon Mar  7 14:57:23 1988
X--- curs_io.c	Wed May 11 20:38:32 1988
X***************
X*** 135,140 ****
X--- 135,141 ----
X  		Addch(c);
X  	}
X      }
X+     fflush(stdout); /* for sys-v folks */
X      if (c == CTRL(D) || c == EOF || ison(glob_flags, WAS_INTR)) {
X  	if (feof(stdin))
X  	    clearerr(stdin);
X*** OLD/curses.c	Thu May 12 13:52:00 1988
X--- curses.c	Wed May 11 10:39:41 1988
X***************
X*** 718,724 ****
X      int n;
X  
X      for (n = 0; n < COLS; n++)
X! 	if ((buf = mvinch(curline, n) & A_CHARTEXT) == '\0')
X  	    break;
X      buf[n] = '\0';
X  #endif /* A_CHARTEXT */
X--- 718,724 ----
X      int n;
X  
X      for (n = 0; n < COLS; n++)
X! 	if ((buf = mvinch(line, n) & A_CHARTEXT) == '\0')
X  	    break;
X      buf[n] = '\0';
X  #endif /* A_CHARTEXT */
X*** OLD/execute.c	Sat Apr  2 16:14:19 1988
X--- execute.c	Wed May 11 16:17:13 1988
X***************
X*** 68,74 ****
X       * if other forks die (sendmail), then this wait will catch them,
X       * This loop will really get -1, cuz sigchldcatcher will catch all else.
X       */
X!     while ((pid = wait(&status) != -1) && pid != exec_pid)
X  	Debug("The exec loop caught a signal? (pid = %d)\n", pid);
X      /* reset our ttymodes */
X      echo_off();
X--- 68,74 ----
X       * if other forks die (sendmail), then this wait will catch them,
X       * This loop will really get -1, cuz sigchldcatcher will catch all else.
X       */
X!     while ((pid = wait(&status)) != -1 && pid != exec_pid)
X  	Debug("The exec loop caught a signal? (pid = %d)\n", pid);
X      /* reset our ttymodes */
X      echo_off();
X*** OLD/help.c	Mon Dec  7 18:37:47 1987
X--- help.c	Wed May 11 16:08:07 1988
X***************
X*** 72,77 ****
X--- 72,79 ----
X  #include <sys/types.h>
X  #define wprint printf
X  #define print  printf
X+ #define TRUE   1
X+ #define FALSE  0
X  
X  #endif /* SUNTOOL */
X  
X***************
X*** 311,320 ****
X      if (height == MAXLINES - 1)
X  	print("Help message is too long!\n");
X  
X      for (n = 0; n < height; n++) {
X  	(void) no_newln(args[n]);
X! 	wprint("%s\n", args[n]);
X      }
X  
X      return 0;
X  }
X--- 313,326 ----
X      if (height == MAXLINES - 1)
X  	print("Help message is too long!\n");
X  
X+     do_pager(NULL, TRUE);
X      for (n = 0; n < height; n++) {
X  	(void) no_newln(args[n]);
X! 	(void) do_pager(args[n], FALSE);
X! 	if (do_pager("\n", FALSE) == EOF)
X! 	    break;
X      }
X+     do_pager(NULL, FALSE);
X  
X      return 0;
X  }
X*** OLD/loop.c	Thu May 12 13:52:05 1988
X--- loop.c	Wed May 11 21:31:42 1988
X***************
X*** 106,112 ****
X  	if (Getstr(line, sizeof(line), 0) > -1)
X  	    p = line;
X  	else {
X! 	    if (p = do_set(set_options, "ignoreeof")) {
X  		if (!*p)
X  		    continue;
X  		else
X--- 106,112 ----
X  	if (Getstr(line, sizeof(line), 0) > -1)
X  	    p = line;
X  	else {
X! 	    if (isatty(0) && (p = do_set(set_options, "ignoreeof"))) {
X  		if (!*p)
X  		    continue;
X  		else
X*** OLD/mail.c	Sat May 21 10:53:59 1988
X--- mail.c	Sat May 21 10:56:08 1988
X***************
X*** 10,17 ****
X   *    mail_someone()    called from do_mail() or from the shell.
X   *    add_to_letter()	adds the next line to letter --determine ~ escapes.
X   *    finish_up_letter()  prompts for Cc:, verifies user really wants to send
X!  *    send_it()		invokes mailer, sends to record file, adds signature,
X!  *			fortune, expands aliases, adds own_hdrs.
X   *    rm_edfile()	signals are directed here. remove letter, longjmp
X   *
X   * The flow of control in this file is NOT obvious to allow for both text
X--- 10,18 ----
X   *    mail_someone()    called from do_mail() or from the shell.
X   *    add_to_letter()	adds the next line to letter --determine ~ escapes.
X   *    finish_up_letter()  prompts for Cc:, verifies user really wants to send
X!  *    send_it()		invokes mailer, sends to record file, expands aliases,
X!  *			adds own_hdrs.
X!  *    sign_letter()	adds signature and fortunes.
X   *    rm_edfile()	signals are directed here. remove letter, longjmp
X   *
X   * The flow of control in this file is NOT obvious to allow for both text
X***************
X*** 283,296 ****
X  start_file(list)
X  char *list;
X  {
X!     register char  *home;
X      register int   i;
X      char  	   line[MAXPATHLEN];
X  
X!     if (!(home = do_set(set_options, "home")) || !*home)
X  alted:
X! 	home = ALTERNATE_HOME;
X!     (void) mktemp(sprintf(line, "%s/%s", home, EDFILE));
X      strdup(edfile, line);
X      {
X  	int omask = umask(077);
X--- 284,298 ----
X  start_file(list)
X  char *list;
X  {
X!     register char  *dir;
X      register int   i;
X      char  	   line[MAXPATHLEN];
X  
X!     if (!(dir = do_set(set_options, "tmpdir")) &&
X! 	!(dir = do_set(set_options, "home")))
X  alted:
X! 	dir = ALTERNATE_HOME;
X!     (void) mktemp(sprintf(line, "%s/%s", dir, EDFILE));
X      strdup(edfile, line);
X      {
X  	int omask = umask(077);
X***************
X*** 297,303 ****
X  	ed_fp = fopen(edfile, "w+");
X  	(void) umask(omask);
X  	if (!ed_fp) {
X! 	    if (home != ALTERNATE_HOME)
X  		goto alted;
X  #ifdef SUNTOOL
X  	    if (istool)
X--- 299,305 ----
X  	ed_fp = fopen(edfile, "w+");
X  	(void) umask(omask);
X  	if (!ed_fp) {
X! 	    if (dir != ALTERNATE_HOME)
X  		goto alted;
X  #ifdef SUNTOOL
X  	    if (istool)
X***************
X*** 407,415 ****
X  	 * be cleared cuz it's a new call.
X  	 */
X  	(void) setjmp(cntrl_c_buf);
X! 	while (Getstr(line, sizeof(line), 0) > -1)
X  	    if ((i = add_to_letter(line)) <= 0)
X  		break;
X      } while (i >= 0 && !finish_up_letter());
X      return i; /* return -1 if ~x or ~q to terminate letter */
X  }
X--- 409,419 ----
X  	 * be cleared cuz it's a new call.
X  	 */
X  	(void) setjmp(cntrl_c_buf);
X! 	while (Getstr(line, sizeof(line), 0) > -1) {
X! 	    (void) check_new_mail(); /* if new mail comes in, get it */
X  	    if ((i = add_to_letter(line)) <= 0)
X  		break;
X+ 	}
X      } while (i >= 0 && !finish_up_letter());
X      return i; /* return -1 if ~x or ~q to terminate letter */
X  }
X***************
X*** 513,519 ****
X  	    if (!*p || *p == 'i' && !p[1])
X  		switch (line[1]) {
X  		    case 'p' :
X! 			if (!(p = do_set(set_options, "pager")))
X  			    p = DEF_PAGER;
X  			if (!*p || !strcmp(p, "internal"))
X  			    p = NULL;
X--- 517,523 ----
X  	    if (!*p || *p == 'i' && !p[1])
X  		switch (line[1]) {
X  		    case 'p' :
X! 			if (!*p && !(p = do_set(set_options, "pager")))
X  			    p = DEF_PAGER;
X  			if (!*p || !strcmp(p, "internal"))
X  			    p = NULL;
X***************
X*** 1043,1049 ****
X      /* Sign the letter before adding the Bcc list since they aren't
X       * considered when adding a signature.
X       */
X!     if (ison(flags, SIGN) && isoff(glob_flags, REDIRECT))
X  	sign_letter(addr_list);
X  
X      if (*Bcc) {
X--- 1047,1054 ----
X      /* Sign the letter before adding the Bcc list since they aren't
X       * considered when adding a signature.
X       */
X!     if ((ison(flags, SIGN) || ison(flags, FORTUNE)) &&
X! 	isoff(glob_flags, REDIRECT) && isoff(flags, FORWARD))
X  	sign_letter(addr_list);
X  
X      if (*Bcc) {
X***************
X*** 1351,1357 ****
X  register char *list; /* list of addresses -- no comment fields */
X  {
X      char buf[BUFSIZ];
X!     register char *p, *p2, *signature, *addr;
X      FILE 	*pp2;
X      int 	lines = 0;
X  
X--- 1356,1362 ----
X  register char *list; /* list of addresses -- no comment fields */
X  {
X      char buf[BUFSIZ];
X!     register char *p = NULL, *p2, *signature, *addr;
X      FILE 	*pp2;
X      int 	lines = 0;
X  
X***************
X*** 1358,1424 ****
X      buf[0] = 0;
X      while (isspace(*list))
X  	list++;
X!     if (p = do_set(set_options, "autosign2")) {
X! 	if (!(signature = index(p, ':')))
X! 	    wprint("\"autosign2\" incorrectly set (missing `:').\n");
X! 	else {
X! 	    int ret_val = 0;
X! 	    *signature = 0;
X! 	    /* p now points to a list of addresses and p2 points to the
X! 	     * signature format to use. Check that each address contains
X! 	     * the stuff in alternate sign.
X! 	     */
X! 	    skipspaces(0);
X! 	    if (!*p)
X! 		/* autosign2 = " : <signature>"  send to all recipients */
X! 		ret_val = 1;
X! 	    else if (p = alias_to_address(p)) {
X! 		rm_cmts_in_addr(p);
X! 		for (addr = list;;) {
X! 		    char c;
X! 		    if (p2 = any(addr, ", ")) {
X! 			c = *p2;
X! 			*p2 = 0;
X  		    }
X- 		    ret_val = chk_two_lists(addr, p, ", ");
X- 		    if (p2)
X- 			for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
X- 			    ;
X- 		    if (!ret_val || !(addr = p2))
X- 			break;
X  		}
X  	    }
X- 	    *signature++ = ':'; /* must reset first! */
X- 	    if (ret_val) {
X- 		while (isspace(*signature))
X- 		    signature++;
X- 		if (!*strcpy(buf, signature))
X- 		    return;
X- 	    }
X  	}
X!     }
X!     if (!buf[0]) {
X! 	if (!(p = do_set(set_options, "autosign")) || !*p) {
X! 	    char *home;
X! 	    if (!(home = do_set(set_options, "home")) || !*home)
X! 		home = ALTERNATE_HOME;
X! 	    (void) sprintf(buf, "%s/%s", home, SIGNATURE);
X  	} else
X! 	    (void) strcpy(buf, p);
X! 	wprint("Signing letter... ");
X!     } else
X! 	wprint("Using alternate signature... ");
X!     fputc('\n', ed_fp), fflush(ed_fp);
X!     (void) fseek(ed_fp, 0L, 2); /* guarantee position at end of file */
X!     if (*buf == '$')
X! 	if (!(p = do_set(set_options, buf)))
X! 	    wprint("(%s isn't set -- letter not signed)\n", buf);
X  	else
X! 	    fprintf(ed_fp, "%s\n", p), wprint("\n"), fflush(ed_fp);
X!     else if (*buf == '\\')
X! 	fprintf(ed_fp, "%s\n", buf+1), wprint("\n"), fflush(ed_fp);
X!     else
X! 	file_to_fp(buf, ed_fp, "r");
X  
X      /* if fortune is set, check to see if fortunates is set. If so,
X       * check to see if all the recipient are on the fortunates list.
X--- 1363,1431 ----
X      buf[0] = 0;
X      while (isspace(*list))
X  	list++;
X!     if (ison(flags, SIGN)) {
X! 	if (p = do_set(set_options, "autosign2")) {
X! 	    if (!(signature = index(p, ':')))
X! 		(void) strcpy(buf, p); /* No colon; use entire string as sig */
X! 	    else {
X! 		int ret_val = 0;
X! 		*signature = 0;
X! 		/* p now points to a list of addresses and p2 points to the
X! 		 * signature format to use. Check that each address contains
X! 		 * the stuff in alternate sign.
X! 		 */
X! 		skipspaces(0);
X! 		if (!*p)
X! 		    /* autosign2 = " : <signature>"  send to all recipients */
X! 		    ret_val = 1;
X! 		else if (p = alias_to_address(p)) {
X! 		    rm_cmts_in_addr(p);
X! 		    for (addr = list;;) {
X! 			char c;
X! 			if (p2 = any(addr, ", ")) {
X! 			    c = *p2;
X! 			    *p2 = 0;
X! 			}
X! 			ret_val = chk_two_lists(addr, p, ", ");
X! 			if (p2)
X! 			    for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
X! 				;
X! 			if (!ret_val || !(addr = p2))
X! 			    break;
X  		    }
X  		}
X+ 		*signature++ = ':'; /* must reset first! */
X+ 		if (ret_val) {
X+ 		    while (isspace(*signature))
X+ 			signature++;
X+ 		    if (!*strcpy(buf, signature))
X+ 			return;
X+ 		}
X  	    }
X  	}
X! 	if (!buf[0]) {
X! 	    if (!(p = do_set(set_options, "autosign")) || !*p) {
X! 		char *home;
X! 		if (!(home = do_set(set_options, "home")) || !*home)
X! 		    home = ALTERNATE_HOME;
X! 		(void) sprintf(buf, "%s/%s", home, SIGNATURE);
X! 	    } else
X! 		(void) strcpy(buf, p);
X! 	    wprint("Signing letter... ");
X  	} else
X! 	    wprint("Using alternate signature... ");
X! 	fputs("\n-- \n", ed_fp), fflush(ed_fp);
X! 	(void) fseek(ed_fp, 0L, 2); /* guarantee position at end of file */
X! 	if (*buf == '$')
X! 	    if (!(p = do_set(set_options, buf)))
X! 		wprint("(%s isn't set -- letter not signed)\n", buf);
X! 	    else
X! 		fprintf(ed_fp, "%s\n", p), wprint("\n"), fflush(ed_fp);
X! 	else if (*buf == '\\')
X! 	    fprintf(ed_fp, "%s\n", buf+1), wprint("\n"), fflush(ed_fp);
X  	else
X! 	    file_to_fp(buf, ed_fp, "r");
X!     }
X  
X      /* if fortune is set, check to see if fortunates is set. If so,
X       * check to see if all the recipient are on the fortunates list.
X*** OLD/main.c	Thu Apr  7 22:47:31 1988
X--- main.c	Thu May 12 17:14:16 1988
X***************
X*** 25,32 ****
X  char **argv;
X  {
X      u_long 	    flg = NO_FLG;
X!     int		    n, source_rc = TRUE;
X!     char 	    f_flags[10], buf[256], *Cc = NULL, *Subj = NULL;
X      register char  *p;
X      char	  **args;
X  
X--- 25,33 ----
X  char **argv;
X  {
X      u_long 	    flg = NO_FLG;
X!     int		    n, source_rc = TRUE, src_n_exit;
X!     char 	    f_flags[10], buf[256];
X!     char	   *Cc = NULL, *Subj = NULL, *src_file = NULL;
X      register char  *p;
X      char	  **args;
X  
X***************
X*** 93,98 ****
X--- 94,100 ----
X  #endif /* SUNTOOL */
X  		case 'S' : turnon(glob_flags, DO_SHELL);
X  		case 'f' :
X+ 		case 'F' :
X  		case 'u' :
X  		    if (args[1])
X  			args++;
X***************
X*** 147,153 ****
X  		else
X  		    turnon(glob_flags, PRE_CURSES);
X  #endif /* CURSES */
X! 	    when 'N':
X  		(void) strcat(f_flags, "-N ");
X  	    when 'r':
X  		(void) strcat(f_flags, "-r "); /* folder() argument */
X--- 149,160 ----
X  		else
X  		    turnon(glob_flags, PRE_CURSES);
X  #endif /* CURSES */
X! 	    when 'F':
X! 		src_n_exit = (argv[0][2] == '!');
X! 		if (!(src_file = *++argv))
X! 		    puts("specify filename to source"), exit(1);
X! 		/* fall thru! */
X! 	    case 'N':
X  		(void) strcat(f_flags, "-N ");
X  	    when 'r':
X  		(void) strcat(f_flags, "-r "); /* folder() argument */
X***************
X*** 228,233 ****
X--- 235,241 ----
X  	}
X  
X      if (source_rc) {
X+ 	/* use cmd_line() in case DEFAULT_RC has expandable chars */
X  	(void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
X  	(void) source(0, DUBL_NULL);
X      }
X***************
X*** 322,328 ****
X      }
X  
X      /* find a free tmpfile */
X!     if (!(p = do_set(set_options, "home")) || !*p)
X  alted:
X  	p = ALTERNATE_HOME;
X      flg = getpid();
X--- 330,337 ----
X      }
X  
X      /* find a free tmpfile */
X!     if (!(p = do_set(set_options, "tmpdir")) &&
X! 	!(p = do_set(set_options, "home")))
X  alted:
X  	p = ALTERNATE_HOME;
X      flg = getpid();
X***************
X*** 348,354 ****
X      (void) signal(SIGQUIT, catch);
X      (void) signal(SIGHUP,  catch);
X  
X!     if (!hdrs_only && !istool && !do_set(set_options, "quiet"))
X  	printf("%s: Type '?' for help.\n", VERSION);
X  
X      (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
X--- 357,364 ----
X      (void) signal(SIGQUIT, catch);
X      (void) signal(SIGHUP,  catch);
X  
X!     if (!hdrs_only && !istool && (!src_file || !src_n_exit) &&
X! 	!do_set(set_options, "quiet"))
X  	printf("%s: Type '?' for help.\n", VERSION);
X  
X      (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
X***************
X*** 368,373 ****
X--- 378,392 ----
X      turnon(glob_flags, DO_SHELL);
X      if (istool && msg_cnt)
X  	set_isread(current_msg);
X+ 
X+     /* finally, if the user wanted to source a file to execute, do it now */
X+     if (src_file) {
X+ 	char *s_argv[2];
X+ 	s_argv[1] = src_file;
X+ 	(void) source(2, s_argv);
X+ 	if (!istool && src_n_exit)
X+ 	    cleanup(0);
X+     }
X  
X  #ifdef SUNTOOL
X      if (istool) {
X*** OLD/makefile.bsd	Thu Apr  7 22:47:37 1988
X--- makefile.bsd	Wed May 11 15:53:44 1988
X***************
X*** 7,13 ****
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o curses.o curs_io.o bind.o
X! HELP_FILES= README-6.0 README cmd_help mush.1
X  MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
X  
X  CFLAGS= -O -DCURSES -DBSD
X--- 7,15 ----
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o curses.o curs_io.o bind.o
X! 
X! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
X! 
X  MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
X  
X  CFLAGS= -O -DCURSES -DBSD
X*** OLD/makefile.sun	Thu Apr  7 22:47:40 1988
X--- makefile.sun	Wed May 11 15:53:25 1988
X***************
X*** 17,23 ****
X  IMAGES= mail.icon.1 mail.icon.2 check.pr cycle.pr envelope.pr glasses.pr \
X  	write.pr up.arrow.pr dn.arrow.pr coffee.cup.pr
X  
X! HELP_FILES= README-6.0 README cmd_help tool_help mush.1
X  
X  MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.x286 makefile.x386
X  
X--- 17,23 ----
X  IMAGES= mail.icon.1 mail.icon.2 check.pr cycle.pr envelope.pr glasses.pr \
X  	write.pr up.arrow.pr dn.arrow.pr coffee.cup.pr
X  
X! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help tool_help
X  
X  MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.x286 makefile.x386
X  
X*** OLD/makefile.x286	Tue Apr 12 22:00:18 1988
X--- makefile.x286	Wed May 11 15:54:23 1988
X***************
X*** 10,16 ****
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
X! DOCS= README cmd_help mush.1
X  MAKES= makefile.sys.v makefile.xenix makefile.bsd
X  
X  CFLAGS= -O -DSYSV -Mle -DCURSES -DREGCMP -DUSG
X--- 10,16 ----
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
X! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
X  MAKES= makefile.sys.v makefile.xenix makefile.bsd
X  
X  CFLAGS= -O -DSYSV -Mle -DCURSES -DREGCMP -DUSG
X***************
X*** 28,34 ****
X  	cc $(CFLAGS) -LARGE -c bind.c
X  
X  shar:
X! 	shar ${DOCS} ${MAKES} ${HDRS}>hdr.shr
X  	shar ${SRCS1} > src1.shr
X  	shar ${SRCS2} > src2.shr
X  	shar ${SRCS3} > src3.shr
X--- 28,34 ----
X  	cc $(CFLAGS) -LARGE -c bind.c
X  
X  shar:
X! 	shar ${HELP_FILES} ${MAKES} ${HDRS}>hdr.shr
X  	shar ${SRCS1} > src1.shr
X  	shar ${SRCS2} > src2.shr
X  	shar ${SRCS3} > src3.shr
X***************
X*** 39,45 ****
X  	shar ${SRCS8} > src8.shr
X  
X  tar:
X! 	tar fcv MUSH ${MAKES} ${HDRS} ${DOCS} ${SRCS1} \
X  	${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS}8
X  
X  clean:
X--- 39,45 ----
X  	shar ${SRCS8} > src8.shr
X  
X  tar:
X! 	tar fcv MUSH ${MAKES} ${HDRS} ${HELP_FILES} ${SRCS1} \
X  	${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS}8
X  
X  clean:
X*** OLD/makefile.x386	Tue Apr 12 21:59:57 1988
X--- makefile.x386	Wed May 11 15:54:42 1988
X***************
X*** 10,16 ****
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
X! DOCS= README cmd_help mush.1
X  MAKES= makefile.sys.v makefile.xenix makefile.bsd
X  
X  CFLAGS= -O -DSYSV -M3e -DCURSES -DREGCMP -DUSG 
X--- 10,16 ----
X  OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
X        signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
X        folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
X! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
X  MAKES= makefile.sys.v makefile.xenix makefile.bsd
X  
X  CFLAGS= -O -DSYSV -M3e -DCURSES -DREGCMP -DUSG 
X***************
X*** 25,31 ****
X  	cc $(CFLAGS) -LARGE -c bind.c
X  
X  shar:
X! 	shar ${DOCS} ${MAKES} ${HDRS}>hdr.shr
X  	shar ${SRCS1} > src1.shr
X  	shar ${SRCS2} > src2.shr
X  	shar ${SRCS3} > src3.shr
X--- 25,31 ----
X  	cc $(CFLAGS) -LARGE -c bind.c
X  
X  shar:
X! 	shar ${HELP_FILES} ${MAKES} ${HDRS}>hdr.shr
X  	shar ${SRCS1} > src1.shr
X  	shar ${SRCS2} > src2.shr
X  	shar ${SRCS3} > src3.shr
X***************
X*** 36,42 ****
X  	shar ${SRCS8} > src8.shr
X  
X  tar:
X! 	tar fcv MUSH ${MAKES} ${HDRS} ${DOCS} ${SRCS1} \
X  	${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS8}
X  
X  clean:
X--- 36,42 ----
X  	shar ${SRCS8} > src8.shr
X  
X  tar:
X! 	tar fcv MUSH ${MAKES} ${HDRS} ${HELP_FILES} ${SRCS1} \
X  	${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS8}
X  
X  clean:
X*** OLD/misc.c	Thu Apr  7 22:47:54 1988
X--- misc.c	Wed May 11 14:01:36 1988
X***************
X*** 354,363 ****
X  	turnon(glob_flags, IGN_SIGS);
X  	if (!buf)
X  	    pp = stdout;
X! 	else if (!(pp = popen(buf, "w")))
X! 	    error(buf);
X! 	else
X  	    echo_on();
X  	cnt = 0;
X      } else if (!buf) {
X  	if (pp && pp != stdout)
X--- 354,364 ----
X  	turnon(glob_flags, IGN_SIGS);
X  	if (!buf)
X  	    pp = stdout;
X! 	else {
X  	    echo_on();
X+ 	    if (!(pp = popen(buf, "w")))
X+ 		error(buf);
X+ 	}
X  	cnt = 0;
X      } else if (!buf) {
X  	if (pp && pp != stdout)
X*** OLD/mush.1	Wed Apr  6 00:34:07 1988
X--- mush.1	Thu May 12 17:08:32 1988
X***************
X*** 60,65 ****
X--- 60,70 ----
X  .B \-f
X  [ folder ]
X  ]
X+ [
X+ .B \-F
X+ [!]
X+ [ file ]
X+ ]
X  .br
X  .B mush
X  [
X***************
X*** 126,131 ****
X--- 131,140 ----
X  .B \-f
X  [ folder ]
X  ]
X+ [
X+ .B \-F
X+ [ file ]
X+ ]
X  .br
X  .B mush
X  [
X***************
X*** 218,223 ****
X--- 227,244 ----
X  .B debug
X  command.
X  .TP
X+ \-F[!] filename
X+ This file is the same type as the initialization file read on startup
X+ (see INITIALIZATION) with the exception that commands which manipulate
X+ or search messages may be given.  Normally, such commands may not exist
X+ in the initialization file since that file is read before the folder
X+ is scanned.  This file is read after the folder is scanned, so commands
X+ which change folders are allowed.
X+ The optional `!' argument prevents the shell from running after the file
X+ has been sourced.  Otherwise,
X+ .I Mush
X+ continues into whatever interface has been specified.
X+ .TP
X  \-f [ filename ]
X  The optional filename argument specifies a folder containing mail messages.
X  With no argument,
X***************
X*** 2069,2091 ****
X  Options:
X  .ta 1.5i
X  .in +2
X! \-d [\-]date	messages sent on or after [`\-' before] date
X! \-f	search for pattern in \*QFrom\*U field only
X! \-h header	search for pattern in specified header only
X! \-i	ignore case of letters when searching
X! \-r msg_list	search only the listed messages
X! \-s	search for pattern in \*QSubject\*U field only
X! \-t	search for pattern in \*QTo\*U field only
X! \-x	select messages not containing the pattern
X  .in -2
X  .fi
X  .sp
X! Only one of \-d, \-f, \-h, \-s and \-t can be specified at once.
X  Entire messages are scanned for the <pattern>
X! unless \-f, \-h, \-s or \-t is specified.
X  Messages marked for deletion are also searched.
X! No patterns can be specified with the \-d option,
X! and the \-x option may not be used with \-d.
X  .sp
X  For the \-d option, \*Qdate\*U is of the form:
X  .sp
X--- 2090,2112 ----
X  Options:
X  .ta 1.5i
X  .in +2
X! \-d [+-]date	messages sent on or [+ after] [`\-' before] date.
X! \-ago <format>	search for messages relative to today's date.
X! \-f	search for pattern in \*QFrom\*U field only.
X! \-i	ignore case of letters when searching.
X! \-r msg_list	search only the listed messages.
X! \-s	search for pattern in \*QSubject\*U field only.
X! \-t	search for pattern in \*QTo\*U field only.
X! \-h header	search for pattern in specified header only.
X! \-x	select messages not containing the pattern.
X  .in -2
X  .fi
X  .sp
X! Only one of \-d, \-a, \-f, \-h, \-s and \-t can be specified at once.
X  Entire messages are scanned for the <pattern>
X! unless \-d, \-a, \-f, \-h, \-s or \-t is specified.
X  Messages marked for deletion are also searched.
X! No patterns can be specified with the \-d or \-a options.
X  .sp
X  For the \-d option, \*Qdate\*U is of the form:
X  .sp
X***************
X*** 2100,2108 ****
X  .in +2
X  .ta 2.0i
X  .sp
X! pick \-d 4/20	on or after April 20, this year
X! pick \-d \-/2/85	on or before the 2nd, this month, 1985
X! pick \-d /	today only
X  .fi
X  .in -2
X  .sp
X--- 2121,2130 ----
X  .in +2
X  .ta 2.0i
X  .sp
X! pick \-d 4/20	on April 20, this year.
X! pick \-d \-/2/85	on or before the 2nd, this month, 1985.
X! pick \-d +5/4	on or after May 4 of this year.
X! pick \-d /	today only.
X  .fi
X  .in -2
X  .sp
X***************
X*** 2109,2114 ****
X--- 2131,2159 ----
X  At least one `/' char must be used in a date.
X  There is no strong date checking; 2/30 would be considered a valid date.
X  .sp
X+ For the \-ago option, the format is very simple.  Specify the number of
X+ days followed by the word \*Qdays\*U, or the number of weeks followed by
X+ the word \*Qweeks\*U, and so on with months and years.  Truncation is allowed,
X+ since only the first character is examined, so all of the following are
X+ equivalent:
X+ .sp
X+ .in +2
X+ pick -ago 1 day, 2 weeks
X+ pick -ago 2Weeks 1Day
X+ pick -ago 2w,1day
X+ pick -a 2w1d
X+ .in -2
X+ These examples will find all messages that are exactly 2 weeks and 1 day
X+ old.  All \*Qago\*U dates collapse into \*Qday\*U time segments.  This
X+ means that months are 30.5 days long.  If more precise date selection is
X+ required, use the \-d option and specify specific dates.
X+ .sp
X+ Also note that the -ago option allows the \*Qbefore\*U (-) and \*Qafter\*U (+)
X+ arguments.  Thus, you may pick for all messages older than 1 week with:
X+ .sp
X+ .ti +2
X+ pick -ago -1 week
X+ .sp
X  Other examples of
X  .B pick:
X  .sp
X***************
X*** 2116,2127 ****
X  pick \-d 2/5/86 | pick \-d \-2/5/87 | pick \-s "mail stuff" | lpr
X  .sp
X  will find all the messages between the dates February 5, 1986 and
X! February 5, 1987 that contain the subject "mail stuff" and print them.
X  .sp
X  .ti +2
X  pick -s Re: | delete
X  .sp
X! deletes messages that have \*QRe:\*U in the subject
X  .sp
X  .ti +2
X  folder +project | pick -f frank
X--- 2161,2173 ----
X  pick \-d 2/5/86 | pick \-d \-2/5/87 | pick \-s "mail stuff" | lpr
X  .sp
X  will find all the messages between the dates February 5, 1986 and
X! February 5, 1987 that contain the subject "mail stuff" and send them
X! to the printer.
X  .sp
X  .ti +2
X  pick -s Re: | delete
X  .sp
X! deletes messages that have \*QRe:\*U in the Subject header.
X  .sp
X  .ti +2
X  folder +project | pick -f frank
X***************
X*** 2135,2140 ****
X--- 2181,2192 ----
X  if the string \*Qucbvax\*U is in the header.
X  Note that case sensitivity
X  applies only to the pattern searched, not the header itself.
X+ .sp
X+ .ti +2
X+ pick -ago +1w | save +current
X+ .sp
X+ This finds all messages that are a week or less old and saves them in the file
X+ called \fIcurrent\fR, which is found in the user's \fIfolder\fR variable.
X  .TP
X  .B preserve
X  .RB ( pre )
X***************
X*** 3287,3292 ****
X--- 3339,3353 ----
X  (Boolean)
X  Whenever messages are read, piped, or saved, if this variable is set,
X  all consecutive blank lines are squeezed into one blank line.
X+ .TP
X+ .B tmpdir
X+ (String)
X+ This variable describes the path to use as the directory to use
X+ for all tempfiles that
X+ .I Mush
X+ uses.  By default, the user's home directory is used.  If that
X+ cannot be accessed, a directory writable by all is used (typically, /tmp).
X+ If \fBtmpdir\fR is set, then it is used first.
X  .TP
X  .B toplines
X  (Numeric)
X*** OLD/mush.h	Thu May 12 13:52:11 1988
X--- mush.h	Wed May 11 15:19:26 1988
X***************
X*** 1,6 ****
X  /* @(#)mush.h	(c) copyright 1986 (Dan Heller) */
X  
X! #define VERSION "Mail User's Shell (6.1 4/26/88)"
X  
X  #include "config.h"
X  
X--- 1,6 ----
X  /* @(#)mush.h	(c) copyright 1986 (Dan Heller) */
X  
X! #define VERSION "Mail User's Shell (6.2 5/11/88)"
X  
X  #include "config.h"
X  
X*** OLD/pick.c	Tue Mar  1 14:59:20 1988
X--- pick.c	Wed May 11 15:51:46 1988
X***************
X*** 2,9 ****
X  
X  #include "mush.h"
X  
X! static int before, mdy[3], search_from, search_subj, search_to, xflg, icase;
X! static search_hdr[64];
X  
X  do_pick(n, argv, list)
X  register int n;
X--- 2,9 ----
X  
X  #include "mush.h"
X  
X! static int before, after, search_from, search_subj, search_to, xflg, icase;
X! static mdy[3], search_hdr[64];
X  
X  do_pick(n, argv, list)
X  register int n;
X***************
X*** 38,45 ****
X  register char **argv, list[];
X  {
X      register char c;
X!     int o_before = before, o_mdy[3], o_search_from = search_from,
X! 	o_search_subj = search_subj, o_search_to = search_to, o_xflg = xflg, n;
X  
X      for (c = 0; c < 3; c++)
X  	o_mdy[c] = mdy[c];
X--- 38,46 ----
X  register char **argv, list[];
X  {
X      register char c;
X!     int o_before = before, o_after = after, o_search_from = search_from,
X! 	o_search_subj = search_subj, o_search_to = search_to, o_xflg = xflg,
X! 	o_mdy[3], n;
X  
X      for (c = 0; c < 3; c++)
X  	o_mdy[c] = mdy[c];
X***************
X*** 50,56 ****
X  	goto bad;
X      }
X  
X!     icase = before = search_from = search_subj = xflg = 0;
X      mdy[0] = search_hdr[0] = 0;
X      while (*argv && *++argv && **argv == '-')
X  	switch(c = argv[0][1]) {
X--- 51,57 ----
X  	goto bad;
X      }
X  
X!     icase = before = after = search_from = search_subj = xflg = 0;
X      mdy[0] = search_hdr[0] = 0;
X      while (*argv && *++argv && **argv == '-')
X  	switch(c = argv[0][1]) {
X***************
X*** 76,81 ****
X--- 77,88 ----
X  		    goto bad;
X  		argv += (n-1); /* we're going to increment another up top */
X  	    }
X+ 	    when 'a': {
X+ 		int n = ago_date(++argv);
X+ 		if (n == -1)
X+ 		    goto bad;
X+ 		argv += n;
X+ 	    }
X  	    when 'd':
X  		if (!*++argv) {
X  		    print("specify a date for -%c\n", c);
X***************
X*** 108,129 ****
X  	}
X      if (verbose) {
X  	print_more("Searching for messages");
X! 	if (mdy[1] == 0)
X  	    print(" that %s \"%s\"", (xflg)? "doesn't contain": "contains",
X  				(*argv)? *argv: "<previous expression>");
X! 	if (search_subj)
X! 	    print_more(" in subject line");
X! 	else if (search_from)
X! 	    print_more(" from author names");
X! 	else if (search_to)
X! 	    print_more(" from the To: field");
X! 	else if (search_hdr[0])
X! 	    print_more(" from the message header: \"%s:\"", search_hdr);
X! 	if (mdy[1] > 0) {
X  	    extern char *month_names[]; /* from dates.c */
X! 	    print_more(" dated on or %s %s. %d, 19%d.",
X! 		  (before)? "before": "after",
X! 		  month_names[mdy[0]], mdy[1], mdy[2]);
X  	}
X  	print_more("\n");
X      }
X--- 115,138 ----
X  	}
X      if (verbose) {
X  	print_more("Searching for messages");
X! 	if (mdy[1] == 0) {
X  	    print(" that %s \"%s\"", (xflg)? "doesn't contain": "contains",
X  				(*argv)? *argv: "<previous expression>");
X! 	    if (search_subj)
X! 		print_more(" in subject line");
X! 	    else if (search_from)
X! 		print_more(" from author names");
X! 	    else if (search_to)
X! 		print_more(" from the To: field");
X! 	    else if (search_hdr[0])
X! 		print_more(" from the message header: \"%s:\"", search_hdr);
X! 	} else {
X  	    extern char *month_names[]; /* from dates.c */
X! 	    print_more(" dated ");
X! 	    if (before || after)
X! 		print_more("on or %s ", (before)? "before": "after");
X! 	    print_more("%s. %d, 19%d.",
X! 		      month_names[mdy[0]], mdy[1], mdy[2]);
X  	}
X  	print_more("\n");
X      }
X***************
X*** 131,137 ****
X  	print("using date: -i flag ignored.\n");
X      ret = find_pattern(*argv, list);
X  bad:
X!     before = o_before, search_from = o_search_from;
X      search_subj = o_search_subj, search_to = o_search_to, xflg = o_xflg;
X      for (c = 0; c < 3; c++)
X  	mdy[c] = o_mdy[c];
X--- 140,146 ----
X  	print("using date: -i flag ignored.\n");
X      ret = find_pattern(*argv, list);
X  bad:
X!     before = o_before, after = o_after, search_from = o_search_from;
X      search_subj = o_search_subj, search_to = o_search_to, xflg = o_xflg;
X      for (c = 0; c < 3; c++)
X  	mdy[c] = o_mdy[c];
X***************
X*** 197,204 ****
X  		 */
X  		for (i = 2; i < 5; i++)
X  		    if (before && msg_mdy[i%3] < mdy[i%3]
X! 			|| !before && msg_mdy[i%3] > mdy[i%3]
X! 			|| i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
X  			    Debug("matched (%s).\n",
X  				(i == 2)? "year" : (i == 3)? "month" : "day");
X  			    break;
X--- 206,213 ----
X  		 */
X  		for (i = 2; i < 5; i++)
X  		    if (before && msg_mdy[i%3] < mdy[i%3]
X! 		    ||  after  && msg_mdy[i%3] > mdy[i%3]
X! 		    ||  i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
X  			    Debug("matched (%s).\n",
X  				(i == 2)? "year" : (i == 3)? "month" : "day");
X  			    break;
X***************
X*** 373,380 ****
X      int 	  i;
X      struct tm 	  *today;
X  
X!     if (*p == '-') {
X! 	before = 1;
X  	skipspaces(1);
X      }
X      if (!isdigit(*p) && *p != '/') {
X--- 382,389 ----
X      int 	  i;
X      struct tm 	  *today;
X  
X!     if (*p == '-' || *p == '+') {
X! 	before = !(after = *p == '+');
X  	skipspaces(1);
X      }
X      if (!isdigit(*p) && *p != '/') {
X***************
X*** 406,409 ****
X--- 415,484 ----
X  		p++;
X  	}
X      return 1;
X+ }
X+ 
X+ /*
X+  * Parse arguments specifying days/months/years "ago" (relative to today).
X+  * Legal syntax: -ago [+-][args]
X+  *    where "args" is defined to be:
X+  *    [0-9]+[ ]*[dD][a-Z]*[ ,]*[0-9]+[mM][a-Z]*[ ,]*[0-9]+[ ]*[yY][a-Z]*
X+  *    1 or more digits, 0 or more spaces, d or D followed by 0 or more chars,
X+  *    0 or more whitespaces or commas, repeat for months and years...
X+  * Examples:
X+  *    1 day, 2 months, 0 years
X+  *    2 weeks 1 year
X+  *    10d, 5m
X+  *    3w
X+  *    1d 1Y
X+  *
X+  * Return number of args parsed; -1 on error.
X+  */
X+ ago_date(argv)
X+ char **argv;
X+ {
X+ #define SECS_PER_DAY   (60 * 60 * 24)
X+ #define SECS_PER_WEEK  (SECS_PER_DAY * 7)
X+ #define SECS_PER_MONTH ((int)(SECS_PER_DAY * 30.5))
X+ #define SECS_PER_YEAR  (SECS_PER_DAY * 365)
X+     register char *p;
X+     char	   buf[256];
X+     int		   n = 0, value, mdy_index = 0;
X+     long	   t;
X+     struct tm 	  *today;
X+ 
X+     (void) argv_to_string(buf, argv);
X+     p = buf;
X+     (void) time (&t); /* get current time in seconds and subtract new values */
X+     if (*p == '-')
X+ 	before = TRUE;
X+     else if (*p == '+')
X+ 	after = TRUE;
X+     skipspaces(before || after);
X+     while (*p) {
X+ 	if (!isdigit(*p))
X+ 	    break; /* really a syntax error, but it could be other pick ars */
X+ 	p = my_atoi(p, &value); /* get 1 or more digits */
X+ 	skipspaces(0); /* 0 or more spaces */
X+ 	switch (lower(*p)) {   /* d, m, or y */
X+ 	    when 'd' : t -= value * SECS_PER_DAY;
X+ 	    when 'w' : t -= value * SECS_PER_WEEK;
X+ 	    when 'm' : t -= value * SECS_PER_MONTH;
X+ 	    when 'y' : t -= value * SECS_PER_YEAR;
X+ 	    otherwise: return -1;
X+ 	}
X+ 	for (p++; Lower(*p) >= 'a' && *p <= 'z'; p++)
X+ 	    ; /* skip the rest of this token */
X+ 	while (*p == ',' || isspace(*p))
X+ 	    ; /* 0 or more whitespaces or commas */
X+     }
X+     today = localtime(&t);
X+     mdy[0] = today->tm_mon;
X+     mdy[1] = today->tm_mday;
X+     mdy[2] = today->tm_year;
X+ 
X+     /* Count the number of args parsed */
X+     for (n = 0; p > buf && *argv; n++)
X+ 	p -= (strlen(*argv++)+1);
X+     Debug("parsed %d args\n", n);
X+     return n;
X  }
X*** OLD/print.c	Thu May 12 13:52:13 1988
X--- print.c	Thu Apr 28 21:47:54 1988
X***************
X*** 1,4 ****
X- 
X  /* @(#)print.c	2.4	(c) copyright 10/15/86 (Dan Heller) */
X  
X  #include "mush.h"
X--- 1,3 ----
X***************
X*** 185,188 ****
X  {
X      print("");
X  }
X- 
X--- 184,186 ----
X*** OLD/strings.c	Thu Apr  7 09:51:46 1988
X--- strings.c	Tue Apr 26 19:01:20 1988
X***************
X*** 219,229 ****
X  }
X  
X  #ifdef SYSV
X  char *
X! Sprintf(buf, fmt, args)
X  register char *buf, *fmt;
X  {
X!     vsprintf(buf, fmt, &args);
X      return buf;
X  }
X  #endif /* SYSV */
X--- 219,247 ----
X  }
X  
X  #ifdef SYSV
X+ #include <varargs.h>
X  char *
X! Sprintf(buf, fmt, va_alist)
X  register char *buf, *fmt;
X+ va_dcl
X  {
X!     va_list ap;
X! #ifdef VPRINTF
X!     va_start(ap);
X!     (void) vsprintf(buf, fmt, ap);
X!     va_end(ap);
X! #else
X!     {
X! 	FILE foo;
X! 	foo._cnt = BUFSIZ;
X! 	foo._base = foo._ptr = buf; /* may have to be cast (unsigned char *) */
X! 	foo._flag = _IOWRT+_IOSTRG;
X! 	va_start(ap);
X! 	(void) _doprnt(fmt, ap, &foo);
X! 	va_end(ap);
X! 	*foo._ptr = '\0'; /* plant terminating null character */
X!     }
X! #endif /* VPRINTF */
X      return buf;
X  }
X  #endif /* SYSV */
X*** OLD/viewopts.c	Sat Apr  2 21:12:48 1988
X--- viewopts.c	Wed May 11 20:48:41 1988
X***************
X*** 129,134 ****
X--- 129,136 ----
X        "When reading messages, squeeze all blank lines into one." },
X      { "top", "Lines", TOOL | TEXT,
X        "Number of lines to print of a message for the 'top' command."  },
X+     { "tmpdir", "Directory", TOOL | TEXT,
X+       "Directory to use for temporary files used by Mush." },
X      { "unix", NULL, TEXT,
X        "Non-mush commands are considered to be UNIX commands." },
X      { "verify", NULL, TEXT,
END_OF_FILE
if test 38618 -ne `wc -c <'Diffs-6.2'`; then
    echo shar: \"'Diffs-6.2'\" unpacked with wrong size!
fi
# end of 'Diffs-6.2'
fi
echo shar: End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.