home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume32 / mush / patch05b < prev    next >
Text File  |  1992-10-18  |  47KB  |  1,666 lines

  1. Newsgroups: comp.sources.misc
  2. From: bart@zigzag.z-code.com (Bart Schaefer)
  3. Subject:  v32i102:  mush - Mail User's Shell, Patch05b/3
  4. Message-ID: <1992Oct16.141335.6872@sparky.imd.sterling.com>
  5. X-Md4-Signature: 887782b73a72f6f74abd4268fff88cc2
  6. Date: Fri, 16 Oct 1992 14:13:35 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: bart@zigzag.z-code.com (Bart Schaefer)
  10. Posting-number: Volume 32, Issue 102
  11. Archive-name: mush/patch05b
  12. Environment: UNIX
  13. Patch-To: mush: Volume 18, Issue 58-79
  14.  
  15. This is Part 02 of Official Patch #5 for Mush 7.2.  To apply this patch,
  16. save this message to a file in your mush source directory and type:
  17.  
  18.     patch -N -p1 < file
  19.  
  20. See Part 01 for a description of the changes in this patch.  You can apply
  21. the two parts in any order, but you must apply both parts before applying
  22. the additional Apollo patches that are included in Part 01.
  23.  
  24. Prereq: "2/2/92"
  25. *** 7.2.4/version.h    Sun Feb  2 14:08:19 1992
  26. --- 7.2.5/version.h    Wed Oct 14 00:05:07 1992
  27. ***************
  28. *** 1,7 ****
  29.   /* @(#)version.h    (c) Copyright 1989, 1990, 1991 (Dan Heller) */
  30.   
  31.   #define MUSHNAME    "Mail User's Shell"
  32. ! #define RELEASE_DATE    "2/2/92"
  33.   #define RELEASE        7
  34.   #define REVISION    "2"
  35. ! #define PATCHLEVEL    4
  36. --- 1,7 ----
  37.   /* @(#)version.h    (c) Copyright 1989, 1990, 1991 (Dan Heller) */
  38.   
  39.   #define MUSHNAME    "Mail User's Shell"
  40. ! #define RELEASE_DATE    "10/14/92"
  41.   #define RELEASE        7
  42.   #define REVISION    "2"
  43. ! #define PATCHLEVEL    5
  44. *** 7.2.4/addrs.c    Wed Nov 13 00:53:20 1991
  45. --- 7.2.5/addrs.c    Sat Aug 22 11:46:57 1992
  46. ***************
  47. *** 188,194 ****
  48.   char *addr;
  49.   char *naddr;
  50.   {
  51. !     char *i, *r, *at;
  52.       char s[BUFSIZ], t[BUFSIZ];
  53.       int anglebrace = 0;
  54.   
  55. --- 188,194 ----
  56.   char *addr;
  57.   char *naddr;
  58.   {
  59. !     char *i, *r, *at = NULL;
  60.       char s[BUFSIZ], t[BUFSIZ];
  61.       int anglebrace = 0;
  62.   
  63. ***************
  64. *** 201,208 ****
  65.           return NULL;
  66.       /* Skip any leading double-quoted comment. */
  67.       if (*i == '"') {
  68. !         if ((i = index(i + 1, '"')) && (*i == '\0' || *(++i) == '\0'))
  69. !             return NULL;
  70.       }
  71.       /* Skip any more whitespace. */
  72.       while (*i && index(" \t", *i))
  73. --- 201,209 ----
  74.           return NULL;
  75.       /* Skip any leading double-quoted comment. */
  76.       if (*i == '"') {
  77. !         at = i;
  78. !         if (!(i = index(i + 1, '"')) || *(++i) == '\0')
  79. !         return NULL;
  80.       }
  81.       /* Skip any more whitespace. */
  82.       while (*i && index(" \t", *i))
  83. ***************
  84. *** 214,219 ****
  85. --- 215,222 ----
  86.           if (*(++i) == '\0')
  87.           return NULL;
  88.           ++anglebrace;
  89. +     } else if ((*i == '@' || *i == '!') && at) {
  90. +         i = at; /* The "comment" was actually a quoted token */
  91.       }
  92.       /*
  93.        * Look for a route.  A route is a comma-separated set of @-tagged
  94. ***************
  95. *** 713,719 ****
  96.           (void) strcpy(p2, login);
  97.           (void) reverse(tmp);
  98.           if (!lcase_strncmp(tmp, addr, (len = strlen(tmp))) &&
  99. !             (!addr[len] || addr[len] == '!')) {
  100.               Debug("\t%s\n", reverse(addr));
  101.               rm_me = TRUE;
  102.           }
  103. --- 716,723 ----
  104.           (void) strcpy(p2, login);
  105.           (void) reverse(tmp);
  106.           if (!lcase_strncmp(tmp, addr, (len = strlen(tmp))) &&
  107. !             (!addr[len] || addr[len] == '!' ||
  108. !             addr[len] == '.' && index(p2, '!'))) {
  109.               Debug("\t%s\n", reverse(addr));
  110.               rm_me = TRUE;
  111.           }
  112. ***************
  113. *** 930,936 ****
  114.           *p = '<';
  115.       }
  116.       if (!(p2 = index(p+1, '>'))) {
  117. !         wprint("Warning! Malformed address: \"%s\"\n", str);
  118.           return NULL;
  119.       }
  120.       if (addr) {
  121. --- 934,941 ----
  122.           *p = '<';
  123.       }
  124.       if (!(p2 = index(p+1, '>'))) {
  125. !         if (name || addr)
  126. !         wprint("Warning! Malformed address: \"%s\"\n", str);
  127.           return NULL;
  128.       }
  129.       if (addr) {
  130. ***************
  131. *** 956,962 ****
  132.               *name++ = p[1];
  133.           }
  134.           if (p_cnt) {
  135. !         wprint("Warning! Malformed name: \"%s\"\n", name);
  136.           return NULL;
  137.           }
  138.       }
  139. --- 961,968 ----
  140.               *name++ = p[1];
  141.           }
  142.           if (p_cnt) {
  143. !         if (name || addr)
  144. !             wprint("Warning! Malformed name: \"%s\"\n", name);
  145.           return NULL;
  146.           }
  147.       }
  148. ***************
  149. *** 986,993 ****
  150.       }
  151.       while (comment) {
  152.           if (c == '"' && !(p = index(p+1, '"')) ||
  153. !         c == '(' && !(p = any(p+1, "()"))) {
  154. !         wprint("Warning! Malformed address: \"%s\"\n", str);
  155.           return NULL;
  156.           }
  157.           if (*p == '(') /* loop again on parenthesis. quote ends loop */
  158. --- 992,1000 ----
  159.       }
  160.       while (comment) {
  161.           if (c == '"' && !(p = index(p+1, '"')) ||
  162. !             c == '(' && !(p = any(p+1, "()"))) {
  163. !         if (name || addr)
  164. !             wprint("Warning! Malformed address: \"%s\"\n", str);
  165.           return NULL;
  166.           }
  167.           if (*p == '(') /* loop again on parenthesis. quote ends loop */
  168. ***************
  169. *** 1001,1007 ****
  170.        */
  171.       if ((p2 = any(p+1, "<,")) && *p2 == '<') {
  172.           if (!(p = index(p2, '>'))) {
  173. !         wprint("Warning! Malformed address: \"%s\"\n", str);
  174.           return NULL;
  175.           }
  176.           if (addr = beg_addr) { /* reassign addr and compare to null */
  177. --- 1008,1015 ----
  178.        */
  179.       if ((p2 = any(p+1, "<,")) && *p2 == '<') {
  180.           if (!(p = index(p2, '>'))) {
  181. !         if (name || addr)
  182. !             wprint("Warning! Malformed address: \"%s\"\n", str);
  183.           return NULL;
  184.           }
  185.           if (addr = beg_addr) { /* reassign addr and compare to null */
  186. *** 7.2.4/bind.c    Sat Dec  7 16:51:57 1991
  187. --- 7.2.5/bind.c    Sat Aug 22 11:46:56 1992
  188. ***************
  189. *** 1,7 ****
  190.   /* bind.c */
  191.   
  192. - #include "bindings.h"
  193.   #include "mush.h"
  194.   
  195.   extern char *c_macro();
  196.   static un_bind();
  197. --- 1,7 ----
  198.   /* bind.c */
  199.   
  200.   #include "mush.h"
  201. + #include "bindings.h"
  202.   
  203.   extern char *c_macro();
  204.   static un_bind();
  205. *** 7.2.4/command2.c    Sun Dec 15 10:03:34 1991
  206. --- 7.2.5/command2.c    Sat Aug 22 11:46:58 1992
  207. ***************
  208. *** 145,150 ****
  209. --- 145,151 ----
  210.   int n;
  211.   char **argv;
  212.   {
  213. +     static int new;
  214.       char **envp, **last;
  215.   
  216.       if (n != 2 || !strcmp(argv[1], "-?"))
  217. ***************
  218. *** 152,157 ****
  219. --- 153,182 ----
  220.   
  221.       n = strlen(argv[1]);
  222.       for (last = environ; *last; last++);
  223. +     /* Allocate a copy of the environment so we can free() strings we unset */
  224. +     if (new == 0) {
  225. +     if (!(envp = (char **)calloc((last - environ) + 1, sizeof(char *)))) {
  226. +         error("Unsetenv: out of memory");
  227. +         return -1;
  228. +     }
  229. +     while (environ[new]) {
  230. +         envp[new] = savestr(environ[new]);
  231. +         if (!envp[new++]) {
  232. +         error("Unsetenv: out of memory");
  233. +         free_vec(envp);
  234. +         new = 0;
  235. +         return -1;
  236. +         }
  237. +     }
  238. +     environ = envp;
  239. +     last = &envp[new];
  240. +     new = 1;
  241. +     }
  242. +     if (last == environ) /* Empty environment? */
  243. +     return 0;
  244.       last--;
  245.   
  246.       for (envp = environ; envp <= last; envp++) {
  247. *** 7.2.4/commands.c    Wed Nov 13 01:25:17 1991
  248. --- 7.2.5/commands.c    Sat Aug 22 12:15:06 1992
  249. ***************
  250. *** 103,108 ****
  251. --- 103,111 ----
  252.       register char *p = x? *argv : NULL;
  253.       register long flg = 0;
  254.       extern FILE *ed_fp;
  255. + #ifdef SUNTOOL
  256. +     SIGRET (*oldint)(), (*oldquit)();
  257. + #endif /* SUNTOOL */
  258.   
  259.       if (x && *++argv && !strcmp(*argv, "-?"))
  260.       return help(0, "readmsg", cmd_help);
  261. ***************
  262. *** 169,186 ****
  263.       if (isoff(glob_flags, IS_PIPE))
  264.           set_msg_bit(list, current_msg);
  265.       }
  266.       current_msg = 0;
  267. !     for (x = 0; x < msg_cnt; x++)
  268.       if (msg_bit(list, x)) {
  269.           current_msg = x;
  270.   #ifdef SUNTOOL
  271.           if (istool > 1) {
  272.           read_mail(NO_ITEM, 0, NO_EVENT);
  273. !         return 0;
  274.           }
  275.   #endif /* SUNTOOL */
  276.           display_msg(x, flg);
  277.       }
  278.       return 0;
  279.   }
  280.   
  281. --- 172,200 ----
  282.       if (isoff(glob_flags, IS_PIPE))
  283.           set_msg_bit(list, current_msg);
  284.       }
  285. + #ifdef SUNTOOL
  286. +     if (istool > 1)
  287. +     on_intr();
  288. + #endif /* SUNTOOL */
  289.       current_msg = 0;
  290. !     for (x = 0; x < msg_cnt && isoff(glob_flags, WAS_INTR); x++)
  291.       if (msg_bit(list, x)) {
  292. +         if (current_msg > 0 && istool > 1 && isoff(flg, NO_PAGE) &&
  293. +             c_more("Type RETURN for next message, q to quit:") == 'q')
  294. +         break;
  295.           current_msg = x;
  296.   #ifdef SUNTOOL
  297.           if (istool > 1) {
  298.           read_mail(NO_ITEM, 0, NO_EVENT);
  299. !         break;
  300.           }
  301.   #endif /* SUNTOOL */
  302.           display_msg(x, flg);
  303.       }
  304. + #ifdef SUNTOOL
  305. +     if (istool > 1)
  306. +     off_intr();
  307. + #endif /* SUNTOOL */
  308.       return 0;
  309.   }
  310.   
  311. *** 7.2.4/config.h-dist    Sun Feb  2 14:03:44 1992
  312. --- 7.2.5/config.h-dist    Sat Aug 22 11:46:46 1992
  313. ***************
  314. *** 74,79 ****
  315. --- 74,89 ----
  316.   /* mail delivery system macros and defines... */
  317.   
  318.   /*
  319. +  * For POP3_SUPPORT, define this.  Mush will act as a POP-3 client,
  320. +  * periodically calling the server on the machine described by the
  321. +  * environment variable MAILHOST to pick up new mail.
  322. +  */
  323. + /* #define POP3_SUPPORT /**/
  324. + #ifdef POP3_SUPPORT
  325. + #define HOMEMAIL
  326. + #endif /* POP3_SUPPORT */
  327. + /*
  328.    * If you are using MMDF, define MMDF here.
  329.    */
  330.   /* #define MMDF /**/
  331. *** 7.2.4/curs_io.c    Thu May 16 18:28:43 1991
  332. --- 7.2.5/curs_io.c    Sun Sep 20 14:14:37 1992
  333. ***************
  334. *** 33,41 ****
  335.   
  336.   tty_settings()
  337.   {
  338. !     savetty();
  339.   
  340. ! #ifdef SYSV
  341.       eofc = _tty.c_cc[VEOF];
  342.   #else
  343.   #ifdef BSD
  344. --- 33,44 ----
  345.   
  346.   tty_settings()
  347.   {
  348. !     int is_tty = isatty(0);
  349.   
  350. !     if (is_tty)
  351. !     savetty();
  352. ! #if defined(SYSV) || defined(AIX)
  353.       eofc = _tty.c_cc[VEOF];
  354.   #else
  355.   #ifdef BSD
  356. ***************
  357. *** 46,52 ****
  358.       eofc = CTRL('D');
  359.   #endif /* SYSV */
  360.   
  361. !     if (!isatty(0)) {
  362.       del_line = CTRL('U');
  363.       del_char = CTRL('H');
  364.       } else {
  365. --- 49,55 ----
  366.       eofc = CTRL('D');
  367.   #endif /* SYSV */
  368.   
  369. !     if (!is_tty) {
  370.       del_line = CTRL('U');
  371.       del_char = CTRL('H');
  372.       } else {
  373. ***************
  374. *** 55,60 ****
  375. --- 58,64 ----
  376.       }
  377.   
  378.   #ifdef TIOCGLTC
  379. + #ifndef AIX    /* Just in case */
  380.   #ifndef AUX    /* AUX defines TIOCGLTC but doesn't use it */
  381.       if (ioctl(0, TIOCGLTC, <chars) != -1) {
  382.       del_word = ltchars.t_werasc;
  383. ***************
  384. *** 62,67 ****
  385. --- 66,72 ----
  386.       lit_next = ltchars.t_lnextc;
  387.       } else
  388.   #endif /* AUX */
  389. + #endif /* AIX */
  390.   #endif /* TIOCGLTC */
  391.       {
  392.       del_word = CTRL('W');
  393. *** 7.2.4/curses.c    Tue Mar  3 10:46:01 1992
  394. --- 7.2.5/curses.c    Sat Aug 22 11:46:55 1992
  395. ***************
  396. *** 1,9 ****
  397.   /* @(#)curses.c    (c) copyright 3/18/87 (Dan Heller) */
  398.   
  399.   /* curses.c -- routine to deal with the curses interface */
  400. - #ifdef CURSES
  401.   
  402.   #include "mush.h"
  403.   #include "bindings.h"
  404.   
  405.   curses_init(argc, argv)
  406. --- 1,9 ----
  407.   /* @(#)curses.c    (c) copyright 3/18/87 (Dan Heller) */
  408.   
  409.   /* curses.c -- routine to deal with the curses interface */
  410.   
  411.   #include "mush.h"
  412. + #ifdef CURSES
  413.   #include "bindings.h"
  414.   
  415.   curses_init(argc, argv)
  416. ***************
  417. *** 804,809 ****
  418. --- 804,810 ----
  419.   scrn_line(line, buf)
  420.   char *buf;
  421.   {
  422. + #ifndef AIX
  423.   #ifndef A_CHARTEXT
  424.       (void) strncpy(buf, stdscr->_y[line], COLS-1);
  425.       buf[COLS-1] = 0; /* strncpy does not null terminate */
  426. ***************
  427. *** 815,820 ****
  428. --- 816,824 ----
  429.           break;
  430.       buf[n] = '\0';
  431.   #endif /* A_CHARTEXT */
  432. + #else /* AIX */
  433. +     (void) strncpy(buf, compose_hdr(n_array[line-1]), COLS - 1);
  434. + #endif /* AIX */
  435.   }
  436.   
  437.   /*
  438. *** 7.2.4/file.c    Thu Jan 30 20:50:48 1992
  439. --- 7.2.5/file.c    Sat Aug 22 11:46:56 1992
  440. ***************
  441. *** 402,412 ****
  442.       c = *p, *p = 0;
  443.       /* See if it's a file.  This doesn't get written back
  444.        * onto "buf" since it is supposed to be extracted anyway.
  445. !      * The check for '@' in names beginning with '/' is to
  446.        * avoid mis-identifying X.400 addresses as file names.
  447.        */
  448.       if (force || *file == '+' || *file == '~' ||
  449. !         *file == '|' || *file == '/' && !index(file, '@')) {
  450.           int isdir;
  451.           /* open either "file" or &file[1] */
  452.           if (*file == '|') {
  453. --- 402,414 ----
  454.       c = *p, *p = 0;
  455.       /* See if it's a file.  This doesn't get written back
  456.        * onto "buf" since it is supposed to be extracted anyway.
  457. !      * The check for '=' in names beginning with '/' is to
  458.        * avoid mis-identifying X.400 addresses as file names.
  459. +      *
  460. +      * \052 is a * for broken compilers that would do a comment.
  461.        */
  462.       if (force || *file == '+' || *file == '~' ||
  463. !         *file == '|' || *file == '/' && !glob(file, "/?*=*?/\052")) {
  464.           int isdir;
  465.           /* open either "file" or &file[1] */
  466.           if (*file == '|') {
  467. *** 7.2.4/hdrs.c    Wed Nov 13 01:27:59 1991
  468. --- 7.2.5/hdrs.c    Sat Aug 22 11:46:49 1992
  469. ***************
  470. *** 614,622 ****
  471.   reply_to(n, all, buf)
  472.   char buf[];
  473.   {
  474. !     register char *p = NULL, *p2, *b = buf, *field;
  475.       char line[256], name[256], addr[256], *unscramble_addr();
  476.   
  477.       if (field = do_set(set_options, "reply_to_hdr")) {
  478.   #ifndef MSG_SEPARATOR
  479.       if (!*field)
  480. --- 614,624 ----
  481.   reply_to(n, all, buf)
  482.   char buf[];
  483.   {
  484. !     register char *p = NULL, *p2 = NULL, *b = buf, *field;
  485.       char line[256], name[256], addr[256], *unscramble_addr();
  486.   
  487. +     name[0] = addr[0] = '\0';
  488.       if (field = do_set(set_options, "reply_to_hdr")) {
  489.   #ifndef MSG_SEPARATOR
  490.       if (!*field)
  491. ***************
  492. *** 643,666 ****
  493.       }
  494.       if (p || (!p && ((p = header_field(n, field = "reply-to")) ||
  495.               (p = header_field(n, field = "from")) ||
  496. !             (p = header_field(n, field = "return-path")))))
  497.       skipspaces(0);
  498. !     else if (!p) {
  499. ! #ifndef MSG_SEPARATOR
  500.   DoFrom:
  501.       field = "from_";
  502.       /* if all else fails, then get the first token in "From" line */
  503.       if (p2 = msg_get(n, line, sizeof line))
  504.           p = index(p2, ' ');
  505. !     else
  506.           return "";
  507.       skipspaces(1);
  508. !     if (p2 = index(p, ' '))
  509.           *p2 = 0;
  510. !     (void) unscramble_addr(p, line); /* p is safely recopied to line */
  511. !     p = line;
  512.   #else /* MSG_SEPARATOR */
  513.       wprint("Warning: unable to find who msg %d is from!\n", n+1);
  514.   #endif /* MSG_SEPARATOR */
  515.       }
  516.       (void) get_name_n_addr(p, name, addr);
  517. --- 645,683 ----
  518.       }
  519.       if (p || (!p && ((p = header_field(n, field = "reply-to")) ||
  520.               (p = header_field(n, field = "from")) ||
  521. !             (p = header_field(n, field = "return-path"))))) {
  522.       skipspaces(0);
  523. !     } else if (!p) {
  524.   DoFrom:
  525.       field = "from_";
  526. + #ifndef MSG_SEPARATOR
  527.       /* if all else fails, then get the first token in "From" line */
  528.       if (p2 = msg_get(n, line, sizeof line))
  529.           p = index(p2, ' ');
  530. !     if (!p2 || !p)
  531.           return "";
  532.       skipspaces(1);
  533. !     /* Extra work to handle quoted tokens */
  534. !     while (p2 = any(p, "\" ")) {
  535. !         if (*p2 == '"') {
  536. !         if (p2 = index(p2 + 1, '"'))
  537. !             p2++;
  538. !         else
  539. !             return "";
  540. !         } else
  541. !         break;
  542. !     }
  543. !     if (p2)
  544.           *p2 = 0;
  545. !     if (!unscramble_addr(p, line)) { /* p is safely recopied to line */
  546. !         p2 = addr;
  547. !         goto BrokenFrom;
  548. !     } else
  549. !         p2 = NULL;
  550.   #else /* MSG_SEPARATOR */
  551.       wprint("Warning: unable to find who msg %d is from!\n", n+1);
  552. +     p2 = addr;
  553. +     goto BrokenFrom;
  554.   #endif /* MSG_SEPARATOR */
  555.       }
  556.       (void) get_name_n_addr(p, name, addr);
  557. ***************
  558. *** 675,685 ****
  559.        * Check Resent-From: if the address came from the from_ line, else
  560.        * check From:, and finally Sender: or Name:.
  561.        */
  562.       if (!lcase_strncmp(field, "from_", -1) &&
  563.           (p = header_field(n, "resent-from")) ||
  564.               (p = header_field(n, "from")) ||
  565. !             (p = header_field(n, "sender")))
  566. !         (void) get_name_n_addr(p, name, NULL);
  567.       if (!name[0] && (p = header_field(n, "name")))
  568.           (void) strcpy(name, p);
  569.       if (name[0]) {
  570. --- 692,705 ----
  571.        * Check Resent-From: if the address came from the from_ line, else
  572.        * check From:, and finally Sender: or Name:.
  573.        */
  574. + BrokenFrom:
  575.       if (!lcase_strncmp(field, "from_", -1) &&
  576.           (p = header_field(n, "resent-from")) ||
  577.               (p = header_field(n, "from")) ||
  578. !             (p = header_field(n, "sender"))) {
  579. !         /* p2 is either NULL or addr (BrokenFrom) */
  580. !         (void) get_name_n_addr(p, name, p2);
  581. !     }
  582.       if (!name[0] && (p = header_field(n, "name")))
  583.           (void) strcpy(name, p);
  584.       if (name[0]) {
  585. ***************
  586. *** 743,752 ****
  587.       if (!*p)
  588.       if (p2) /* take_me_off() was not done */
  589.           (void) strcpy(buf, login);
  590. !     else if (index(name, '"'))
  591. !         (void) sprintf(buf, "<%s> (%s)", addr, name);
  592. !     else
  593. !         (void) sprintf(buf, "\"%s\" <%s>", name, addr);
  594.       return buf;
  595.   }
  596.   
  597. --- 763,776 ----
  598.       if (!*p)
  599.       if (p2) /* take_me_off() was not done */
  600.           (void) strcpy(buf, login);
  601. !     else {
  602. !         if (!*name)
  603. !         (void) sprintf(buf, "<%s>", addr);
  604. !         else if (index(name, '"'))
  605. !         (void) sprintf(buf, "<%s> (%s)", addr, name);
  606. !         else
  607. !         (void) sprintf(buf, "\"%s\" <%s>", name, addr);
  608. !     }
  609.       return buf;
  610.   }
  611.   
  612. *** 7.2.4/init.c    Thu Jan 30 00:14:42 1992
  613. --- 7.2.5/init.c    Sat Aug 22 13:36:35 1992
  614. ***************
  615. *** 73,94 ****
  616.       (void) add_option(&set_options, argv);
  617.       }
  618.   
  619.   #ifdef HOMEMAIL
  620.       strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
  621.   #else /* HOMEMAIL */
  622.       if ((p = getenv("MAIL")) && *p)
  623.       strdup(spoolfile, p);
  624.       else
  625.       strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  626.   #endif /* HOMEMAIL */
  627.       mailfile = "";
  628.   
  629. -     if (realname && *buf) {
  630. -     /* realname has already been copied to buf */
  631. -     argv[0] = "realname";
  632. -     argv[2] = buf;
  633. -     (void) add_option(&set_options, argv);
  634. -     }
  635.       crt = 24;
  636.       screen = 18;
  637.       wrapcolumn = 0; /* Default is no wrap */
  638. --- 73,97 ----
  639.       (void) add_option(&set_options, argv);
  640.       }
  641.   
  642. +     if (realname && *buf) {
  643. +     /* realname has already been copied to buf */
  644. +     argv[0] = "realname";
  645. +     argv[2] = buf;
  646. +     (void) add_option(&set_options, argv);
  647. +     }
  648.   #ifdef HOMEMAIL
  649.       strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
  650.   #else /* HOMEMAIL */
  651. + #ifdef ENV_MAIL
  652.       if ((p = getenv("MAIL")) && *p)
  653.       strdup(spoolfile, p);
  654.       else
  655. + #endif /* ENV_MAIL */
  656.       strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  657.   #endif /* HOMEMAIL */
  658.       mailfile = "";
  659.   
  660.       crt = 24;
  661.       screen = 18;
  662.       wrapcolumn = 0; /* Default is no wrap */
  663. ***************
  664. *** 101,118 ****
  665.       if (ourname = (char **)calloc((unsigned)2, sizeof (char *)))
  666.           strdup(ourname[0], ourhost);
  667.       } else {
  668. !     int n = 0;
  669.       cnt = 2; /* 1 for ourhost and 1 for NULL terminator */
  670. !     for (p = hp->h_name; p && *p; p = hp->h_aliases[n++])
  671. !         if (strcmp(ourhost, p)) /* if host name is different */
  672. !         cnt++;
  673. !     if (ourname = (char **)calloc((unsigned)cnt, sizeof (char *))) {
  674. !         ourname[--cnt] = NULL;
  675. !         for (p = hp->h_name; p && *p && n >= 0; p = hp->h_aliases[--n])
  676. !         if (strcmp(ourhost, p)) /* if host name is different */
  677. !             ourname[--cnt] = savestr(p);
  678. !         strdup(ourname[0], ourhost); /* cnt better be 0! */
  679. !     }
  680.       }
  681.   #else
  682.   #ifdef SYSV
  683. --- 104,125 ----
  684.       if (ourname = (char **)calloc((unsigned)2, sizeof (char *)))
  685.           strdup(ourname[0], ourhost);
  686.       } else {
  687. !     int n = -1;
  688.       cnt = 2; /* 1 for ourhost and 1 for NULL terminator */
  689. !         for (p = hp->h_name; p && *p; p = hp->h_aliases[++n])
  690. !             if (strcmp(ourhost, p)) /* if host name is different */
  691. !                 cnt++;
  692. !         if (ourname = (char **)malloc((unsigned)cnt * sizeof (char *))) {
  693. !             n = -1;
  694. !             cnt = 0;
  695. !             ourname[cnt++] = savestr(ourhost);
  696. !             for (p = hp->h_name; p && *p; p = hp->h_aliases[++n])
  697. !                 if (strcmp(ourhost, p)) /* if host name is different */
  698. !                     ourname[cnt++] = savestr(p);
  699. !             ourname[cnt++] = NULL;
  700. !         }
  701.       }
  702.   #else
  703.   #ifdef SYSV
  704. *** 7.2.4/lock.c    Sun Feb  2 19:43:53 1992
  705. --- 7.2.5/lock.c    Sun Oct 11 18:14:56 1992
  706. ***************
  707. *** 32,39 ****
  708.    * permission on /usr/mail).  Instead, we need an external program that
  709.    * can be setgid, which mush then runs to create and remove lock files.
  710.    * Compiling this file with -DDOT_LOCK -DLOCK_PROG added to your CFLAGS
  711. !  * will generate such a program.
  712.    *
  713.    * For mush purposes, you should hardwire the DOLOCK_PATH to the full path
  714.    * name of the installed executable.  This helps prevent malicious users
  715.    * from substituting a different program.
  716. --- 32,41 ----
  717.    * permission on /usr/mail).  Instead, we need an external program that
  718.    * can be setgid, which mush then runs to create and remove lock files.
  719.    * Compiling this file with -DDOT_LOCK -DLOCK_PROG added to your CFLAGS
  720. !  * will generate such a program:
  721.    *
  722. +  *    cc -o dotlock -DDOT_LOCK -DLOCK_PROG lock.c xcreat.c
  723. +  *
  724.    * For mush purposes, you should hardwire the DOLOCK_PATH to the full path
  725.    * name of the installed executable.  This helps prevent malicious users
  726.    * from substituting a different program.
  727. ***************
  728. *** 129,135 ****
  729.       SIGRET (*oldint)(), (*oldquit)();
  730.   
  731.   #ifndef LOCK_PROG
  732. ! #ifdef SYSV
  733.       /* Only the spoolfile needs to be dot_locked -- other files are
  734.        * handled by lock_fopen, below.  To avoid collisions with 14-char
  735.        * file name limits, we allow dot_locking ONLY of the spoolfile.
  736. --- 131,137 ----
  737.       SIGRET (*oldint)(), (*oldquit)();
  738.   
  739.   #ifndef LOCK_PROG
  740. ! #if defined(SYSV) && !defined(HPUX) && !defined(IRIX4)
  741.       /* Only the spoolfile needs to be dot_locked -- other files are
  742.        * handled by lock_fopen, below.  To avoid collisions with 14-char
  743.        * file name limits, we allow dot_locking ONLY of the spoolfile.
  744. ***************
  745. *** 139,145 ****
  746.   #ifdef SVR2
  747.       return lock_proc(filename, DOLOCKIT);
  748.   #endif /* SVR2 */
  749. ! #endif /* SYSV */
  750.   #ifdef BSD
  751.       setregid(rgid, sgid);
  752.   #else /* BSD */
  753. --- 141,147 ----
  754.   #ifdef SVR2
  755.       return lock_proc(filename, DOLOCKIT);
  756.   #endif /* SVR2 */
  757. ! #endif /* SYSV && !HPUX && !IRIX4 */
  758.   #ifdef BSD
  759.       setregid(rgid, sgid);
  760.   #else /* BSD */
  761. ***************
  762. *** 152,158 ****
  763.       (void) sprintf(buf, "%s.lock", filename);
  764.   #endif /* M_XENIX */
  765.       on_intr();
  766. !     while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0444)) == -1) {
  767.       if (errno != EEXIST) {
  768.           error("unable to lock %s", filename);
  769.           break;
  770. --- 154,160 ----
  771.       (void) sprintf(buf, "%s.lock", filename);
  772.   #endif /* M_XENIX */
  773.       on_intr();
  774. !     while ((lockfd = xcreat(buf, 0444)) == -1) {
  775.       if (errno != EEXIST) {
  776.           error("unable to lock %s", filename);
  777.           break;
  778. ***************
  779. *** 208,214 ****
  780.           return 0;
  781.       (void) strcpy(buf, p);
  782.       }
  783. ! #ifdef SYSV
  784.       if (strncmp(spoolfile, buf, strlen(spoolfile)) != 0)
  785.       return 0;
  786.   #ifdef SVR2
  787. --- 210,216 ----
  788.           return 0;
  789.       (void) strcpy(buf, p);
  790.       }
  791. ! #if defined(SYSV)  && !defined(HPUX) && !defined(IRIX4)
  792.       if (strncmp(spoolfile, buf, strlen(spoolfile)) != 0)
  793.       return 0;
  794.   #ifdef SVR2
  795. ***************
  796. *** 216,222 ****
  797.       *p = 0;
  798.       return lock_proc(buf, UNLOCKIT);
  799.   #endif /* SVR2 */
  800. ! #endif /* SYSV */
  801.   #else /* LOCK_PROG */
  802.       errno = 0;
  803.   #endif /* !LOCK_PROG */
  804. --- 218,224 ----
  805.       *p = 0;
  806.       return lock_proc(buf, UNLOCKIT);
  807.   #endif /* SVR2 */
  808. ! #endif /* SYSV && !HPUX && !IRIX4 */
  809.   #else /* LOCK_PROG */
  810.       errno = 0;
  811.   #endif /* !LOCK_PROG */
  812. *** 7.2.4/loop.c    Wed Nov 13 09:58:26 1991
  813. --- 7.2.5/loop.c    Sat Aug 22 11:46:54 1992
  814. ***************
  815. *** 859,867 ****
  816.   
  817.       while (*str && b < sizeof buf - 1) {
  818.       if (*str == '~' && (str == start || isspace(*(str-1)))) {
  819. !         register char *p = any(str, " \t"), *tmp;
  820.           int x = 1;
  821. !         if (p)
  822.           *p = 0;
  823.           tmp = getpath(str, &x);
  824.           /* if error, print message and return 0 */
  825. --- 859,872 ----
  826.   
  827.       while (*str && b < sizeof buf - 1) {
  828.       if (*str == '~' && (str == start || isspace(*(str-1)))) {
  829. !         register char *p, *tmp;
  830.           int x = 1;
  831. !         /* Is it ever possible to have a user name start with tilde?
  832. !          * On the assumption it isn't, recur in case of ~$foo or ~/$foo
  833. !          */
  834. !         if (str[1] != '~' && variable_expand(&str[1]) == 0)
  835. !         return 0;
  836. !         if (p = any(str, " \t"))
  837.           *p = 0;
  838.           tmp = getpath(str, &x);
  839.           /* if error, print message and return 0 */
  840. ***************
  841. *** 869,880 ****
  842.           wprint("%s: %s\n", str, tmp);
  843.           return 0;
  844.           }
  845. !         b += Strcpy(buf+b, tmp);
  846. !         if (p)
  847. !         *p = ' ', str = p;
  848. !         else
  849. !         str += strlen(str);
  850.           expanded = 1;
  851.       }
  852.       /* if single-quotes, just copy byte by byte, char by char ... */
  853.       if ((buf[b] = *str++) == '\'' && !inquotes) {
  854. --- 874,888 ----
  855.           wprint("%s: %s\n", str, tmp);
  856.           return 0;
  857.           }
  858. !         /* Use strncat instead of strncpy to get \0 terminator */
  859. !         buf[b] = 0; /* Just in case */
  860. !         b += strlen(strncat(buf + b, tmp, sizeof buf - 1 - b));
  861. !         if (p && b < sizeof buf - 1) {
  862. !         *p = ' ';
  863. !         b += strlen(strncat(buf + b, p, sizeof buf - 1 - b));
  864. !         }
  865.           expanded = 1;
  866. +         break;
  867.       }
  868.       /* if single-quotes, just copy byte by byte, char by char ... */
  869.       if ((buf[b] = *str++) == '\'' && !inquotes) {
  870. ***************
  871. *** 895,908 ****
  872.           struct expand expansion;
  873.           expansion.orig = str - 1;
  874.           if (varexp(&expansion)) {
  875. !         b += Strcpy(&buf[b], expansion.exp);
  876.           xfree(expansion.exp);
  877.           str = expansion.rest;
  878.           expanded = 1;
  879.           } else
  880.           return 0;
  881. !     } else if (!inquotes && buf[b] == ';') {
  882. !         while (buf[++b] = *str++)
  883.           ;
  884.           b++;
  885.           break;
  886. --- 903,917 ----
  887.           struct expand expansion;
  888.           expansion.orig = str - 1;
  889.           if (varexp(&expansion)) {
  890. !         b += Strcpy(&buf[b],
  891. !                 quoteit(expansion.exp, inquotes? '"' : 0, FALSE));
  892.           xfree(expansion.exp);
  893.           str = expansion.rest;
  894.           expanded = 1;
  895.           } else
  896.           return 0;
  897. !     } else if (!inquotes && (buf[b] == ';' || buf[b] == '|')) {
  898. !         while ((buf[++b] = *str++) && b < sizeof buf - 2)
  899.           ;
  900.           b++;
  901.           break;
  902. *** 7.2.4/mail.c    Mon Mar  2 20:59:14 1992
  903. --- 7.2.5/mail.c    Sat Aug 22 11:46:48 1992
  904. ***************
  905. *** 1236,1246 ****
  906.       if (isoff(flags, VERBOSE) && debug < 3)
  907.       switch (fork_pid = fork()) {
  908.           case  0:  /* the child will send the letter. ignore signals */
  909. ! #if defined(SYSV) && !defined(AUX)
  910.           if (setpgrp() == -1)
  911. ! #else /* !SYSV || AUX */
  912.           if (setpgrp(0, getpid()) == -1)
  913. ! #endif /* SYSV && !AUX */
  914.               error("setpgrp");
  915.           /* NOTE: No special case needed for tool here because
  916.            * this is the sending child -- it's going to pclose()
  917. --- 1236,1246 ----
  918.       if (isoff(flags, VERBOSE) && debug < 3)
  919.       switch (fork_pid = fork()) {
  920.           case  0:  /* the child will send the letter. ignore signals */
  921. ! #if defined(SYSV) && !defined(AUX) && !defined(IRIX4)
  922.           if (setpgrp() == -1)
  923. ! #else /* !SYSV || AUX || IRIX4 */
  924.           if (setpgrp(0, getpid()) == -1)
  925. ! #endif /* SYSV && !AUX || IRIX4 */
  926.               error("setpgrp");
  927.           /* NOTE: No special case needed for tool here because
  928.            * this is the sending child -- it's going to pclose()
  929. *** 7.2.4/main.c    Wed Jan 29 23:34:31 1992
  930. --- 7.2.5/main.c    Mon Sep 21 10:32:25 1992
  931. ***************
  932. *** 71,76 ****
  933. --- 71,79 ----
  934.       /* check for any mail at all and exit if we're not continuing */
  935.       if (!n) {
  936.       struct stat statb;
  937. + #ifdef POP3_SUPPORT
  938. +     popgetmail(); /*Load mailbox with new mail, if any*/
  939. + #endif /* POP3_SUPPORT*/
  940.       if (stat(spoolfile, &statb) || statb.st_size == 0) {
  941.           (void) printf("No mail for %s.\n", login);
  942.           exit(0);
  943. ***************
  944. *** 200,206 ****
  945.       turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  946.   
  947.       if (ison(glob_flags, REDIRECT)
  948. !         && (!Flags.src_file || !Flags.src_n_exit)) {
  949.       puts("You can't redirect input unless you're sending mail.");
  950.       puts("If you want to run a shell with redirection, use \"-i\"");
  951.       cleanup(0);
  952. --- 203,209 ----
  953.       turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  954.   
  955.       if (ison(glob_flags, REDIRECT)
  956. !         && (!Flags.src_file || !Flags.src_n_exit) && !hdrs_only) {
  957.       puts("You can't redirect input unless you're sending mail.");
  958.       puts("If you want to run a shell with redirection, use \"-i\"");
  959.       cleanup(0);
  960. ***************
  961. *** 270,275 ****
  962. --- 273,279 ----
  963.       }
  964.   
  965.       if (hdrs_only) {
  966. +     (void) mail_status(0);
  967.       (void) sprintf(buf, "headers %s", hdrs_only);
  968.       if (argv = make_command(buf, TRPL_NULL, &argc))
  969.           (void) do_hdrs(argc, argv, NULL);
  970. ***************
  971. *** 287,298 ****
  972.           cleanup(0);
  973.       }
  974.   
  975.   #ifdef SUNTOOL
  976.       if (istool) {
  977.       char buf[16];
  978.       n = 0;
  979. !     if (time_out < 30)
  980. !         time_out = 30;
  981.       turnoff(glob_flags, IGN_SIGS);
  982.       (void) do_hdrs(0, DUBL_NULL, NULL);
  983.       timerclear(&(mail_timer.it_interval));
  984. --- 291,308 ----
  985.           cleanup(0);
  986.       }
  987.   
  988. + #ifdef POP3_SUPPORT
  989. +     if (time_out < MIN_TIME_OUT)
  990. +     time_out = MIN_TIME_OUT;
  991. + #endif /* POP3_SUPPORT */
  992.   #ifdef SUNTOOL
  993.       if (istool) {
  994.       char buf[16];
  995.       n = 0;
  996. ! #ifndef POP3_SUPPORT
  997. !     if (time_out < MIN_TIME_OUT)
  998. !         time_out = MIN_TIME_OUT;
  999. ! #endif /* POP3_SUPPORT */
  1000.       turnoff(glob_flags, IGN_SIGS);
  1001.       (void) do_hdrs(0, DUBL_NULL, NULL);
  1002.       timerclear(&(mail_timer.it_interval));
  1003. *** 7.2.4/misc.c    Fri Feb 14 07:51:54 1992
  1004. --- 7.2.5/misc.c    Sat Aug 22 11:46:47 1992
  1005. ***************
  1006. *** 413,418 ****
  1007. --- 413,419 ----
  1008.   char *buf;
  1009.   {
  1010.       static FILE *pp;
  1011. +     static SIGRET (*oldchld)();
  1012.       static int cnt, len;
  1013.       static u_long save_echo_flag;
  1014.   #ifdef SUNTOOL
  1015. ***************
  1016. *** 511,520 ****
  1017.           echo_on();
  1018.           if (!(pp = popen(buf, "w")))
  1019.           error(buf);
  1020.       }
  1021.       } else if (!buf) {
  1022. !     if (pp && pp != stdout)
  1023.           (void) pclose(pp);
  1024.       pp = NULL_FILE;
  1025.       if (save_echo_flag) {
  1026.           echo_on();
  1027. --- 512,525 ----
  1028.           echo_on();
  1029.           if (!(pp = popen(buf, "w")))
  1030.           error(buf);
  1031. +         else /* Don't reap popen()'s child */
  1032. +         oldchld = signal(SIGCHLD, SIG_DFL);
  1033.       }
  1034.       } else if (!buf) {
  1035. !     if (pp && pp != stdout) {
  1036.           (void) pclose(pp);
  1037. +         (void) signal(SIGCHLD, oldchld);
  1038. +     }
  1039.       pp = NULL_FILE;
  1040.       if (save_echo_flag) {
  1041.           echo_on();
  1042. *** 7.2.4/msgs.c    Sun Feb  2 13:59:14 1992
  1043. --- 7.2.5/msgs.c    Sat Aug 22 11:46:51 1992
  1044. ***************
  1045. *** 8,13 ****
  1046. --- 8,14 ----
  1047.   u_long flg;
  1048.   {
  1049.       char buf[32], *pager = NULL;
  1050. +     int intro = TRUE;
  1051.   
  1052.       if (ison(msg[n].m_flags, DELETE) && !do_set(set_options, "show_deleted")) {
  1053.       print("Message %d deleted; ", n+1);
  1054. ***************
  1055. *** 31,37 ****
  1056.   #ifdef MSG_SEPARATOR
  1057.       turnon(flg, NO_SEPARATOR);
  1058.   #endif /* MMDF */
  1059. !     if (!istool && isoff(flg, NO_PAGE) &&
  1060.           crt < msg[n].m_lines && isoff(flg, M_TOP)) {
  1061.       if (!(pager = do_set(set_options, "pager")))
  1062.           pager = DEF_PAGER;
  1063. --- 32,44 ----
  1064.   #ifdef MSG_SEPARATOR
  1065.       turnon(flg, NO_SEPARATOR);
  1066.   #endif /* MMDF */
  1067. !     if (ison(msg[n].m_flags, METAMAIL) && isoff(flg, NO_PAGE) &&
  1068. !         (pager = do_set(set_options, "metamail"))) {
  1069. !     intro = FALSE;
  1070. !     turnoff(flg, NO_HEADER);
  1071. !     turnoff(flg, M_TOP);
  1072. !     turnon(flg, NO_IGNORE);
  1073. !     } else if (!istool && isoff(flg, NO_PAGE) &&
  1074.           crt < msg[n].m_lines && isoff(flg, M_TOP)) {
  1075.       if (!(pager = do_set(set_options, "pager")))
  1076.           pager = DEF_PAGER;
  1077. ***************
  1078. *** 38,46 ****
  1079.       if (!*pager || !strcmp(pager, "internal"))
  1080.           pager = NULL; /* default to internal pager if pager set to "" */
  1081.       }
  1082. !     (void) do_pager(pager, TRUE); /* start pager */
  1083. !     (void) do_pager(sprintf(buf, "Message #%d (%d lines)\n",
  1084. !              n+1, msg[n].m_lines), FALSE);
  1085.       (void) copy_msg(n, NULL_FILE, flg, NULL);
  1086.       (void) do_pager(NULL, FALSE); /* end pager */
  1087.   }
  1088. --- 45,54 ----
  1089.       if (!*pager || !strcmp(pager, "internal"))
  1090.           pager = NULL; /* default to internal pager if pager set to "" */
  1091.       }
  1092. !     (void) do_pager(pager, intro? 1 : -1); /* start pager */
  1093. !     if (intro)
  1094. !     (void) do_pager(sprintf(buf, "Message #%d (%d lines)\n",
  1095. !                  n+1, msg[n].m_lines), FALSE);
  1096.       (void) copy_msg(n, NULL_FILE, flg, NULL);
  1097.       (void) do_pager(NULL, FALSE); /* end pager */
  1098.   }
  1099. ***************
  1100. *** 505,514 ****
  1101.        * bogus "new mail" messages from the shell.
  1102.        */
  1103.   #ifdef POSIX_UTIME
  1104. !     struct utimbuf times;
  1105.       (void) fflush(mail_fp); /* just in case */
  1106. !     times.modtime = time(×.actime) - 2;
  1107. !     times.ausec = times.modusec = 0;
  1108.   #else /* !POSIX_UTIME */
  1109.       long times[2];
  1110.       (void) fflush(mail_fp); /* just in case */
  1111. --- 513,522 ----
  1112.        * bogus "new mail" messages from the shell.
  1113.        */
  1114.   #ifdef POSIX_UTIME
  1115. !     struct utimbuf times[1];
  1116.       (void) fflush(mail_fp); /* just in case */
  1117. !     times[0].modtime = time(×[0].actime) - 2;
  1118. !     times[0].ausec = times[0].modusec = 0;
  1119.   #else /* !POSIX_UTIME */
  1120.       long times[2];
  1121.       (void) fflush(mail_fp); /* just in case */
  1122. ***************
  1123. *** 828,839 ****
  1124.   #ifndef MSG_SEPARATOR
  1125.       turnoff(glob_flags, WARNING);
  1126.       if (!strncmp(buf, "From ", 5)) {
  1127.           p = buf + 5;    /* skip "From " */
  1128.           skipspaces(0);
  1129. !         p = any(p, " \t");    /* skip the address */
  1130.       } else
  1131. !         p = buf;
  1132. !     if (p > buf && (p = parse_date(p + 1)) && strcpy(date, p))
  1133.   #else /* MSG_SEPARATOR */
  1134.       if (!strncmp(buf, MSG_SEPARATOR, strlen(MSG_SEPARATOR)))
  1135.   #endif /* MSG_SEPARATOR */
  1136. --- 836,852 ----
  1137.   #ifndef MSG_SEPARATOR
  1138.       turnoff(glob_flags, WARNING);
  1139.       if (!strncmp(buf, "From ", 5)) {
  1140. +         /* skip the address to find the date */
  1141.           p = buf + 5;    /* skip "From " */
  1142.           skipspaces(0);
  1143. !         if ((p = any(p, " \t")) && (p = parse_date(p + 1)) ||
  1144. !             /* Try once more the hard way */
  1145. !             (p = get_name_n_addr(buf + 5, NULL, NULL)) &&
  1146. !             (p = parse_date(p + 1)))
  1147. !         (void) strcpy(date, p);
  1148.       } else
  1149. !         p = NULL;
  1150. !     if (p)
  1151.   #else /* MSG_SEPARATOR */
  1152.       if (!strncmp(buf, MSG_SEPARATOR, strlen(MSG_SEPARATOR)))
  1153.   #endif /* MSG_SEPARATOR */
  1154. ***************
  1155. *** 897,905 ****
  1156.            */
  1157.           while (fgets(buf, sizeof (buf), fp) && (*buf != '\n')) {
  1158.               p = buf;
  1159.               if (!strncmp(buf, "Date:", 5))
  1160.               strdup(msg[cnt].m_date_sent, parse_date(p+5));
  1161. !             if (!strncmp(buf, "Priority:", 9)) {
  1162.               for (p += 9 ; *p != '\n'; p++) {
  1163.                   if (!isalpha(*p) || upper(*p) > 'A' + MAX_PRIORITY)
  1164.                   continue;
  1165. --- 910,935 ----
  1166.            */
  1167.           while (fgets(buf, sizeof (buf), fp) && (*buf != '\n')) {
  1168.               p = buf;
  1169. + #ifdef MMDF
  1170. +             /* MMDF might keep the From_ line, so check for it */
  1171. +             if (!msg[cnt].m_date_recv && !strncmp(buf, "From ", 5)) {
  1172. +             p = buf + 5;    /* skip "From " */
  1173. +             skipspaces(0);
  1174. +             if ((p = any(p, " \t")) && (p = parse_date(p + 1)) ||
  1175. +                 /* Try once more the hard way */
  1176. +                 (p = get_name_n_addr(buf + 5, NULL, NULL)) &&
  1177. +                 (p = parse_date(p + 1)))
  1178. +                 strdup(msg[cnt].m_date_recv, p);
  1179. +             } else
  1180. + #endif /* MMDF */
  1181.               if (!strncmp(buf, "Date:", 5))
  1182.               strdup(msg[cnt].m_date_sent, parse_date(p+5));
  1183. !             else if (!msg[cnt].m_date_sent &&
  1184. !                 !strncmp(buf, "Resent-Date:", 12))
  1185. !             msg[cnt].m_date_sent = savestr(parse_date(p+12));
  1186. !             else if (!strncmp(buf, "Content-Type:", 13))
  1187. !             turnon(msg[cnt].m_flags, METAMAIL);
  1188. !             else if (!strncmp(buf, "Priority:", 9)) {
  1189.               for (p += 9 ; *p != '\n'; p++) {
  1190.                   if (!isalpha(*p) || upper(*p) > 'A' + MAX_PRIORITY)
  1191.                   continue;
  1192. ***************
  1193. *** 906,913 ****
  1194.                   turnon(msg[cnt].m_flags,
  1195.                   M_PRIORITY(upper(*p) - 'A' + 1));
  1196.               }
  1197. !             }
  1198. !             if (get_status &&
  1199.                   !(get_status = strncmp(p, "Status:", 7))) {
  1200.               /* new mail should not have a Status: field! */
  1201.               turnon(msg[cnt].m_flags, OLD);
  1202. --- 936,942 ----
  1203.                   turnon(msg[cnt].m_flags,
  1204.                   M_PRIORITY(upper(*p) - 'A' + 1));
  1205.               }
  1206. !             } else if (get_status &&
  1207.                   !(get_status = strncmp(p, "Status:", 7))) {
  1208.               /* new mail should not have a Status: field! */
  1209.               turnon(msg[cnt].m_flags, OLD);
  1210. *** 7.2.4/mush.h    Sun Feb  2 13:50:50 1992
  1211. --- 7.2.5/mush.h    Sun Sep 20 14:12:32 1992
  1212. ***************
  1213. *** 30,36 ****
  1214.   
  1215.   #else /* CURSES */
  1216.   #include <stdio.h>
  1217. ! #if defined(SYSV) && defined(USG)
  1218.   #include <termio.h>
  1219.   #endif /* SYSV && USG */
  1220.   #endif /* CURSES */
  1221. --- 30,36 ----
  1222.   
  1223.   #else /* CURSES */
  1224.   #include <stdio.h>
  1225. ! #if defined(SYSV) && defined(USG) || defined(AIX)
  1226.   #include <termio.h>
  1227.   #endif /* SYSV && USG */
  1228.   #endif /* CURSES */
  1229. ***************
  1230. *** 166,172 ****
  1231.   #endif /* TIOCSETN */
  1232.   
  1233.   /* for system-V machines that run termio */
  1234. ! #if defined(SYSV) && defined(USG)
  1235.   #ifdef crmode
  1236.   #undef crmode
  1237.   #undef nocrmode
  1238. --- 166,172 ----
  1239.   #endif /* TIOCSETN */
  1240.   
  1241.   /* for system-V machines that run termio */
  1242. ! #if defined(SYSV) && defined(USG) || defined(AIX)
  1243.   #ifdef crmode
  1244.   #undef crmode
  1245.   #undef nocrmode
  1246. ***************
  1247. *** 209,217 ****
  1248.   #define crmode()   ((iscurses) ? cbreak() : cbrkon())
  1249.   #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
  1250.   #endif /* CURSES */
  1251. ! #endif /* SYSV && USG */
  1252.   
  1253. ! #if !defined(USG)
  1254.   #ifndef CURSES
  1255.   /* if curses is not defined, simulate the same tty based macros */
  1256.   typedef struct sgttyb SGTTY;
  1257. --- 209,217 ----
  1258.   #define crmode()   ((iscurses) ? cbreak() : cbrkon())
  1259.   #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
  1260.   #endif /* CURSES */
  1261. ! #endif /* SYSV && USG || AIX */
  1262.   
  1263. ! #if !defined(USG) && !defined(AIX)
  1264.   #ifndef CURSES
  1265.   /* if curses is not defined, simulate the same tty based macros */
  1266.   typedef struct sgttyb SGTTY;
  1267. ***************
  1268. *** 368,374 ****
  1269.   #define skipdigits(n)     for(p += (n); isdigit(*p); ++p)
  1270.   #define ismsgnum(c)       (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
  1271.   #define skipmsglist(n)\
  1272. !     for(p += (n); ismsgnum(*p) || index(" \t,-{`}", *p); ++p)\
  1273.       if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
  1274.   
  1275.   /* define a macro to declare unsigned-long bits */
  1276. --- 368,374 ----
  1277.   #define skipdigits(n)     for(p += (n); isdigit(*p); ++p)
  1278.   #define ismsgnum(c)       (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
  1279.   #define skipmsglist(n)\
  1280. !     for(p += (n); *p && (ismsgnum(*p) || index(" \t,-{`}", *p)); p += !!*p)\
  1281.       if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
  1282.   
  1283.   /* define a macro to declare unsigned-long bits */
  1284. ***************
  1285. *** 430,441 ****
  1286.   #define REPLIED        ULBIT(17) /* Messages that have been replied to */
  1287.   #define NEW_SUBJECT    ULBIT(18) /* new subject regardless of $ask (mail -s) */
  1288.   #define SAVED        ULBIT(19) /* when message has been saved */
  1289. - #ifdef MSG_SEPARATOR
  1290.   #define NO_SEPARATOR    ULBIT(20) /* don't include message separator lines */
  1291. ! #endif /* MSG_SEPARATOR */
  1292.   
  1293. ! #define M_PRIORITY(n)    ULBIT(21+(n))
  1294. ! /* It is possible to reset MAX_PRIORITY to as high as 10 */
  1295.   #define MAX_PRIORITY    5
  1296.   
  1297.   #define    MAXMSGS_BITS    MAXMSGS/sizeof(char)    /* number of bits for bitmap */
  1298. --- 430,440 ----
  1299.   #define REPLIED        ULBIT(17) /* Messages that have been replied to */
  1300.   #define NEW_SUBJECT    ULBIT(18) /* new subject regardless of $ask (mail -s) */
  1301.   #define SAVED        ULBIT(19) /* when message has been saved */
  1302.   #define NO_SEPARATOR    ULBIT(20) /* don't include message separator lines */
  1303. ! #define METAMAIL    ULBIT(21) /* message can display with "metamail" */
  1304.   
  1305. ! #define M_PRIORITY(n)    ULBIT(22+(n))
  1306. ! /* It is possible to reset MAX_PRIORITY to as high as 9 */
  1307.   #define MAX_PRIORITY    5
  1308.   
  1309.   #define    MAXMSGS_BITS    MAXMSGS/sizeof(char)    /* number of bits for bitmap */
  1310. ***************
  1311. *** 590,598 ****
  1312.   #ifdef TIOCGLTC
  1313.   struct ltchars ltchars;            /* tty character settings */
  1314.   #endif /* TIOCGLTC */
  1315. ! #ifdef BSD /* (TIOCGETC) */
  1316.   struct tchars  tchars;            /* more tty character settings */
  1317. ! #endif /* BSD (TIOCGETC) */
  1318.   
  1319.   #ifdef CURSES
  1320.   
  1321. --- 589,597 ----
  1322.   #ifdef TIOCGLTC
  1323.   struct ltchars ltchars;            /* tty character settings */
  1324.   #endif /* TIOCGLTC */
  1325. ! #if defined(BSD) && !defined(AIX) /* (TIOCGETC) */
  1326.   struct tchars  tchars;            /* more tty character settings */
  1327. ! #endif /* BSD && !AIX (TIOCGETC) */
  1328.   
  1329.   #ifdef CURSES
  1330.   
  1331. ***************
  1332. *** 610,615 ****
  1333. --- 609,627 ----
  1334.   void
  1335.       mac_flush();    /* Abandon macro processing (on error) */
  1336.   
  1337. + #if defined(SUNTOOL) || defined(POP3_SUPPORT)
  1338. + #ifdef POP3_SUPPORT
  1339. + #define MIN_TIME_OUT    (15 * 60)    /* 15 min. checks */
  1340. + extern void popchkmail();
  1341. + extern void popgetmail();
  1342. + #else
  1343. + #define MIN_TIME_OUT    30        /* 30 sec. checks */
  1344. + #endif /* POP3_SUPPORT */
  1345. + int
  1346. +     time_out;        /* time out interval to wait for new mail */
  1347. + #endif /* SUNTOOL || POP3_SUPPORT */
  1348.   #ifdef SUNTOOL
  1349.   void
  1350.       timeout_cursors(), do_file_dir(), toggle_mail_items(), ok_box(),
  1351. ***************
  1352. *** 624,630 ****
  1353.       blank[128];        /* use to clear to end of line */
  1354.   
  1355.   int
  1356. -     time_out,        /* time out interval to wait for new mail */
  1357.       is_iconic;        /* set if the mushview window is iconic. */
  1358.   
  1359.   Notify_value
  1360. --- 636,641 ----
  1361. *** 7.2.4/options.c    Thu May  3 12:40:56 1990
  1362. --- 7.2.5/options.c    Thu Oct  1 13:11:42 1992
  1363. ***************
  1364. *** 91,100 ****
  1365.           fix_word_flag(&args[0]);
  1366.   DoNext:
  1367.           switch (args[0][next]) {
  1368. ! #ifdef SUNTOOL
  1369.           case 'T' :
  1370.               if (args[1])
  1371.               args++;
  1372.           case 't' :
  1373.               /* Note: we won't ever get here if started as
  1374.                * "mushtool" or "mushview" because istool is true.
  1375. --- 91,104 ----
  1376.           fix_word_flag(&args[0]);
  1377.   DoNext:
  1378.           switch (args[0][next]) {
  1379. ! #if defined(SUNTOOL) || defined(POP3_SUPPORT)
  1380.           case 'T' :
  1381.               if (args[1])
  1382.               args++;
  1383. + #ifdef POP3_SUPPORT
  1384. +             break;
  1385. + #endif /* POP3_SUPPORT */
  1386. + #ifdef SUNTOOL
  1387.           case 't' :
  1388.               /* Note: we won't ever get here if started as
  1389.                * "mushtool" or "mushview" because istool is true.
  1390. ***************
  1391. *** 105,110 ****
  1392. --- 109,115 ----
  1393.               return TRUE;
  1394.               /* break; */
  1395.   #endif /* SUNTOOL */
  1396. + #endif /* SUNTOOL || POP3_SUPPORT */
  1397.           case 'S' :
  1398.               turnon(glob_flags, DO_SHELL);
  1399.               n = TRUE;
  1400. ***************
  1401. *** 301,314 ****
  1402.           turnon(flags->flg, VERBOSE);
  1403.           break;
  1404.   #endif /* VERBOSE_ARG */
  1405. ! #ifdef SUNTOOL
  1406.           case 'T':
  1407. !         if ((time_out = atoi(*(*argvp))) <= 29)
  1408. !             time_out = 30;
  1409.           look_again = FALSE;
  1410.           /* -T implies -t */
  1411.           case 't': istool = 1;
  1412.   #endif /* SUNTOOL */
  1413.           case 'S': turnon(glob_flags, DO_SHELL);
  1414.           when 'n':
  1415.           if ((*argvp)[0][2] == '!') {
  1416. --- 306,324 ----
  1417.           turnon(flags->flg, VERBOSE);
  1418.           break;
  1419.   #endif /* VERBOSE_ARG */
  1420. ! #if defined(SUNTOOL) || defined(POP3_SUPPORT)
  1421.           case 'T':
  1422. !         if ((time_out = atoi(*(*argvp))) < MIN_TIME_OUT)
  1423. !             time_out = MIN_TIME_OUT;
  1424.           look_again = FALSE;
  1425. + #ifdef POP3_SUPPORT
  1426. +         break;
  1427. + #endif /* POP3_SUPPORT */
  1428. + #ifdef SUNTOOL
  1429.           /* -T implies -t */
  1430.           case 't': istool = 1;
  1431.   #endif /* SUNTOOL */
  1432. + #endif /* SUNTOOL || POP3_SUPPORT */
  1433.           case 'S': turnon(glob_flags, DO_SHELL);
  1434.           when 'n':
  1435.           if ((*argvp)[0][2] == '!') {
  1436. *** 7.2.4/pick.c    Wed Nov 20 23:42:33 1991
  1437. --- 7.2.5/pick.c    Mon Sep  7 09:56:57 1992
  1438. ***************
  1439. *** 74,80 ****
  1440.       head_cnt = tail_cnt = -1;
  1441.       match_priority = 0;
  1442.       icase = before = after = search_from = search_subj = search_to = xflg = 0;
  1443. !     mdy[0] = mdy[1] = search_hdr[0] = 0;
  1444.       while (*argv && *++argv && (**argv == '-' || **argv == '+'))
  1445.       if (**argv == '+' || isdigit(argv[0][1])) {
  1446.           if (**argv == '+')
  1447. --- 74,80 ----
  1448.       head_cnt = tail_cnt = -1;
  1449.       match_priority = 0;
  1450.       icase = before = after = search_from = search_subj = search_to = xflg = 0;
  1451. !     pattern[0] = mdy[0] = mdy[1] = search_hdr[0] = 0;
  1452.       while (*argv && *++argv && (**argv == '-' || **argv == '+'))
  1453.       if (**argv == '+' || isdigit(argv[0][1])) {
  1454.           if (**argv == '+')
  1455. ***************
  1456. *** 166,172 ****
  1457.       return -1;
  1458.       }
  1459.       if (!mdy[1]) {
  1460. -     pattern[0] = 0;
  1461.       (void) argv_to_string(pattern, argv);
  1462.       if (pattern[0] == '\0' && match_priority == 0 &&
  1463.           head_cnt + tail_cnt < 0) {
  1464. --- 166,171 ----
  1465. *** 7.2.4/setopts.c    Thu Nov 21 10:06:23 1991
  1466. --- 7.2.5/setopts.c    Wed Oct 14 00:03:24 1992
  1467. ***************
  1468. *** 604,609 ****
  1469. --- 604,690 ----
  1470.       return 0;
  1471.   }
  1472.   
  1473. + char *
  1474. + quoteit(str, in_quotes, fix_vars)
  1475. + char *str;
  1476. + int in_quotes;    /* Type of quote the string is in, if any */
  1477. + int fix_vars;    /* Variables will be expanded, so quote $ */
  1478. + {
  1479. + #define other_quote(x) ((x == '"')? '\'' : '"')
  1480. +     static char *buf;
  1481. +     static int bufsiz;
  1482. +     char *s = str, *d;
  1483. +     int len = str? strlen(str) : 0, was_magic = FALSE;
  1484. +     if (!len)
  1485. +     return str;
  1486. +     if (bufsiz < 2 * len) {
  1487. +     xfree(buf);
  1488. +     buf = malloc(bufsiz = 2 * len);
  1489. +     }
  1490. +     if (!buf)
  1491. +     return NULL;
  1492. +     for (d = buf; *d = *s; d++, s++) {
  1493. +     if ((*s == '\'' || *s == '"') &&
  1494. +         (was_magic || in_quotes != other_quote(*s))) {
  1495. +         if (was_magic) {
  1496. +         if (*s == '\'')
  1497. +             continue;
  1498. +         /* else '"' */
  1499. +         ++d;
  1500. +         was_magic = FALSE;
  1501. +         }
  1502. +         if (in_quotes == *s)
  1503. +         *d++ = *s;
  1504. +         *d = other_quote(*s);
  1505. +         *++d = *s;
  1506. +         *++d = other_quote(*s);
  1507. +         if (in_quotes == *s)
  1508. +         *++d = *s;
  1509. +     } else if (*s == '$' && fix_vars && (was_magic || in_quotes != '\'')) {
  1510. +        if (was_magic || in_quotes == '"') {
  1511. +         *d++ = '"';
  1512. +         was_magic = FALSE;
  1513. +         }
  1514. +         *d = '\'';
  1515. +         *++d = *s;
  1516. +         *++d = '\'';
  1517. +         if (in_quotes == '"')
  1518. +         *++d = in_quotes;
  1519. +     } else if (fix_vars && isspace(*s)) {
  1520. +         /* backslash-newline may get stripped when fix_vars */
  1521. +         if (*s == '\n' || *s == '\r') {
  1522. +         *d = '\\';
  1523. +         *++d = *s;
  1524. +         *++d = ' ';    /* XXX not perfect, but ... */
  1525. +         } else if (!was_magic && !in_quotes) {
  1526. +         *d = '"';
  1527. +         *++d = *s;
  1528. +         was_magic = TRUE;
  1529. +         }
  1530. +     } else if (!in_quotes && index("#;|~", *s)) {
  1531. +         if (*s == '~' && !fix_vars) {
  1532. +         /* !fix_vars implies !fix_tildes */
  1533. +         if (was_magic) {
  1534. +             *d = '"';
  1535. +             *++d = *s;
  1536. +             was_magic = FALSE;
  1537. +         }
  1538. +         } else if (!was_magic && (s == str || *s != '~')) {
  1539. +         *d = '"';
  1540. +         *++d = *s;
  1541. +         was_magic = TRUE;
  1542. +         }
  1543. +     }
  1544. +     }
  1545. +     if (was_magic) {
  1546. +     *d = '"';
  1547. +     *++d = '\0';
  1548. +     }
  1549. +     return buf;
  1550. + #undef other_quote
  1551. + }
  1552.   save_list(title, list, command, equals, fp)
  1553.   struct options *list;
  1554.   register char *command, *title, equals;
  1555. ***************
  1556. *** 634,640 ****
  1557.           else
  1558.               quote = "'";
  1559.           (void) fputc(equals? equals: ' ', fp);
  1560. !         (void) fprintf(fp, "%s%s%s", quote, opts->value, quote);
  1561.       }
  1562.       (void) fputc('\n', fp);
  1563.       }
  1564. --- 715,724 ----
  1565.           else
  1566.               quote = "'";
  1567.           (void) fputc(equals? equals: ' ', fp);
  1568. !         (void) fprintf(fp, "%s%s%s",
  1569. !                 quote,
  1570. !                 quoteit(opts->value, quote, TRUE),
  1571. !                 quote);
  1572.       }
  1573.       (void) fputc('\n', fp);
  1574.       }
  1575. ***************
  1576. *** 661,668 ****
  1577.           quote = "\"";
  1578.       else
  1579.           quote = "'";
  1580. !     (void) fprintf(fp, "%s %s%s%s", command, quote,
  1581. !             ctrl_strcpy(buf, opts->m_str, TRUE), quote);
  1582.       if (equals && map_func_names[opts->m_cmd].m_str)
  1583.           (void) fprintf(fp, " %s", map_func_names[opts->m_cmd].m_str);
  1584.       if (opts->x_str && *opts->x_str) {
  1585. --- 745,754 ----
  1586.           quote = "\"";
  1587.       else
  1588.           quote = "'";
  1589. !     (void) fprintf(fp, "%s %s%s%s", command,
  1590. !             quote,
  1591. !             quoteit(ctrl_strcpy(buf, opts->m_str, TRUE), quote, TRUE),
  1592. !             quote);
  1593.       if (equals && map_func_names[opts->m_cmd].m_str)
  1594.           (void) fprintf(fp, " %s", map_func_names[opts->m_cmd].m_str);
  1595.       if (opts->x_str && *opts->x_str) {
  1596. ***************
  1597. *** 670,677 ****
  1598.           quote = "\"";
  1599.           else
  1600.           quote = "'";
  1601. !         (void) fprintf(fp, " %s%s%s", quote,
  1602. !             ctrl_strcpy(buf, opts->x_str, TRUE), quote);
  1603.       }
  1604.       (void) fputc('\n', fp);
  1605.       }
  1606. --- 756,765 ----
  1607.           quote = "\"";
  1608.           else
  1609.           quote = "'";
  1610. !         (void) fprintf(fp, " %s%s%s",
  1611. !             quote,
  1612. !             quoteit(ctrl_strcpy(buf, opts->x_str, TRUE), quote, TRUE),
  1613. !             quote);
  1614.       }
  1615.       (void) fputc('\n', fp);
  1616.       }
  1617. *** 7.2.4/signals.c    Sun Feb  2 14:07:38 1992
  1618. --- 7.2.5/signals.c    Sat Aug 22 11:46:50 1992
  1619. ***************
  1620. *** 418,424 ****
  1621.    */
  1622.   check_new_mail()
  1623.   {
  1624. !     int        ret_value;
  1625.   
  1626.       if (ret_value = mail_size()) {
  1627.   #ifdef SUNTOOL
  1628. --- 418,435 ----
  1629.    */
  1630.   check_new_mail()
  1631.   {
  1632. !     int ret_value;
  1633. ! #ifdef POP3_SUPPORT
  1634. !     static long last_check = -1;  /* We checked at startup */
  1635. !     if (last_check < 0)
  1636. !     last_check = time((long *)0);
  1637. !     
  1638. !     if (istool || time((long *)0) - last_check > time_out) {
  1639. !     popchkmail();
  1640. !     last_check = time((long *)0);
  1641. !     }
  1642. ! #endif /* POP3_SUPPORT */
  1643.   
  1644.       if (ret_value = mail_size()) {
  1645.   #ifdef SUNTOOL
  1646.  
  1647. -- 
  1648. Bart Schaefer                                     schaefer@zigzag.z-code.com
  1649. Z-Code Software Corp.                             schaefer@z-code.com
  1650.  
  1651. exit 0 # Just in case...
  1652.