home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume15 / mush6.2.pch / Diffs-6.2 next >
Text File  |  1988-05-22  |  39KB  |  1,307 lines

  1. *** OLD/cmd_help    Wed Mar  2 12:05:28 1988
  2. --- cmd_help    Wed May 11 14:06:12 1988
  3. ***************
  4. *** 174,193 ****
  5.   %%
  6.   
  7.   %pick%
  8. ! use: pick [-r msg_list] [-d [-][date] ] [-s|f|t]] [-x] [-i] [-h hdr] [<pat>]
  9.   Search for patterns within messages. Entire messages are searched
  10.   for <pattern> unless -s, -f, -t, or -h is specified.
  11. ! Only one of -s, -f, -t, -d and -h can be specified at once.
  12.   -r msg_list  restrict the range of messages search to msg_list
  13. - -d: print message headers on or after [`-' before] `date' (no patterns).
  14.   -h hdr   requires a header to be searched for.  Pattern searched in that hdr.
  15. !      `date' is of the form: month/date/year
  16.         Omitted fields default to today's values. Examples:
  17. !       pick -d 4/20     msgs on or after Apr 20, this year
  18.         pick -d -/2/85   on or before the 2nd, this month, 1985
  19. !       pick -d /        finds today's messages only.
  20.       At least one `/' char must be used in date.
  21.       There is no strong date checking; 2/30 would be considered valid
  22.   -s search for pattern in the "subject" headers only.
  23.   -f search for pattern in the "from" field (author) only.
  24.   -t search for pattern in the "to" field.
  25. --- 174,196 ----
  26.   %%
  27.   
  28.   %pick%
  29. ! use: pick [-r msg_list] [-d [-][date] ] [-s|f|t]] [-x] [-i]
  30. !       [-h hdr] [-ago [n days] [n weeks] [n months] ] [<pat>]
  31.   Search for patterns within messages. Entire messages are searched
  32.   for <pattern> unless -s, -f, -t, or -h is specified.
  33. ! Only one of -s, -f, -t, -d, -ago and -h can be specified at once.
  34.   -r msg_list  restrict the range of messages search to msg_list
  35.   -h hdr   requires a header to be searched for.  Pattern searched in that hdr.
  36. ! -d: print headers on or [+ after] [- before] `date' (no pattern search).
  37. !      `date' is of the form: [+-] [month]/[date/year]
  38.         Omitted fields default to today's values. Examples:
  39. !       pick -d 4/20     messages on Apr 20, this year
  40.         pick -d -/2/85   on or before the 2nd, this month, 1985
  41. !       pick -d +5/4     on or after May 4, this year
  42. !       pick -d /        finds today's messages only
  43.       At least one `/' char must be used in date.
  44.       There is no strong date checking; 2/30 would be considered valid
  45. + -ago search for messages relative to the current date (see manual).
  46.   -s search for pattern in the "subject" headers only.
  47.   -f search for pattern in the "from" field (author) only.
  48.   -t search for pattern in the "to" field.
  49. *** OLD/commands.c    Thu May 12 13:51:57 1988
  50. --- commands.c    Wed May 11 21:47:30 1988
  51. ***************
  52. *** 752,758 ****
  53.   {
  54.       char **e;
  55.       for (e = environ; *e; e++)
  56. !     if (argc < 1 || !strncmp(*e, argv[1]))
  57.           wprint("%s\n", *e);
  58.       return -1;
  59.   }
  60. --- 752,758 ----
  61.   {
  62.       char **e;
  63.       for (e = environ; *e; e++)
  64. !     if (argc < 2 || !strncmp(*e, argv[1]))
  65.           wprint("%s\n", *e);
  66.       return -1;
  67.   }
  68. *** OLD/curs_io.c    Mon Mar  7 14:57:23 1988
  69. --- curs_io.c    Wed May 11 20:38:32 1988
  70. ***************
  71. *** 135,140 ****
  72. --- 135,141 ----
  73.           Addch(c);
  74.       }
  75.       }
  76. +     fflush(stdout); /* for sys-v folks */
  77.       if (c == CTRL(D) || c == EOF || ison(glob_flags, WAS_INTR)) {
  78.       if (feof(stdin))
  79.           clearerr(stdin);
  80. *** OLD/curses.c    Thu May 12 13:52:00 1988
  81. --- curses.c    Wed May 11 10:39:41 1988
  82. ***************
  83. *** 718,724 ****
  84.       int n;
  85.   
  86.       for (n = 0; n < COLS; n++)
  87. !     if ((buf = mvinch(curline, n) & A_CHARTEXT) == '\0')
  88.           break;
  89.       buf[n] = '\0';
  90.   #endif /* A_CHARTEXT */
  91. --- 718,724 ----
  92.       int n;
  93.   
  94.       for (n = 0; n < COLS; n++)
  95. !     if ((buf = mvinch(line, n) & A_CHARTEXT) == '\0')
  96.           break;
  97.       buf[n] = '\0';
  98.   #endif /* A_CHARTEXT */
  99. *** OLD/execute.c    Sat Apr  2 16:14:19 1988
  100. --- execute.c    Wed May 11 16:17:13 1988
  101. ***************
  102. *** 68,74 ****
  103.        * if other forks die (sendmail), then this wait will catch them,
  104.        * This loop will really get -1, cuz sigchldcatcher will catch all else.
  105.        */
  106. !     while ((pid = wait(&status) != -1) && pid != exec_pid)
  107.       Debug("The exec loop caught a signal? (pid = %d)\n", pid);
  108.       /* reset our ttymodes */
  109.       echo_off();
  110. --- 68,74 ----
  111.        * if other forks die (sendmail), then this wait will catch them,
  112.        * This loop will really get -1, cuz sigchldcatcher will catch all else.
  113.        */
  114. !     while ((pid = wait(&status)) != -1 && pid != exec_pid)
  115.       Debug("The exec loop caught a signal? (pid = %d)\n", pid);
  116.       /* reset our ttymodes */
  117.       echo_off();
  118. *** OLD/help.c    Mon Dec  7 18:37:47 1987
  119. --- help.c    Wed May 11 16:08:07 1988
  120. ***************
  121. *** 72,77 ****
  122. --- 72,79 ----
  123.   #include <sys/types.h>
  124.   #define wprint printf
  125.   #define print  printf
  126. + #define TRUE   1
  127. + #define FALSE  0
  128.   
  129.   #endif /* SUNTOOL */
  130.   
  131. ***************
  132. *** 311,320 ****
  133.       if (height == MAXLINES - 1)
  134.       print("Help message is too long!\n");
  135.   
  136.       for (n = 0; n < height; n++) {
  137.       (void) no_newln(args[n]);
  138. !     wprint("%s\n", args[n]);
  139.       }
  140.   
  141.       return 0;
  142.   }
  143. --- 313,326 ----
  144.       if (height == MAXLINES - 1)
  145.       print("Help message is too long!\n");
  146.   
  147. +     do_pager(NULL, TRUE);
  148.       for (n = 0; n < height; n++) {
  149.       (void) no_newln(args[n]);
  150. !     (void) do_pager(args[n], FALSE);
  151. !     if (do_pager("\n", FALSE) == EOF)
  152. !         break;
  153.       }
  154. +     do_pager(NULL, FALSE);
  155.   
  156.       return 0;
  157.   }
  158. *** OLD/loop.c    Thu May 12 13:52:05 1988
  159. --- loop.c    Wed May 11 21:31:42 1988
  160. ***************
  161. *** 106,112 ****
  162.       if (Getstr(line, sizeof(line), 0) > -1)
  163.           p = line;
  164.       else {
  165. !         if (p = do_set(set_options, "ignoreeof")) {
  166.           if (!*p)
  167.               continue;
  168.           else
  169. --- 106,112 ----
  170.       if (Getstr(line, sizeof(line), 0) > -1)
  171.           p = line;
  172.       else {
  173. !         if (isatty(0) && (p = do_set(set_options, "ignoreeof"))) {
  174.           if (!*p)
  175.               continue;
  176.           else
  177. *** OLD/mail.c    Sat May 21 10:53:59 1988
  178. --- mail.c    Sat May 21 10:56:08 1988
  179. ***************
  180. *** 10,17 ****
  181.    *    mail_someone()    called from do_mail() or from the shell.
  182.    *    add_to_letter()    adds the next line to letter --determine ~ escapes.
  183.    *    finish_up_letter()  prompts for Cc:, verifies user really wants to send
  184. !  *    send_it()        invokes mailer, sends to record file, adds signature,
  185. !  *            fortune, expands aliases, adds own_hdrs.
  186.    *    rm_edfile()    signals are directed here. remove letter, longjmp
  187.    *
  188.    * The flow of control in this file is NOT obvious to allow for both text
  189. --- 10,18 ----
  190.    *    mail_someone()    called from do_mail() or from the shell.
  191.    *    add_to_letter()    adds the next line to letter --determine ~ escapes.
  192.    *    finish_up_letter()  prompts for Cc:, verifies user really wants to send
  193. !  *    send_it()        invokes mailer, sends to record file, expands aliases,
  194. !  *            adds own_hdrs.
  195. !  *    sign_letter()    adds signature and fortunes.
  196.    *    rm_edfile()    signals are directed here. remove letter, longjmp
  197.    *
  198.    * The flow of control in this file is NOT obvious to allow for both text
  199. ***************
  200. *** 283,296 ****
  201.   start_file(list)
  202.   char *list;
  203.   {
  204. !     register char  *home;
  205.       register int   i;
  206.       char         line[MAXPATHLEN];
  207.   
  208. !     if (!(home = do_set(set_options, "home")) || !*home)
  209.   alted:
  210. !     home = ALTERNATE_HOME;
  211. !     (void) mktemp(sprintf(line, "%s/%s", home, EDFILE));
  212.       strdup(edfile, line);
  213.       {
  214.       int omask = umask(077);
  215. --- 284,298 ----
  216.   start_file(list)
  217.   char *list;
  218.   {
  219. !     register char  *dir;
  220.       register int   i;
  221.       char         line[MAXPATHLEN];
  222.   
  223. !     if (!(dir = do_set(set_options, "tmpdir")) &&
  224. !     !(dir = do_set(set_options, "home")))
  225.   alted:
  226. !     dir = ALTERNATE_HOME;
  227. !     (void) mktemp(sprintf(line, "%s/%s", dir, EDFILE));
  228.       strdup(edfile, line);
  229.       {
  230.       int omask = umask(077);
  231. ***************
  232. *** 297,303 ****
  233.       ed_fp = fopen(edfile, "w+");
  234.       (void) umask(omask);
  235.       if (!ed_fp) {
  236. !         if (home != ALTERNATE_HOME)
  237.           goto alted;
  238.   #ifdef SUNTOOL
  239.           if (istool)
  240. --- 299,305 ----
  241.       ed_fp = fopen(edfile, "w+");
  242.       (void) umask(omask);
  243.       if (!ed_fp) {
  244. !         if (dir != ALTERNATE_HOME)
  245.           goto alted;
  246.   #ifdef SUNTOOL
  247.           if (istool)
  248. ***************
  249. *** 407,415 ****
  250.        * be cleared cuz it's a new call.
  251.        */
  252.       (void) setjmp(cntrl_c_buf);
  253. !     while (Getstr(line, sizeof(line), 0) > -1)
  254.           if ((i = add_to_letter(line)) <= 0)
  255.           break;
  256.       } while (i >= 0 && !finish_up_letter());
  257.       return i; /* return -1 if ~x or ~q to terminate letter */
  258.   }
  259. --- 409,419 ----
  260.        * be cleared cuz it's a new call.
  261.        */
  262.       (void) setjmp(cntrl_c_buf);
  263. !     while (Getstr(line, sizeof(line), 0) > -1) {
  264. !         (void) check_new_mail(); /* if new mail comes in, get it */
  265.           if ((i = add_to_letter(line)) <= 0)
  266.           break;
  267. +     }
  268.       } while (i >= 0 && !finish_up_letter());
  269.       return i; /* return -1 if ~x or ~q to terminate letter */
  270.   }
  271. ***************
  272. *** 513,519 ****
  273.           if (!*p || *p == 'i' && !p[1])
  274.           switch (line[1]) {
  275.               case 'p' :
  276. !             if (!(p = do_set(set_options, "pager")))
  277.                   p = DEF_PAGER;
  278.               if (!*p || !strcmp(p, "internal"))
  279.                   p = NULL;
  280. --- 517,523 ----
  281.           if (!*p || *p == 'i' && !p[1])
  282.           switch (line[1]) {
  283.               case 'p' :
  284. !             if (!*p && !(p = do_set(set_options, "pager")))
  285.                   p = DEF_PAGER;
  286.               if (!*p || !strcmp(p, "internal"))
  287.                   p = NULL;
  288. ***************
  289. *** 1043,1049 ****
  290.       /* Sign the letter before adding the Bcc list since they aren't
  291.        * considered when adding a signature.
  292.        */
  293. !     if (ison(flags, SIGN) && isoff(glob_flags, REDIRECT))
  294.       sign_letter(addr_list);
  295.   
  296.       if (*Bcc) {
  297. --- 1047,1054 ----
  298.       /* Sign the letter before adding the Bcc list since they aren't
  299.        * considered when adding a signature.
  300.        */
  301. !     if ((ison(flags, SIGN) || ison(flags, FORTUNE)) &&
  302. !     isoff(glob_flags, REDIRECT) && isoff(flags, FORWARD))
  303.       sign_letter(addr_list);
  304.   
  305.       if (*Bcc) {
  306. ***************
  307. *** 1351,1357 ****
  308.   register char *list; /* list of addresses -- no comment fields */
  309.   {
  310.       char buf[BUFSIZ];
  311. !     register char *p, *p2, *signature, *addr;
  312.       FILE     *pp2;
  313.       int     lines = 0;
  314.   
  315. --- 1356,1362 ----
  316.   register char *list; /* list of addresses -- no comment fields */
  317.   {
  318.       char buf[BUFSIZ];
  319. !     register char *p = NULL, *p2, *signature, *addr;
  320.       FILE     *pp2;
  321.       int     lines = 0;
  322.   
  323. ***************
  324. *** 1358,1424 ****
  325.       buf[0] = 0;
  326.       while (isspace(*list))
  327.       list++;
  328. !     if (p = do_set(set_options, "autosign2")) {
  329. !     if (!(signature = index(p, ':')))
  330. !         wprint("\"autosign2\" incorrectly set (missing `:').\n");
  331. !     else {
  332. !         int ret_val = 0;
  333. !         *signature = 0;
  334. !         /* p now points to a list of addresses and p2 points to the
  335. !          * signature format to use. Check that each address contains
  336. !          * the stuff in alternate sign.
  337. !          */
  338. !         skipspaces(0);
  339. !         if (!*p)
  340. !         /* autosign2 = " : <signature>"  send to all recipients */
  341. !         ret_val = 1;
  342. !         else if (p = alias_to_address(p)) {
  343. !         rm_cmts_in_addr(p);
  344. !         for (addr = list;;) {
  345. !             char c;
  346. !             if (p2 = any(addr, ", ")) {
  347. !             c = *p2;
  348. !             *p2 = 0;
  349.               }
  350. -             ret_val = chk_two_lists(addr, p, ", ");
  351. -             if (p2)
  352. -             for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
  353. -                 ;
  354. -             if (!ret_val || !(addr = p2))
  355. -             break;
  356.           }
  357.           }
  358. -         *signature++ = ':'; /* must reset first! */
  359. -         if (ret_val) {
  360. -         while (isspace(*signature))
  361. -             signature++;
  362. -         if (!*strcpy(buf, signature))
  363. -             return;
  364. -         }
  365.       }
  366. !     }
  367. !     if (!buf[0]) {
  368. !     if (!(p = do_set(set_options, "autosign")) || !*p) {
  369. !         char *home;
  370. !         if (!(home = do_set(set_options, "home")) || !*home)
  371. !         home = ALTERNATE_HOME;
  372. !         (void) sprintf(buf, "%s/%s", home, SIGNATURE);
  373.       } else
  374. !         (void) strcpy(buf, p);
  375. !     wprint("Signing letter... ");
  376. !     } else
  377. !     wprint("Using alternate signature... ");
  378. !     fputc('\n', ed_fp), fflush(ed_fp);
  379. !     (void) fseek(ed_fp, 0L, 2); /* guarantee position at end of file */
  380. !     if (*buf == '$')
  381. !     if (!(p = do_set(set_options, buf)))
  382. !         wprint("(%s isn't set -- letter not signed)\n", buf);
  383.       else
  384. !         fprintf(ed_fp, "%s\n", p), wprint("\n"), fflush(ed_fp);
  385. !     else if (*buf == '\\')
  386. !     fprintf(ed_fp, "%s\n", buf+1), wprint("\n"), fflush(ed_fp);
  387. !     else
  388. !     file_to_fp(buf, ed_fp, "r");
  389.   
  390.       /* if fortune is set, check to see if fortunates is set. If so,
  391.        * check to see if all the recipient are on the fortunates list.
  392. --- 1363,1431 ----
  393.       buf[0] = 0;
  394.       while (isspace(*list))
  395.       list++;
  396. !     if (ison(flags, SIGN)) {
  397. !     if (p = do_set(set_options, "autosign2")) {
  398. !         if (!(signature = index(p, ':')))
  399. !         (void) strcpy(buf, p); /* No colon; use entire string as sig */
  400. !         else {
  401. !         int ret_val = 0;
  402. !         *signature = 0;
  403. !         /* p now points to a list of addresses and p2 points to the
  404. !          * signature format to use. Check that each address contains
  405. !          * the stuff in alternate sign.
  406. !          */
  407. !         skipspaces(0);
  408. !         if (!*p)
  409. !             /* autosign2 = " : <signature>"  send to all recipients */
  410. !             ret_val = 1;
  411. !         else if (p = alias_to_address(p)) {
  412. !             rm_cmts_in_addr(p);
  413. !             for (addr = list;;) {
  414. !             char c;
  415. !             if (p2 = any(addr, ", ")) {
  416. !                 c = *p2;
  417. !                 *p2 = 0;
  418. !             }
  419. !             ret_val = chk_two_lists(addr, p, ", ");
  420. !             if (p2)
  421. !                 for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
  422. !                 ;
  423. !             if (!ret_val || !(addr = p2))
  424. !                 break;
  425.               }
  426.           }
  427. +         *signature++ = ':'; /* must reset first! */
  428. +         if (ret_val) {
  429. +             while (isspace(*signature))
  430. +             signature++;
  431. +             if (!*strcpy(buf, signature))
  432. +             return;
  433. +         }
  434.           }
  435.       }
  436. !     if (!buf[0]) {
  437. !         if (!(p = do_set(set_options, "autosign")) || !*p) {
  438. !         char *home;
  439. !         if (!(home = do_set(set_options, "home")) || !*home)
  440. !             home = ALTERNATE_HOME;
  441. !         (void) sprintf(buf, "%s/%s", home, SIGNATURE);
  442. !         } else
  443. !         (void) strcpy(buf, p);
  444. !         wprint("Signing letter... ");
  445.       } else
  446. !         wprint("Using alternate signature... ");
  447. !     fputs("\n-- \n", ed_fp), fflush(ed_fp);
  448. !     (void) fseek(ed_fp, 0L, 2); /* guarantee position at end of file */
  449. !     if (*buf == '$')
  450. !         if (!(p = do_set(set_options, buf)))
  451. !         wprint("(%s isn't set -- letter not signed)\n", buf);
  452. !         else
  453. !         fprintf(ed_fp, "%s\n", p), wprint("\n"), fflush(ed_fp);
  454. !     else if (*buf == '\\')
  455. !         fprintf(ed_fp, "%s\n", buf+1), wprint("\n"), fflush(ed_fp);
  456.       else
  457. !         file_to_fp(buf, ed_fp, "r");
  458. !     }
  459.   
  460.       /* if fortune is set, check to see if fortunates is set. If so,
  461.        * check to see if all the recipient are on the fortunates list.
  462. *** OLD/main.c    Thu Apr  7 22:47:31 1988
  463. --- main.c    Thu May 12 17:14:16 1988
  464. ***************
  465. *** 25,32 ****
  466.   char **argv;
  467.   {
  468.       u_long         flg = NO_FLG;
  469. !     int            n, source_rc = TRUE;
  470. !     char         f_flags[10], buf[256], *Cc = NULL, *Subj = NULL;
  471.       register char  *p;
  472.       char      **args;
  473.   
  474. --- 25,33 ----
  475.   char **argv;
  476.   {
  477.       u_long         flg = NO_FLG;
  478. !     int            n, source_rc = TRUE, src_n_exit;
  479. !     char         f_flags[10], buf[256];
  480. !     char       *Cc = NULL, *Subj = NULL, *src_file = NULL;
  481.       register char  *p;
  482.       char      **args;
  483.   
  484. ***************
  485. *** 93,98 ****
  486. --- 94,100 ----
  487.   #endif /* SUNTOOL */
  488.           case 'S' : turnon(glob_flags, DO_SHELL);
  489.           case 'f' :
  490. +         case 'F' :
  491.           case 'u' :
  492.               if (args[1])
  493.               args++;
  494. ***************
  495. *** 147,153 ****
  496.           else
  497.               turnon(glob_flags, PRE_CURSES);
  498.   #endif /* CURSES */
  499. !         when 'N':
  500.           (void) strcat(f_flags, "-N ");
  501.           when 'r':
  502.           (void) strcat(f_flags, "-r "); /* folder() argument */
  503. --- 149,160 ----
  504.           else
  505.               turnon(glob_flags, PRE_CURSES);
  506.   #endif /* CURSES */
  507. !         when 'F':
  508. !         src_n_exit = (argv[0][2] == '!');
  509. !         if (!(src_file = *++argv))
  510. !             puts("specify filename to source"), exit(1);
  511. !         /* fall thru! */
  512. !         case 'N':
  513.           (void) strcat(f_flags, "-N ");
  514.           when 'r':
  515.           (void) strcat(f_flags, "-r "); /* folder() argument */
  516. ***************
  517. *** 228,233 ****
  518. --- 235,241 ----
  519.       }
  520.   
  521.       if (source_rc) {
  522. +     /* use cmd_line() in case DEFAULT_RC has expandable chars */
  523.       (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  524.       (void) source(0, DUBL_NULL);
  525.       }
  526. ***************
  527. *** 322,328 ****
  528.       }
  529.   
  530.       /* find a free tmpfile */
  531. !     if (!(p = do_set(set_options, "home")) || !*p)
  532.   alted:
  533.       p = ALTERNATE_HOME;
  534.       flg = getpid();
  535. --- 330,337 ----
  536.       }
  537.   
  538.       /* find a free tmpfile */
  539. !     if (!(p = do_set(set_options, "tmpdir")) &&
  540. !     !(p = do_set(set_options, "home")))
  541.   alted:
  542.       p = ALTERNATE_HOME;
  543.       flg = getpid();
  544. ***************
  545. *** 348,354 ****
  546.       (void) signal(SIGQUIT, catch);
  547.       (void) signal(SIGHUP,  catch);
  548.   
  549. !     if (!hdrs_only && !istool && !do_set(set_options, "quiet"))
  550.       printf("%s: Type '?' for help.\n", VERSION);
  551.   
  552.       (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
  553. --- 357,364 ----
  554.       (void) signal(SIGQUIT, catch);
  555.       (void) signal(SIGHUP,  catch);
  556.   
  557. !     if (!hdrs_only && !istool && (!src_file || !src_n_exit) &&
  558. !     !do_set(set_options, "quiet"))
  559.       printf("%s: Type '?' for help.\n", VERSION);
  560.   
  561.       (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
  562. ***************
  563. *** 368,373 ****
  564. --- 378,392 ----
  565.       turnon(glob_flags, DO_SHELL);
  566.       if (istool && msg_cnt)
  567.       set_isread(current_msg);
  568. +     /* finally, if the user wanted to source a file to execute, do it now */
  569. +     if (src_file) {
  570. +     char *s_argv[2];
  571. +     s_argv[1] = src_file;
  572. +     (void) source(2, s_argv);
  573. +     if (!istool && src_n_exit)
  574. +         cleanup(0);
  575. +     }
  576.   
  577.   #ifdef SUNTOOL
  578.       if (istool) {
  579. *** OLD/makefile.bsd    Thu Apr  7 22:47:37 1988
  580. --- makefile.bsd    Wed May 11 15:53:44 1988
  581. ***************
  582. *** 7,13 ****
  583.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  584.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  585.         folders.o dates.o loop.o help.o viewopts.o curses.o curs_io.o bind.o
  586. ! HELP_FILES= README-6.0 README cmd_help mush.1
  587.   MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
  588.   
  589.   CFLAGS= -O -DCURSES -DBSD
  590. --- 7,15 ----
  591.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  592.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  593.         folders.o dates.o loop.o help.o viewopts.o curses.o curs_io.o bind.o
  594. ! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
  595.   MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
  596.   
  597.   CFLAGS= -O -DCURSES -DBSD
  598. *** OLD/makefile.sun    Thu Apr  7 22:47:40 1988
  599. --- makefile.sun    Wed May 11 15:53:25 1988
  600. ***************
  601. *** 17,23 ****
  602.   IMAGES= mail.icon.1 mail.icon.2 check.pr cycle.pr envelope.pr glasses.pr \
  603.       write.pr up.arrow.pr dn.arrow.pr coffee.cup.pr
  604.   
  605. ! HELP_FILES= README-6.0 README cmd_help tool_help mush.1
  606.   
  607.   MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.x286 makefile.x386
  608.   
  609. --- 17,23 ----
  610.   IMAGES= mail.icon.1 mail.icon.2 check.pr cycle.pr envelope.pr glasses.pr \
  611.       write.pr up.arrow.pr dn.arrow.pr coffee.cup.pr
  612.   
  613. ! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help tool_help
  614.   
  615.   MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.x286 makefile.x386
  616.   
  617. *** OLD/makefile.x286    Tue Apr 12 22:00:18 1988
  618. --- makefile.x286    Wed May 11 15:54:23 1988
  619. ***************
  620. *** 10,16 ****
  621.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  622.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  623.         folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
  624. ! DOCS= README cmd_help mush.1
  625.   MAKES= makefile.sys.v makefile.xenix makefile.bsd
  626.   
  627.   CFLAGS= -O -DSYSV -Mle -DCURSES -DREGCMP -DUSG
  628. --- 10,16 ----
  629.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  630.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  631.         folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
  632. ! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
  633.   MAKES= makefile.sys.v makefile.xenix makefile.bsd
  634.   
  635.   CFLAGS= -O -DSYSV -Mle -DCURSES -DREGCMP -DUSG
  636. ***************
  637. *** 28,34 ****
  638.       cc $(CFLAGS) -LARGE -c bind.c
  639.   
  640.   shar:
  641. !     shar ${DOCS} ${MAKES} ${HDRS}>hdr.shr
  642.       shar ${SRCS1} > src1.shr
  643.       shar ${SRCS2} > src2.shr
  644.       shar ${SRCS3} > src3.shr
  645. --- 28,34 ----
  646.       cc $(CFLAGS) -LARGE -c bind.c
  647.   
  648.   shar:
  649. !     shar ${HELP_FILES} ${MAKES} ${HDRS}>hdr.shr
  650.       shar ${SRCS1} > src1.shr
  651.       shar ${SRCS2} > src2.shr
  652.       shar ${SRCS3} > src3.shr
  653. ***************
  654. *** 39,45 ****
  655.       shar ${SRCS8} > src8.shr
  656.   
  657.   tar:
  658. !     tar fcv MUSH ${MAKES} ${HDRS} ${DOCS} ${SRCS1} \
  659.       ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS}8
  660.   
  661.   clean:
  662. --- 39,45 ----
  663.       shar ${SRCS8} > src8.shr
  664.   
  665.   tar:
  666. !     tar fcv MUSH ${MAKES} ${HDRS} ${HELP_FILES} ${SRCS1} \
  667.       ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS}8
  668.   
  669.   clean:
  670. *** OLD/makefile.x386    Tue Apr 12 21:59:57 1988
  671. --- makefile.x386    Wed May 11 15:54:42 1988
  672. ***************
  673. *** 10,16 ****
  674.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  675.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  676.         folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
  677. ! DOCS= README cmd_help mush.1
  678.   MAKES= makefile.sys.v makefile.xenix makefile.bsd
  679.   
  680.   CFLAGS= -O -DSYSV -M3e -DCURSES -DREGCMP -DUSG 
  681. --- 10,16 ----
  682.   OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  683.         signals.o aliases.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  684.         folders.o dates.o loop.o help.o viewopts.o bind.o curses.o curs_io.o
  685. ! HELP_FILES= README README-6.0 README-6.1 README-6.2 mush.1 cmd_help
  686.   MAKES= makefile.sys.v makefile.xenix makefile.bsd
  687.   
  688.   CFLAGS= -O -DSYSV -M3e -DCURSES -DREGCMP -DUSG 
  689. ***************
  690. *** 25,31 ****
  691.       cc $(CFLAGS) -LARGE -c bind.c
  692.   
  693.   shar:
  694. !     shar ${DOCS} ${MAKES} ${HDRS}>hdr.shr
  695.       shar ${SRCS1} > src1.shr
  696.       shar ${SRCS2} > src2.shr
  697.       shar ${SRCS3} > src3.shr
  698. --- 25,31 ----
  699.       cc $(CFLAGS) -LARGE -c bind.c
  700.   
  701.   shar:
  702. !     shar ${HELP_FILES} ${MAKES} ${HDRS}>hdr.shr
  703.       shar ${SRCS1} > src1.shr
  704.       shar ${SRCS2} > src2.shr
  705.       shar ${SRCS3} > src3.shr
  706. ***************
  707. *** 36,42 ****
  708.       shar ${SRCS8} > src8.shr
  709.   
  710.   tar:
  711. !     tar fcv MUSH ${MAKES} ${HDRS} ${DOCS} ${SRCS1} \
  712.       ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS8}
  713.   
  714.   clean:
  715. --- 36,42 ----
  716.       shar ${SRCS8} > src8.shr
  717.   
  718.   tar:
  719. !     tar fcv MUSH ${MAKES} ${HDRS} ${HELP_FILES} ${SRCS1} \
  720.       ${SRCS2} ${SRCS3} ${SRCS4} ${SRCS5} ${SRCS6} ${SRCS7} ${SRCS8}
  721.   
  722.   clean:
  723. *** OLD/misc.c    Thu Apr  7 22:47:54 1988
  724. --- misc.c    Wed May 11 14:01:36 1988
  725. ***************
  726. *** 354,363 ****
  727.       turnon(glob_flags, IGN_SIGS);
  728.       if (!buf)
  729.           pp = stdout;
  730. !     else if (!(pp = popen(buf, "w")))
  731. !         error(buf);
  732. !     else
  733.           echo_on();
  734.       cnt = 0;
  735.       } else if (!buf) {
  736.       if (pp && pp != stdout)
  737. --- 354,364 ----
  738.       turnon(glob_flags, IGN_SIGS);
  739.       if (!buf)
  740.           pp = stdout;
  741. !     else {
  742.           echo_on();
  743. +         if (!(pp = popen(buf, "w")))
  744. +         error(buf);
  745. +     }
  746.       cnt = 0;
  747.       } else if (!buf) {
  748.       if (pp && pp != stdout)
  749. *** OLD/mush.1    Wed Apr  6 00:34:07 1988
  750. --- mush.1    Thu May 12 17:08:32 1988
  751. ***************
  752. *** 60,65 ****
  753. --- 60,70 ----
  754.   .B \-f
  755.   [ folder ]
  756.   ]
  757. + [
  758. + .B \-F
  759. + [!]
  760. + [ file ]
  761. + ]
  762.   .br
  763.   .B mush
  764.   [
  765. ***************
  766. *** 126,131 ****
  767. --- 131,140 ----
  768.   .B \-f
  769.   [ folder ]
  770.   ]
  771. + [
  772. + .B \-F
  773. + [ file ]
  774. + ]
  775.   .br
  776.   .B mush
  777.   [
  778. ***************
  779. *** 218,223 ****
  780. --- 227,244 ----
  781.   .B debug
  782.   command.
  783.   .TP
  784. + \-F[!] filename
  785. + This file is the same type as the initialization file read on startup
  786. + (see INITIALIZATION) with the exception that commands which manipulate
  787. + or search messages may be given.  Normally, such commands may not exist
  788. + in the initialization file since that file is read before the folder
  789. + is scanned.  This file is read after the folder is scanned, so commands
  790. + which change folders are allowed.
  791. + The optional `!' argument prevents the shell from running after the file
  792. + has been sourced.  Otherwise,
  793. + .I Mush
  794. + continues into whatever interface has been specified.
  795. + .TP
  796.   \-f [ filename ]
  797.   The optional filename argument specifies a folder containing mail messages.
  798.   With no argument,
  799. ***************
  800. *** 2069,2091 ****
  801.   Options:
  802.   .ta 1.5i
  803.   .in +2
  804. ! \-d [\-]date    messages sent on or after [`\-' before] date
  805. ! \-f    search for pattern in \*QFrom\*U field only
  806. ! \-h header    search for pattern in specified header only
  807. ! \-i    ignore case of letters when searching
  808. ! \-r msg_list    search only the listed messages
  809. ! \-s    search for pattern in \*QSubject\*U field only
  810. ! \-t    search for pattern in \*QTo\*U field only
  811. ! \-x    select messages not containing the pattern
  812.   .in -2
  813.   .fi
  814.   .sp
  815. ! Only one of \-d, \-f, \-h, \-s and \-t can be specified at once.
  816.   Entire messages are scanned for the <pattern>
  817. ! unless \-f, \-h, \-s or \-t is specified.
  818.   Messages marked for deletion are also searched.
  819. ! No patterns can be specified with the \-d option,
  820. ! and the \-x option may not be used with \-d.
  821.   .sp
  822.   For the \-d option, \*Qdate\*U is of the form:
  823.   .sp
  824. --- 2090,2112 ----
  825.   Options:
  826.   .ta 1.5i
  827.   .in +2
  828. ! \-d [+-]date    messages sent on or [+ after] [`\-' before] date.
  829. ! \-ago <format>    search for messages relative to today's date.
  830. ! \-f    search for pattern in \*QFrom\*U field only.
  831. ! \-i    ignore case of letters when searching.
  832. ! \-r msg_list    search only the listed messages.
  833. ! \-s    search for pattern in \*QSubject\*U field only.
  834. ! \-t    search for pattern in \*QTo\*U field only.
  835. ! \-h header    search for pattern in specified header only.
  836. ! \-x    select messages not containing the pattern.
  837.   .in -2
  838.   .fi
  839.   .sp
  840. ! Only one of \-d, \-a, \-f, \-h, \-s and \-t can be specified at once.
  841.   Entire messages are scanned for the <pattern>
  842. ! unless \-d, \-a, \-f, \-h, \-s or \-t is specified.
  843.   Messages marked for deletion are also searched.
  844. ! No patterns can be specified with the \-d or \-a options.
  845.   .sp
  846.   For the \-d option, \*Qdate\*U is of the form:
  847.   .sp
  848. ***************
  849. *** 2100,2108 ****
  850.   .in +2
  851.   .ta 2.0i
  852.   .sp
  853. ! pick \-d 4/20    on or after April 20, this year
  854. ! pick \-d \-/2/85    on or before the 2nd, this month, 1985
  855. ! pick \-d /    today only
  856.   .fi
  857.   .in -2
  858.   .sp
  859. --- 2121,2130 ----
  860.   .in +2
  861.   .ta 2.0i
  862.   .sp
  863. ! pick \-d 4/20    on April 20, this year.
  864. ! pick \-d \-/2/85    on or before the 2nd, this month, 1985.
  865. ! pick \-d +5/4    on or after May 4 of this year.
  866. ! pick \-d /    today only.
  867.   .fi
  868.   .in -2
  869.   .sp
  870. ***************
  871. *** 2109,2114 ****
  872. --- 2131,2159 ----
  873.   At least one `/' char must be used in a date.
  874.   There is no strong date checking; 2/30 would be considered a valid date.
  875.   .sp
  876. + For the \-ago option, the format is very simple.  Specify the number of
  877. + days followed by the word \*Qdays\*U, or the number of weeks followed by
  878. + the word \*Qweeks\*U, and so on with months and years.  Truncation is allowed,
  879. + since only the first character is examined, so all of the following are
  880. + equivalent:
  881. + .sp
  882. + .in +2
  883. + pick -ago 1 day, 2 weeks
  884. + pick -ago 2Weeks 1Day
  885. + pick -ago 2w,1day
  886. + pick -a 2w1d
  887. + .in -2
  888. + These examples will find all messages that are exactly 2 weeks and 1 day
  889. + old.  All \*Qago\*U dates collapse into \*Qday\*U time segments.  This
  890. + means that months are 30.5 days long.  If more precise date selection is
  891. + required, use the \-d option and specify specific dates.
  892. + .sp
  893. + Also note that the -ago option allows the \*Qbefore\*U (-) and \*Qafter\*U (+)
  894. + arguments.  Thus, you may pick for all messages older than 1 week with:
  895. + .sp
  896. + .ti +2
  897. + pick -ago -1 week
  898. + .sp
  899.   Other examples of
  900.   .B pick:
  901.   .sp
  902. ***************
  903. *** 2116,2127 ****
  904.   pick \-d 2/5/86 | pick \-d \-2/5/87 | pick \-s "mail stuff" | lpr
  905.   .sp
  906.   will find all the messages between the dates February 5, 1986 and
  907. ! February 5, 1987 that contain the subject "mail stuff" and print them.
  908.   .sp
  909.   .ti +2
  910.   pick -s Re: | delete
  911.   .sp
  912. ! deletes messages that have \*QRe:\*U in the subject
  913.   .sp
  914.   .ti +2
  915.   folder +project | pick -f frank
  916. --- 2161,2173 ----
  917.   pick \-d 2/5/86 | pick \-d \-2/5/87 | pick \-s "mail stuff" | lpr
  918.   .sp
  919.   will find all the messages between the dates February 5, 1986 and
  920. ! February 5, 1987 that contain the subject "mail stuff" and send them
  921. ! to the printer.
  922.   .sp
  923.   .ti +2
  924.   pick -s Re: | delete
  925.   .sp
  926. ! deletes messages that have \*QRe:\*U in the Subject header.
  927.   .sp
  928.   .ti +2
  929.   folder +project | pick -f frank
  930. ***************
  931. *** 2135,2140 ****
  932. --- 2181,2192 ----
  933.   if the string \*Qucbvax\*U is in the header.
  934.   Note that case sensitivity
  935.   applies only to the pattern searched, not the header itself.
  936. + .sp
  937. + .ti +2
  938. + pick -ago +1w | save +current
  939. + .sp
  940. + This finds all messages that are a week or less old and saves them in the file
  941. + called \fIcurrent\fR, which is found in the user's \fIfolder\fR variable.
  942.   .TP
  943.   .B preserve
  944.   .RB ( pre )
  945. ***************
  946. *** 3287,3292 ****
  947. --- 3339,3353 ----
  948.   (Boolean)
  949.   Whenever messages are read, piped, or saved, if this variable is set,
  950.   all consecutive blank lines are squeezed into one blank line.
  951. + .TP
  952. + .B tmpdir
  953. + (String)
  954. + This variable describes the path to use as the directory to use
  955. + for all tempfiles that
  956. + .I Mush
  957. + uses.  By default, the user's home directory is used.  If that
  958. + cannot be accessed, a directory writable by all is used (typically, /tmp).
  959. + If \fBtmpdir\fR is set, then it is used first.
  960.   .TP
  961.   .B toplines
  962.   (Numeric)
  963. *** OLD/mush.h    Thu May 12 13:52:11 1988
  964. --- mush.h    Wed May 11 15:19:26 1988
  965. ***************
  966. *** 1,6 ****
  967.   /* @(#)mush.h    (c) copyright 1986 (Dan Heller) */
  968.   
  969. ! #define VERSION "Mail User's Shell (6.1 4/26/88)"
  970.   
  971.   #include "config.h"
  972.   
  973. --- 1,6 ----
  974.   /* @(#)mush.h    (c) copyright 1986 (Dan Heller) */
  975.   
  976. ! #define VERSION "Mail User's Shell (6.2 5/11/88)"
  977.   
  978.   #include "config.h"
  979.   
  980. *** OLD/pick.c    Tue Mar  1 14:59:20 1988
  981. --- pick.c    Wed May 11 15:51:46 1988
  982. ***************
  983. *** 2,9 ****
  984.   
  985.   #include "mush.h"
  986.   
  987. ! static int before, mdy[3], search_from, search_subj, search_to, xflg, icase;
  988. ! static search_hdr[64];
  989.   
  990.   do_pick(n, argv, list)
  991.   register int n;
  992. --- 2,9 ----
  993.   
  994.   #include "mush.h"
  995.   
  996. ! static int before, after, search_from, search_subj, search_to, xflg, icase;
  997. ! static mdy[3], search_hdr[64];
  998.   
  999.   do_pick(n, argv, list)
  1000.   register int n;
  1001. ***************
  1002. *** 38,45 ****
  1003.   register char **argv, list[];
  1004.   {
  1005.       register char c;
  1006. !     int o_before = before, o_mdy[3], o_search_from = search_from,
  1007. !     o_search_subj = search_subj, o_search_to = search_to, o_xflg = xflg, n;
  1008.   
  1009.       for (c = 0; c < 3; c++)
  1010.       o_mdy[c] = mdy[c];
  1011. --- 38,46 ----
  1012.   register char **argv, list[];
  1013.   {
  1014.       register char c;
  1015. !     int o_before = before, o_after = after, o_search_from = search_from,
  1016. !     o_search_subj = search_subj, o_search_to = search_to, o_xflg = xflg,
  1017. !     o_mdy[3], n;
  1018.   
  1019.       for (c = 0; c < 3; c++)
  1020.       o_mdy[c] = mdy[c];
  1021. ***************
  1022. *** 50,56 ****
  1023.       goto bad;
  1024.       }
  1025.   
  1026. !     icase = before = search_from = search_subj = xflg = 0;
  1027.       mdy[0] = search_hdr[0] = 0;
  1028.       while (*argv && *++argv && **argv == '-')
  1029.       switch(c = argv[0][1]) {
  1030. --- 51,57 ----
  1031.       goto bad;
  1032.       }
  1033.   
  1034. !     icase = before = after = search_from = search_subj = xflg = 0;
  1035.       mdy[0] = search_hdr[0] = 0;
  1036.       while (*argv && *++argv && **argv == '-')
  1037.       switch(c = argv[0][1]) {
  1038. ***************
  1039. *** 76,81 ****
  1040. --- 77,88 ----
  1041.               goto bad;
  1042.           argv += (n-1); /* we're going to increment another up top */
  1043.           }
  1044. +         when 'a': {
  1045. +         int n = ago_date(++argv);
  1046. +         if (n == -1)
  1047. +             goto bad;
  1048. +         argv += n;
  1049. +         }
  1050.           when 'd':
  1051.           if (!*++argv) {
  1052.               print("specify a date for -%c\n", c);
  1053. ***************
  1054. *** 108,129 ****
  1055.       }
  1056.       if (verbose) {
  1057.       print_more("Searching for messages");
  1058. !     if (mdy[1] == 0)
  1059.           print(" that %s \"%s\"", (xflg)? "doesn't contain": "contains",
  1060.                   (*argv)? *argv: "<previous expression>");
  1061. !     if (search_subj)
  1062. !         print_more(" in subject line");
  1063. !     else if (search_from)
  1064. !         print_more(" from author names");
  1065. !     else if (search_to)
  1066. !         print_more(" from the To: field");
  1067. !     else if (search_hdr[0])
  1068. !         print_more(" from the message header: \"%s:\"", search_hdr);
  1069. !     if (mdy[1] > 0) {
  1070.           extern char *month_names[]; /* from dates.c */
  1071. !         print_more(" dated on or %s %s. %d, 19%d.",
  1072. !           (before)? "before": "after",
  1073. !           month_names[mdy[0]], mdy[1], mdy[2]);
  1074.       }
  1075.       print_more("\n");
  1076.       }
  1077. --- 115,138 ----
  1078.       }
  1079.       if (verbose) {
  1080.       print_more("Searching for messages");
  1081. !     if (mdy[1] == 0) {
  1082.           print(" that %s \"%s\"", (xflg)? "doesn't contain": "contains",
  1083.                   (*argv)? *argv: "<previous expression>");
  1084. !         if (search_subj)
  1085. !         print_more(" in subject line");
  1086. !         else if (search_from)
  1087. !         print_more(" from author names");
  1088. !         else if (search_to)
  1089. !         print_more(" from the To: field");
  1090. !         else if (search_hdr[0])
  1091. !         print_more(" from the message header: \"%s:\"", search_hdr);
  1092. !     } else {
  1093.           extern char *month_names[]; /* from dates.c */
  1094. !         print_more(" dated ");
  1095. !         if (before || after)
  1096. !         print_more("on or %s ", (before)? "before": "after");
  1097. !         print_more("%s. %d, 19%d.",
  1098. !               month_names[mdy[0]], mdy[1], mdy[2]);
  1099.       }
  1100.       print_more("\n");
  1101.       }
  1102. ***************
  1103. *** 131,137 ****
  1104.       print("using date: -i flag ignored.\n");
  1105.       ret = find_pattern(*argv, list);
  1106.   bad:
  1107. !     before = o_before, search_from = o_search_from;
  1108.       search_subj = o_search_subj, search_to = o_search_to, xflg = o_xflg;
  1109.       for (c = 0; c < 3; c++)
  1110.       mdy[c] = o_mdy[c];
  1111. --- 140,146 ----
  1112.       print("using date: -i flag ignored.\n");
  1113.       ret = find_pattern(*argv, list);
  1114.   bad:
  1115. !     before = o_before, after = o_after, search_from = o_search_from;
  1116.       search_subj = o_search_subj, search_to = o_search_to, xflg = o_xflg;
  1117.       for (c = 0; c < 3; c++)
  1118.       mdy[c] = o_mdy[c];
  1119. ***************
  1120. *** 197,204 ****
  1121.            */
  1122.           for (i = 2; i < 5; i++)
  1123.               if (before && msg_mdy[i%3] < mdy[i%3]
  1124. !             || !before && msg_mdy[i%3] > mdy[i%3]
  1125. !             || i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
  1126.                   Debug("matched (%s).\n",
  1127.                   (i == 2)? "year" : (i == 3)? "month" : "day");
  1128.                   break;
  1129. --- 206,213 ----
  1130.            */
  1131.           for (i = 2; i < 5; i++)
  1132.               if (before && msg_mdy[i%3] < mdy[i%3]
  1133. !             ||  after  && msg_mdy[i%3] > mdy[i%3]
  1134. !             ||  i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
  1135.                   Debug("matched (%s).\n",
  1136.                   (i == 2)? "year" : (i == 3)? "month" : "day");
  1137.                   break;
  1138. ***************
  1139. *** 373,380 ****
  1140.       int       i;
  1141.       struct tm       *today;
  1142.   
  1143. !     if (*p == '-') {
  1144. !     before = 1;
  1145.       skipspaces(1);
  1146.       }
  1147.       if (!isdigit(*p) && *p != '/') {
  1148. --- 382,389 ----
  1149.       int       i;
  1150.       struct tm       *today;
  1151.   
  1152. !     if (*p == '-' || *p == '+') {
  1153. !     before = !(after = *p == '+');
  1154.       skipspaces(1);
  1155.       }
  1156.       if (!isdigit(*p) && *p != '/') {
  1157. ***************
  1158. *** 406,409 ****
  1159. --- 415,484 ----
  1160.           p++;
  1161.       }
  1162.       return 1;
  1163. + }
  1164. + /*
  1165. +  * Parse arguments specifying days/months/years "ago" (relative to today).
  1166. +  * Legal syntax: -ago [+-][args]
  1167. +  *    where "args" is defined to be:
  1168. +  *    [0-9]+[ ]*[dD][a-Z]*[ ,]*[0-9]+[mM][a-Z]*[ ,]*[0-9]+[ ]*[yY][a-Z]*
  1169. +  *    1 or more digits, 0 or more spaces, d or D followed by 0 or more chars,
  1170. +  *    0 or more whitespaces or commas, repeat for months and years...
  1171. +  * Examples:
  1172. +  *    1 day, 2 months, 0 years
  1173. +  *    2 weeks 1 year
  1174. +  *    10d, 5m
  1175. +  *    3w
  1176. +  *    1d 1Y
  1177. +  *
  1178. +  * Return number of args parsed; -1 on error.
  1179. +  */
  1180. + ago_date(argv)
  1181. + char **argv;
  1182. + {
  1183. + #define SECS_PER_DAY   (60 * 60 * 24)
  1184. + #define SECS_PER_WEEK  (SECS_PER_DAY * 7)
  1185. + #define SECS_PER_MONTH ((int)(SECS_PER_DAY * 30.5))
  1186. + #define SECS_PER_YEAR  (SECS_PER_DAY * 365)
  1187. +     register char *p;
  1188. +     char       buf[256];
  1189. +     int           n = 0, value, mdy_index = 0;
  1190. +     long       t;
  1191. +     struct tm       *today;
  1192. +     (void) argv_to_string(buf, argv);
  1193. +     p = buf;
  1194. +     (void) time (&t); /* get current time in seconds and subtract new values */
  1195. +     if (*p == '-')
  1196. +     before = TRUE;
  1197. +     else if (*p == '+')
  1198. +     after = TRUE;
  1199. +     skipspaces(before || after);
  1200. +     while (*p) {
  1201. +     if (!isdigit(*p))
  1202. +         break; /* really a syntax error, but it could be other pick ars */
  1203. +     p = my_atoi(p, &value); /* get 1 or more digits */
  1204. +     skipspaces(0); /* 0 or more spaces */
  1205. +     switch (lower(*p)) {   /* d, m, or y */
  1206. +         when 'd' : t -= value * SECS_PER_DAY;
  1207. +         when 'w' : t -= value * SECS_PER_WEEK;
  1208. +         when 'm' : t -= value * SECS_PER_MONTH;
  1209. +         when 'y' : t -= value * SECS_PER_YEAR;
  1210. +         otherwise: return -1;
  1211. +     }
  1212. +     for (p++; Lower(*p) >= 'a' && *p <= 'z'; p++)
  1213. +         ; /* skip the rest of this token */
  1214. +     while (*p == ',' || isspace(*p))
  1215. +         ; /* 0 or more whitespaces or commas */
  1216. +     }
  1217. +     today = localtime(&t);
  1218. +     mdy[0] = today->tm_mon;
  1219. +     mdy[1] = today->tm_mday;
  1220. +     mdy[2] = today->tm_year;
  1221. +     /* Count the number of args parsed */
  1222. +     for (n = 0; p > buf && *argv; n++)
  1223. +     p -= (strlen(*argv++)+1);
  1224. +     Debug("parsed %d args\n", n);
  1225. +     return n;
  1226.   }
  1227. *** OLD/print.c    Thu May 12 13:52:13 1988
  1228. --- print.c    Thu Apr 28 21:47:54 1988
  1229. ***************
  1230. *** 1,4 ****
  1231.   /* @(#)print.c    2.4    (c) copyright 10/15/86 (Dan Heller) */
  1232.   
  1233.   #include "mush.h"
  1234. --- 1,3 ----
  1235. ***************
  1236. *** 185,188 ****
  1237.   {
  1238.       print("");
  1239.   }
  1240. --- 184,186 ----
  1241. *** OLD/strings.c    Thu Apr  7 09:51:46 1988
  1242. --- strings.c    Tue Apr 26 19:01:20 1988
  1243. ***************
  1244. *** 219,229 ****
  1245.   }
  1246.   
  1247.   #ifdef SYSV
  1248.   char *
  1249. ! Sprintf(buf, fmt, args)
  1250.   register char *buf, *fmt;
  1251.   {
  1252. !     vsprintf(buf, fmt, &args);
  1253.       return buf;
  1254.   }
  1255.   #endif /* SYSV */
  1256. --- 219,247 ----
  1257.   }
  1258.   
  1259.   #ifdef SYSV
  1260. + #include <varargs.h>
  1261.   char *
  1262. ! Sprintf(buf, fmt, va_alist)
  1263.   register char *buf, *fmt;
  1264. + va_dcl
  1265.   {
  1266. !     va_list ap;
  1267. ! #ifdef VPRINTF
  1268. !     va_start(ap);
  1269. !     (void) vsprintf(buf, fmt, ap);
  1270. !     va_end(ap);
  1271. ! #else
  1272. !     {
  1273. !     FILE foo;
  1274. !     foo._cnt = BUFSIZ;
  1275. !     foo._base = foo._ptr = buf; /* may have to be cast (unsigned char *) */
  1276. !     foo._flag = _IOWRT+_IOSTRG;
  1277. !     va_start(ap);
  1278. !     (void) _doprnt(fmt, ap, &foo);
  1279. !     va_end(ap);
  1280. !     *foo._ptr = '\0'; /* plant terminating null character */
  1281. !     }
  1282. ! #endif /* VPRINTF */
  1283.       return buf;
  1284.   }
  1285.   #endif /* SYSV */
  1286. *** OLD/viewopts.c    Sat Apr  2 21:12:48 1988
  1287. --- viewopts.c    Wed May 11 20:48:41 1988
  1288. ***************
  1289. *** 129,134 ****
  1290. --- 129,136 ----
  1291.         "When reading messages, squeeze all blank lines into one." },
  1292.       { "top", "Lines", TOOL | TEXT,
  1293.         "Number of lines to print of a message for the 'top' command."  },
  1294. +     { "tmpdir", "Directory", TOOL | TEXT,
  1295. +       "Directory to use for temporary files used by Mush." },
  1296.       { "unix", NULL, TEXT,
  1297.         "Non-mush commands are considered to be UNIX commands." },
  1298.       { "verify", NULL, TEXT,
  1299.