schaefer@ogccse.ogc.edu (Barton E. Schaefer) (05/13/89)
This is Official Patch #2 for the Mail User's Shell (MUSH), version 6.5. A complete version of Mush including this patch can be obtained by anoymous ftp from ucbvax.berkeley.edu, directory pub, file mush-6.5.tar.Z. Overview of changes/bugfixes in this patch: Added summaries of patches #1 and #2 to README-6.5. Fixed problem of known_hosts being ignored -- touches addrs.c. Added "await" command -- touches commands.c, mush.h, mush.1, cmd_help. Fixed NO_SEPARATOR usage -- commands.c, mail.c, msgs.c. Improved description of MSG_SEPARATOR in config.h-dist. Added sort by length to curses [sort] interface -- curses.c. Fixed redundant waiting for child processes -- execute.c. Fixed Fcc for edit_hdrs -- file.c and mail.c. Fixed $record not using full path for file locking -- file.c. Fixed "folder #" not using full path name for # -- folders.c. Changed "replyall" to pick up Resent-To, Apparently-To, and To -- hdrs.c. Fixed strcmp in close_lock for SYSV (mailfile ==> filename) -- lock.c. Fixed return value of dot_lock() (void ==> 0) -- also lock.c. Fixed M_XENIX dot-locking -- again lock.c. Fixed wrong status from msg-number commands (^, $, 3, etc.), so now e.g. "35 | print" with < 35 messages will break the pipe -- loop.c. Changed PATCHDATE -- main.c. Fixed lack of newline following error messages when mush -C fails to load the spool folder -- main.c. Fixed mail_size() to deal correctly with missing spoolfile -- msgs.c. --------------------------------------------------------------------------- Prereq: "5/04/89" *** /tmp/,RCSt1009330 Fri May 12 11:39:42 1989 --- main.c Fri May 12 11:19:04 1989 *************** *** 3,9 **** #include "mush.h" #include "options.h" ! #define PATCHDATE "5/04/89" /* Here because EVERYTHING depends on mush.h */ #if defined(sun) && defined(M_DEBUG) cpu() --- 3,9 ---- #include "mush.h" #include "options.h" ! #define PATCHDATE "5/12/89" /* Here because EVERYTHING depends on mush.h */ #if defined(sun) && defined(M_DEBUG) cpu() *************** *** 28,34 **** char **argv; { int n; ! char buf[256]; register char *p; char **args; struct mush_flags Flags; --- 28,34 ---- char **argv; { int n; ! char buf[MAXPATHLEN]; register char *p; char **args; struct mush_flags Flags; *************** *** 112,117 **** --- 112,120 ---- (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list); (void) source(0, DUBL_NULL); } + + set_cwd(); /* call _after_ sourcing files */ + if (*spoolfile != '/') { n = 1; p = getpath(spoolfile, &n); *************** *** 119,130 **** fputs(p, stderr), exit(1); else if (n) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1); ! else strdup(spoolfile, p); } - set_cwd(); /* call _after_ sourcing files */ - #ifdef SUNTOOL if (istool) { make_tool(args); --- 122,139 ---- fputs(p, stderr), exit(1); else if (n) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1); ! else if (*spoolfile != '/') { ! /* if it still isn't a full path, make it one */ ! char *wd = do_set(set_options, "cwd"); ! if (*wd) { ! (void) sprintf(buf, "%s/%s", wd, p); ! strdup(spoolfile, buf); ! } else ! strdup(spoolfile, p); ! } else strdup(spoolfile, p); } #ifdef SUNTOOL if (istool) { make_tool(args); *************** *** 247,254 **** (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile); if (argv = make_command(buf, TRPL_NULL, &argc)) { ! if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) turnoff(glob_flags, IGN_SIGS), cleanup(0); #ifdef CURSES if (iscurses) (void) curses_help_msg(TRUE); --- 256,266 ---- (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile); if (argv = make_command(buf, TRPL_NULL, &argc)) { ! if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) { ! if (iscurses) ! putchar('\n'); turnoff(glob_flags, IGN_SIGS), cleanup(0); + } #ifdef CURSES if (iscurses) (void) curses_help_msg(TRUE); *** /tmp/,RCSt1010410 Fri May 12 11:55:02 1989 --- README-6.5 Fri May 12 11:54:38 1989 *************** *** 115,117 **** --- 115,146 ---- Ringing the terminal bell is now done by opening the kbd device directly, rather than by printing ctrl-G on stderr. This corrects the problem of flashing the wrong window when run under SunOS-4.0. + + ---------- + Changes in 5-04-89 patch: + + Some repairs to the way headers are displayed, to avoid both coredumps + and a propensity for things to vanish from the toolmode display. Some + minor, related fixes to the curses interface. + + Added sort-by-length capability, as a -l option to the sort command and + a new menu item in tool mode. + + ---------- + Changes in the 5-12-89 patch: + + Clearer documentation of MSG_SEPARATOR in config.h-dist. MSG_SEPARATOR + should not contain a newline, except for MMDF. + + Numerous minor repairs to address and file handling when sending mail. + + Repairs to locking for SYSV with DOT_LOCK, and to signal handling for folder + updating in general (but especially for DOT_LOCK). + + Minor corrections to error reporting in various situations. + + Added a command "await" to wait for new mail. This allows customizable + "asynchronous" notification of new mail in line and curses modes, similar + to what is done automatically for the tool mode. + + Added sort-by-length to the curses [sort] and [sort-reverse] interface. *** /tmp/,RCSt1009330 Fri May 12 11:39:08 1989 --- addrs.c Sun May 7 18:37:15 1989 *************** *** 567,572 **** --- 567,574 ---- for (i = 0; known_hosts && known_hosts[i]; i++) if (!lcase_strncmp(p, known_hosts[i], -1)) break; + if (known_hosts && known_hosts[i]) + break; } /* temporary holder for where we are in buffer (save address) */ p2 = b; *** /tmp/,RCSt1009330 Fri May 12 11:39:13 1989 --- cmd_help Tue May 9 13:18:07 1989 *************** *** 752,754 **** --- 752,771 ---- filename (if given). If no filename is given and the user did not request a merge, then a folder is created based on the subject of the digest. %% + + %await% + await [-T delay] + + Intructs the shell to wait for new mail to arrive. New mail is checked + every 30 seconds by default; a different delay can be specified by using + the -T option. + + If this command is used in a pipe, its output is its input plus the list + of new messages that have arrived. For example, to show the headers of + all new messages, and set the current message to the first new message: + + await | from - + + The await command terminates only when new mail arrives or a keyboard + interrupt is generated. + %% *** /tmp/,RCSt1009330 Fri May 12 11:39:16 1989 --- commands.c Fri May 12 10:33:39 1989 *************** *** 73,79 **** struct cmd hidden_cmds[] = { { "debug", toggle_debug }, { "open", nopenfiles }, ! { "stty", my_stty }, { "setenv", Setenv }, { "unsetenv", Unsetenv }, { "printenv", Printenv }, { "Pipe", pipe_msg }, { NULL, quit } --- 73,79 ---- struct cmd hidden_cmds[] = { { "debug", toggle_debug }, { "open", nopenfiles }, ! { "stty", my_stty }, { "await", await }, { "setenv", Setenv }, { "unsetenv", Unsetenv }, { "printenv", Printenv }, { "Pipe", pipe_msg }, { NULL, quit } *************** *** 223,229 **** SIGRET (*oldint)(), (*oldquit)(); turnon(flags, NO_IGNORE); ! #ifdef MMDF turnon(flags, NO_SEPARATOR); #endif /* MMDF */ if (!(printer = do_set(set_options, "printer")) || !*printer) --- 223,229 ---- SIGRET (*oldint)(), (*oldquit)(); turnon(flags, NO_IGNORE); ! #ifdef MSG_SEPARATOR turnon(flags, NO_SEPARATOR); #endif /* MMDF */ if (!(printer = do_set(set_options, "printer")) || !*printer) *************** *** 1081,1084 **** --- 1081,1116 ---- turnon(glob_flags, IS_PIPE); } return status; + } + + await(argc, argv, list) + char *argv[], list[]; + { + int done = 0, snooze = 30, last_cnt = msg_cnt; + + if (argc && *++argv) { + if (!strcmp(*argv, "-?")) + return help(0, "await", cmd_help); + else if (!strcmp(*argv, "-T")) { + if (*++argv && isdigit(**argv) && **argv > '0') { + snooze = atoi(*argv); + } else { + print("await: integer greater than 0 required for -T\n"); + return -1; + } + } + } + Debug("snoozing %d\n", snooze); + + do { + if (!(done = check_new_mail())) + sleep(snooze); + } while (!done); + + while (last_cnt < msg_cnt) { + set_msg_bit(list, last_cnt); + ++last_cnt; + } + + return 0; } *** /tmp/,RCSt1009330 Fri May 12 11:39:19 1989 --- config.h-dist Fri May 12 11:00:57 1989 *************** *** 53,60 **** /* If your mail transfer agent uses something *besides* "From " to separate * adjacent messages in a folder, define MSG_SEPARATOR to be this string. ! * If that string is 4 ^A's, then the string would be "\001\001\001\001" ! * If you don't know what this means, leave it alone. */ /* #define MSG_SEPARATOR "From " */ #ifdef MMDF --- 53,62 ---- /* If your mail transfer agent uses something *besides* "From " to separate * adjacent messages in a folder, define MSG_SEPARATOR to be this string. ! * If that string is 4 ^A's, then the string would be "\001\001\001\001". ! * With the exception of MMDF, below, you should OMIT a trailing newline ! * from the setting of MSG_SEPARATOR. ! * If you don't know what any of this means, leave it alone. */ /* #define MSG_SEPARATOR "From " */ #ifdef MMDF *** /tmp/,RCSt1009330 Fri May 12 11:39:21 1989 --- curses.c Mon May 8 13:45:24 1989 *************** *** 472,479 **** print("Reverse "), turnon(glob_flags, CONT_PRNT); (void) strcat(file, " -"); } ! print("Order messages by [Status, date, subject, author]: "); ! if ((c = m_getchar()) == 's' || c == 'S' || c == 'd' || c == 'a') { print("reordering messages..."); (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list); print_more("done."); --- 472,482 ---- print("Reverse "), turnon(glob_flags, CONT_PRNT); (void) strcat(file, " -"); } ! print( ! "Order messages by [author, date, length, Status, subject]: " ! ); ! if ((c = m_getchar()) == 'a' || c == 'd' || c == 'l' || ! c == 'S' || c == 's' || c == 'R') { print("reordering messages..."); (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list); print_more("done."); *** /tmp/,RCSt1009330 Fri May 12 11:39:24 1989 --- execute.c Thu May 11 14:21:47 1989 *************** *** 13,18 **** --- 13,20 ---- #include <sys/resource.h> #endif /* lint */ + static jmp_buf execjbuf; + execute(argv) char **argv; { *************** *** 67,78 **** error(*argv); _exit(-1); } ! /* parent's got to do something; sigchldcatcher will do waiting ! * if other forks die (sendmail), then this wait will catch them, ! * This loop will really get -1, cuz sigchldcatcher will catch all else. */ ! while ((pid = wait(&status)) != -1 && pid != exec_pid) ! Debug("The exec loop caught a signal? (pid = %d)\n", pid); /* reset our ttymodes */ echo_off(); (void) signal(SIGINT, oldint); --- 69,81 ---- error(*argv); _exit(-1); } ! /* Parent's got to do something; sigchldcatcher may also be waiting. ! * This loop will usually get broken by the longjmp() (except tool), ! * but in certain circumstances signchldcatcher isn't yet active. */ ! if (!setjmp(execjbuf)) ! while ((pid = wait(&status)) != -1 && pid != exec_pid) ! Debug("The exec loop caught a signal? (pid = %d)\n", pid); /* reset our ttymodes */ echo_off(); (void) signal(SIGINT, oldint); *************** *** 114,120 **** #endif /* SYSV */ #endif /* BSD */ #ifndef SUNTOOL ! } #else /* SUNTOOL */ /* The following SHOULDN'T be necessary, but it is!!! ttysw_fork() * returns the pid of the thing that it executes, but that's not the --- 117,125 ---- #endif /* SYSV */ #endif /* BSD */ #ifndef SUNTOOL ! if (pid == exec_pid) ! longjmp(execjbuf, 1); ! } /* { */ #else /* SUNTOOL */ /* The following SHOULDN'T be necessary, but it is!!! ttysw_fork() * returns the pid of the thing that it executes, but that's not the *** /tmp/,RCSt1009330 Fri May 12 11:39:26 1989 --- file.c Thu May 11 14:03:17 1989 *************** *** 286,292 **** * The string "s" is modified to be a list of address -- all names AND * files are stripped out of the list. */ ! find_files(s, files, names, size) register char *s; FILE *files[]; char *names[]; --- 286,292 ---- * The string "s" is modified to be a list of address -- all names AND * files are stripped out of the list. */ ! find_files(s, files, names, size, force) register char *s; FILE *files[]; char *names[]; *************** *** 293,299 **** { register int total = 0, prog; char file[MAXPATHLEN], buf[HDRSIZ], *start = s, c; ! register char *p, *b = buf; do { if (!(p = get_name_n_addr(s, NULL, file))) --- 293,299 ---- { register int total = 0, prog; char file[MAXPATHLEN], buf[HDRSIZ], *start = s, c; ! register char *p, *b = buf, *fpath; do { if (!(p = get_name_n_addr(s, NULL, file))) *************** *** 302,318 **** /* It's a file -- try to open it. This doesn't get written back * onto "buf" since it is supposed to be extracted anyway. */ ! if (*file == '+' || *file == '~' || *file == '|' || *file == '/') { ! prog = (*file == '|'); if (size && total < size) { ! /* either open "file" or &file[1] */ ! if (files[total] = open_file(&file[prog], prog)) { if (prog) names[total++] = NULL; ! else if (lock_file(&file[prog],files[total]) < 0) { (void) fclose(files[total]); ! } else ! names[total++] = savestr(file); } } else print("No open space for %s\n", file); --- 302,327 ---- /* It's a file -- try to open it. This doesn't get written back * onto "buf" since it is supposed to be extracted anyway. */ ! if (force || *file == '+' || *file == '~' || ! *file == '|' || *file == '/') { ! int isdir; ! /* open either "file" or &file[1] */ ! if (prog = (*file == '|')) { ! isdir = 0; ! fpath = &file[1]; ! } else { ! isdir = 1; ! /* if successful, getpath will reset isdir to 0 */ ! fpath = getpath(file, &isdir); ! } if (size && total < size) { ! if (!isdir && (files[total] = open_file(fpath, prog))) { if (prog) names[total++] = NULL; ! else if (lock_file(fpath, files[total]) < 0) (void) fclose(files[total]); ! else ! names[total++] = savestr(fpath); } } else print("No open space for %s\n", file); *** /tmp/,RCSt1009330 Fri May 12 11:39:29 1989 --- folders.c Mon May 8 07:55:59 1989 *************** *** 113,119 **** } if (strcmp(mailfile, buf)) { if (!updating) ! (void) strcpy(oldfolder, mailfile); strdup(mailfile, buf); } do_read_only? turnon(glob_flags,READ_ONLY) : turnoff(glob_flags,READ_ONLY); --- 113,119 ---- } if (strcmp(mailfile, buf)) { if (!updating) ! (void) strcpy(oldfolder, *oldfolder? mailfile : buf); strdup(mailfile, buf); } do_read_only? turnon(glob_flags,READ_ONLY) : turnoff(glob_flags,READ_ONLY); *** /tmp/,RCSt1009330 Fri May 12 11:39:30 1989 --- hdrs.c Thu May 11 17:58:02 1989 *************** *** 593,617 **** b += Strcpy(buf, p); /* ! * if `all' is true, append everyone on the "To:" line. * cc_to(), called separately, will catch the cc's */ ! if (all && ! ((p = header_field(n, "resent-to")) || (p = header_field(n, "to")) || ! (p = header_field(n, "apparently-to"))) && *p) { ! *b++ = ',', *b++ = ' '; ! /* The assumption that HDRSIZ is correct is unwise, but I know it * to be true for Mush. Be forewarned if you call this routine. */ ! p[HDRSIZ - (b - buf) - 2] = '\0'; /* prevent overflow */ ! b += Strcpy(b, p); ! } ! /* Also append the Resent-From address if there is one. */ ! if (all && (p = header_field(n, "resent-from")) && *p) { ! *b++ = ',', *b++ = ' '; ! /* Another trick to prevent overflow. See warning above. */ ! (void) strncpy(b, p, HDRSIZ - (b - buf) - 2); ! buf[HDRSIZ - 3] = 0; } fix_up_addr(buf); take_me_off(buf); --- 593,631 ---- b += Strcpy(buf, p); /* ! * if `all' is true, append everyone on the "To:" line(s). * cc_to(), called separately, will catch the cc's */ ! if (all) { ! int lim = HDRSIZ - (b - buf) - 2; ! /* Check for overflow on each copy. ! * The assumption that HDRSIZ is correct is unwise, but I know it * to be true for Mush. Be forewarned if you call this routine. */ ! if (lim > 0 && (p = header_field(n, "resent-to")) && *p) { ! *b++ = ',', *b++ = ' '; ! p[lim] = '\0'; /* prevent overflow */ ! b += Strcpy(b, p); ! lim = HDRSIZ - (b - buf) - 2; ! } ! if (lim > 0 && (p = header_field(n, "to")) && *p) { ! *b++ = ',', *b++ = ' '; ! p[lim] = '\0'; /* prevent overflow */ ! b += Strcpy(b, p); ! lim = HDRSIZ - (b - buf) - 2; ! } ! if (lim > 0 && (p = header_field(n, "apparently-to")) && *p) { ! *b++ = ',', *b++ = ' '; ! p[lim] = '\0'; /* prevent overflow */ ! b += Strcpy(b, p); ! lim = HDRSIZ - (b - buf) - 2; ! } ! /* Also append the Resent-From address if there is one. */ ! if (lim > 0 && (p = header_field(n, "resent-from")) && *p) { ! *b++ = ',', *b++ = ' '; ! p[lim] = '\0'; /* prevent overflow */ ! (void) strcpy(b, p); ! } } fix_up_addr(buf); take_me_off(buf); *** /tmp/,RCSt1009330 Fri May 12 11:39:33 1989 --- lock.c Thu May 11 11:49:36 1989 *************** *** 29,35 **** #ifdef BSD setregid(rgid, sgid); ! #else setgid(sgid); #endif /* BSD */ #ifdef SYSV --- 29,35 ---- #ifdef BSD setregid(rgid, sgid); ! #else /* BSD */ setgid(sgid); #endif /* BSD */ #ifdef SYSV *************** *** 38,51 **** * file name limits, we allow dot_locking ONLY of the spoolfile. */ if (strcmp(spoolfile, filename) != 0) ! return; #endif #ifdef M_XENIX ! if (strcmp(spoolfile, filename) == 0) ! (void) sprintf(buf, "/tmp/%.10s.mlk", login); ! else ! #endif /* M_XENIX */ (void) sprintf(buf, "%s.lock", filename); on_intr(); while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0600)) == -1) { if (errno != EEXIST) { --- 38,50 ---- * file name limits, we allow dot_locking ONLY of the spoolfile. */ if (strcmp(spoolfile, filename) != 0) ! return 0; #endif #ifdef M_XENIX ! (void) sprintf(buf, "/tmp/%.10s.mlk", login); ! #else /* M_XENIX */ (void) sprintf(buf, "%s.lock", filename); + #endif /* M_XENIX */ on_intr(); while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0600)) == -1) { if (errno != EEXIST) { *************** *** 141,146 **** --- 140,146 ---- FILE *fp; #ifdef LCKDFLDIR { + fflush(fp); (void) lk_unlock(filename, NULL, NULL); fclose(fp); } *************** *** 148,164 **** { #ifdef DOT_LOCK char buf[MAXPATHLEN]; #ifdef BSD setregid(rgid, sgid); #else setgid(sgid); #endif /* BSD */ #ifdef M_XENIX ! if (strcmp(spoolfile, mailfile) == 0) ! (void) unlink(sprintf(buf, "/tmp/%.10s.mlk", login)); ! else ! #endif /* M_XENIX */ (void) unlink(sprintf(buf, "%s.lock", filename)); #ifdef BSD setregid(sgid, rgid); #else --- 148,170 ---- { #ifdef DOT_LOCK char buf[MAXPATHLEN]; + #endif /* DOT_LOCK */ + + fflush(fp); + #ifdef DOT_LOCK #ifdef BSD setregid(rgid, sgid); #else setgid(sgid); #endif /* BSD */ + #ifdef SYSV + if (strcmp(spoolfile, filename) == 0) + #endif /* SYSV */ #ifdef M_XENIX ! (void) unlink(sprintf(buf, "/tmp/%.10s.mlk", login)); ! #else /* M_XENIX */ (void) unlink(sprintf(buf, "%s.lock", filename)); + #endif /* M_XENIX */ #ifdef BSD setregid(sgid, rgid); #else *** /tmp/,RCSt1009330 Fri May 12 11:39:35 1989 --- loop.c Mon May 8 15:32:44 1989 *************** *** 356,362 **** n = -1; /* default to failure */ if ((isdigit(**argv) || index("^.*$-`{}", **argv)) && (n = get_msg_list(argv, list)) != 0) { ! if (n > 0 && isoff(glob_flags, DO_PIPE)) for (n = 0; n < msg_cnt; n++) if (msg_bit(list, n)) { display_msg((current_msg = n), (long)0); --- 356,364 ---- n = -1; /* default to failure */ if ((isdigit(**argv) || index("^.*$-`{}", **argv)) && (n = get_msg_list(argv, list)) != 0) { ! if (n < 0) ! return -1; ! else if (isoff(glob_flags, DO_PIPE)) for (n = 0; n < msg_cnt; n++) if (msg_bit(list, n)) { display_msg((current_msg = n), (long)0); *************** *** 368,376 **** if (n == 0) unset_msg_bit(list, current_msg); if (strlen(*argv) == 1 && index("$^.", **argv)) { ! if (!msg_cnt) print("No messages."); ! else { if (**argv != '.') current_msg = (**argv == '$') ? msg_cnt-1 : 0; set_msg_bit(list, current_msg); --- 370,379 ---- if (n == 0) unset_msg_bit(list, current_msg); if (strlen(*argv) == 1 && index("$^.", **argv)) { ! if (!msg_cnt) { print("No messages."); ! return -1; ! } else { if (**argv != '.') current_msg = (**argv == '$') ? msg_cnt-1 : 0; set_msg_bit(list, current_msg); *** /tmp/,RCSt1011304 Fri May 12 12:19:20 1989 --- mail.c Fri May 12 12:18:52 1989 *************** *** 445,451 **** turnon(copy_flgs, NO_HEADER); if (ison(flags, INCLUDE) || is_forw) turnon(copy_flgs, NO_IGNORE); ! #ifdef MMDF turnon(copy_flgs, NO_SEPARATOR); #endif /* MMDF */ #ifdef SUNTOOL --- 445,451 ---- turnon(copy_flgs, NO_HEADER); if (ison(flags, INCLUDE) || is_forw) turnon(copy_flgs, NO_IGNORE); ! #ifdef MSG_SEPARATOR turnon(copy_flgs, NO_SEPARATOR); #endif /* MMDF */ #ifdef SUNTOOL *************** *** 743,749 **** turnon(copy_flgs, INDENT); if (line[1] == 'i') turnon(copy_flgs, NO_HEADER); ! #ifdef MMDF turnon(copy_flgs, NO_SEPARATOR); #endif /* MMDF */ if (!*p) --- 743,749 ---- turnon(copy_flgs, INDENT); if (line[1] == 'i') turnon(copy_flgs, NO_HEADER); ! #ifdef MSG_SEPARATOR turnon(copy_flgs, NO_SEPARATOR); #endif /* MMDF */ if (!*p) *************** *** 948,954 **** /* add the \n, flush the file, truncate to the current pos */ fputc('\n', ed_fp), fflush(ed_fp); (void) ftruncate(fileno(ed_fp), (int)ftell(ed_fp)); ! #else /* pad with blanks to the length of the old line. add \n */ while (pos++ < 0) fputc(' ', ed_fp); --- 948,954 ---- /* add the \n, flush the file, truncate to the current pos */ fputc('\n', ed_fp), fflush(ed_fp); (void) ftruncate(fileno(ed_fp), (int)ftell(ed_fp)); ! #else /* SYSV */ /* pad with blanks to the length of the old line. add \n */ while (pos++ < 0) fputc(' ', ed_fp); *************** *** 1156,1162 **** if (p = header_field(msg_cnt, "bcc")) (void) strcpy(Bcc, p); if (p = header_field(msg_cnt, "fcc")) ! (void) strcat(Bcc, p); } msg[msg_cnt].m_offset = old_offset; tmpf = save_tmpf; --- 1156,1163 ---- if (p = header_field(msg_cnt, "bcc")) (void) strcpy(Bcc, p); if (p = header_field(msg_cnt, "fcc")) ! next_file += ! find_files(p,files+next_file,names+next_file,size-next_file,1); } msg[msg_cnt].m_offset = old_offset; tmpf = save_tmpf; *************** *** 1208,1214 **** rm_edfile(-1); } else { next_file += ! find_files(p, files+next_file, names+next_file, size-next_file); if (expand) (void) strcpy(To, p); rm_cmts_in_addr(p); --- 1209,1215 ---- rm_edfile(-1); } else { next_file += ! find_files(p, files+next_file, names+next_file, size-next_file, 0); if (expand) (void) strcpy(To, p); rm_cmts_in_addr(p); *************** *** 1238,1244 **** rm_edfile(-1); } else { next_file += ! find_files(p, files+next_file, names+next_file, size-next_file); if (expand) (void) strcpy(Cc, p); rm_cmts_in_addr(p); --- 1239,1245 ---- rm_edfile(-1); } else { next_file += ! find_files(p,files+next_file,names+next_file,size-next_file,0); if (expand) (void) strcpy(Cc, p); rm_cmts_in_addr(p); *************** *** 1269,1275 **** rm_edfile(-1); } else { next_file += ! find_files(p, files+next_file, names+next_file, size-next_file); (void) strcpy(Bcc, p); rm_cmts_in_addr(p); skipspaces(0); --- 1270,1276 ---- rm_edfile(-1); } else { next_file += ! find_files(p,files+next_file,names+next_file,size-next_file,0); (void) strcpy(Bcc, p); rm_cmts_in_addr(p); skipspaces(0); *************** *** 1376,1382 **** (void) strcpy(buf, p); log_file = next_file; next_file += ! find_files(buf, files+next_file, names+next_file, size-next_file); if (log_file == next_file) log_file = -1; } --- 1377,1383 ---- (void) strcpy(buf, p); log_file = next_file; next_file += ! find_files(buf,files+next_file,names+next_file,size-next_file,0); if (log_file == next_file) log_file = -1; } *************** *** 1393,1399 **** else (void) strcpy(buf, p); next_file += ! find_files(buf, files+next_file, names+next_file, size-next_file); } /* First, put the message separator in... */ --- 1394,1400 ---- else (void) strcpy(buf, p); next_file += ! find_files(buf,files+next_file,names+next_file,size-next_file,0); } /* First, put the message separator in... */ *************** *** 1827,1837 **** fflush(ed_fp); rewind(ed_fp); #ifdef MSG_SEPARATOR ! fputs(MSG_SEPARATOR, dead); #else /* MSG_SEPARATOR */ fprintf(dead, "From %s %s", login, ctime(&t)); #endif /* MSG_SEPARATOR */ ! fprintf(dead, "To: %s\nSubject: %s\n", To, Subject); fprintf(dead, "Date: %s\n", rfc_date(buf)); if (*Cc) fprintf(dead, "Cc: %s\n", Cc); --- 1828,1841 ---- fflush(ed_fp); rewind(ed_fp); #ifdef MSG_SEPARATOR ! fputs(MSG_SEPARATOR, dead); ! #ifndef MMDF ! fputc('\n', dead); ! #endif /* MMDF */ #else /* MSG_SEPARATOR */ fprintf(dead, "From %s %s", login, ctime(&t)); #endif /* MSG_SEPARATOR */ ! fprintf(dead, "From: %s\nTo: %s\nSubject: %s\n", login, To, Subject); fprintf(dead, "Date: %s\n", rfc_date(buf)); if (*Cc) fprintf(dead, "Cc: %s\n", Cc); *** /tmp/,RCSt1009330 Fri May 12 11:39:48 1989 --- msgs.c Fri May 12 10:59:28 1989 *************** *** 28,34 **** print("Top of "), turnon(glob_flags, CONT_PRNT); } ! #ifdef MMDF turnon(flg, NO_SEPARATOR); #endif /* MMDF */ if (!istool && isoff(flg, NO_PAGE) && --- 28,34 ---- print("Top of "), turnon(glob_flags, CONT_PRNT); } ! #ifdef MSG_SEPARATOR turnon(flg, NO_SEPARATOR); #endif /* MMDF */ if (!istool && isoff(flg, NO_PAGE) && *************** *** 98,106 **** } while (still_more < msg[n].m_size && fgets(line, sizeof (line), tmpf)) { still_more += strlen(line); ! #ifdef MMDF if (ison(flags, NO_SEPARATOR)) { if (!strncmp(line, MSG_SEPARATOR, 4)) continue; } #endif /* MMDF */ --- 98,110 ---- } while (still_more < msg[n].m_size && fgets(line, sizeof (line), tmpf)) { still_more += strlen(line); ! #ifdef MSG_SEPARATOR if (ison(flags, NO_SEPARATOR)) { + #ifdef MMDF if (!strncmp(line, MSG_SEPARATOR, 4)) + #else /* !MMDF */ + if (!strncmp(line, MSG_SEPARATOR, strlen(MSG_SEPARATOR))) + #endif /* MMDF */ continue; } #endif /* MMDF */ *************** *** 276,292 **** error("Unable to write to %s", mbox_file); } } ! #ifdef DOT_LOCK ! if ((i = dot_lock(mailfile)) == 0) ! mail_fp = mask_fopen(mailfile, "w+"); ! #else /* !DOT_LOCK */ /* We can't lock a file unless we have an fd, but "w+" will zero * the file. If the lock later failed for any reason (possible * race condition with an MTA), we would lose all current mail. * So, open read/write (if possible) and truncate later. */ ! mail_fp = mask_fopen(mailfile, "r+"); #endif /* DOT_LOCK */ if (!mail_fp) { error("Unable to rewrite %s", mailfile); if (mbox) --- 280,295 ---- error("Unable to write to %s", mbox_file); } } ! /* We can't lock a file unless we have an fd, but "w+" will zero * the file. If the lock later failed for any reason (possible * race condition with an MTA), we would lose all current mail. * So, open read/write (if possible) and truncate later. */ ! #ifdef DOT_LOCK ! if ((i = dot_lock(mailfile)) == 0) #endif /* DOT_LOCK */ + mail_fp = mask_fopen(mailfile, "r+"); if (!mail_fp) { error("Unable to rewrite %s", mailfile); if (mbox) *************** *** 303,309 **** fclose(mbox); return 0; } ! #if !defined(DOT_LOCK) && defined(SYSV) /* SysV can't truncate a file in the middle, so we can't just * write to mail_fp and close. Instead, we save the mail_fp * and reopen for writing, ignoring our own lock. After updating, --- 306,314 ---- fclose(mbox); return 0; } ! /* ignore signals before truncating */ ! turnon(glob_flags, IGN_SIGS); ! #ifdef SYSV /* SysV can't truncate a file in the middle, so we can't just * write to mail_fp and close. Instead, we save the mail_fp * and reopen for writing, ignoring our own lock. After updating, *************** *** 317,330 **** close_lock(mailfile, save_mail_fp); if (mbox) fclose(mbox); return 0; } ! #endif /* SYSV && !DOT_LOCK */ print("Updating \"%s\"", mailfile); turnon(flg, UPDATE_STATUS); - turnon(glob_flags, IGN_SIGS); keepsave = !!do_set(set_options, "keepsave"); isspool = !strcmp(mailfile, spoolfile); --- 322,335 ---- close_lock(mailfile, save_mail_fp); if (mbox) fclose(mbox); + turnoff(glob_flags, IGN_SIGS); return 0; } ! #endif /* SYSV */ print("Updating \"%s\"", mailfile); turnon(flg, UPDATE_STATUS); keepsave = !!do_set(set_options, "keepsave"); isspool = !strcmp(mailfile, spoolfile); *************** *** 367,373 **** } Debug("\n%s", mailfile); - #ifndef DOT_LOCK #ifdef SYSV /* Close the write file pointer first */ fclose(mail_fp); --- 372,377 ---- *************** *** 379,385 **** */ (void) ftruncate(fileno(mail_fp), ftell(mail_fp)); #endif /* SYSV */ - #endif /* !DOT_LOCK */ /* some users like to have zero length folders for frequent usage */ if (mbox) --- 383,388 ---- *************** *** 436,441 **** --- 439,446 ---- if (!stat(spoolfile, &buf)) spool_size = buf.st_size; + else if (!strcmp(mailfile, spoolfile)) + return 0; if (!*mailfile || ison(glob_flags, IS_SENDING)) return 0; if (strcmp(mailfile, spoolfile) && stat(mailfile, &buf)) { *** /tmp/,RCSt1009330 Fri May 12 11:39:53 1989 --- mush.1 Tue May 9 15:31:25 1989 *************** *** 1660,1665 **** --- 1660,1673 ---- command is given with no arguments, the current set of alternate names is displayed. .TP + .BR await " [\-T timeout]" + Directs the shell to wait for the arrival of new mail. + New mail is checked approximately every 30 seconds, or every + .I timeout + seconds as specified by the \-T option. + This command does not return until new mail arrives + or until a keyboard interrupt (^C) is typed. + .TP .BR bind " [string [command [parameters]]]" .ns .TP *** /tmp/,RCSt1009330 Fri May 12 11:40:01 1989 --- mush.h Thu May 11 13:03:05 1989 *************** *** 490,496 **** save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(), save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(), do_pick(), print_help(), question_mark(), do_from(), my_stty(), ! do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(), nopenfiles(), Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug(); #ifndef SIGRET --- 490,496 ---- save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(), save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(), do_pick(), print_help(), question_mark(), do_from(), my_stty(), ! do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(), await(), nopenfiles(), Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug(); #ifndef SIGRET -- Bart Schaefer "And if you believe that, you'll believe anything." -- DangerMouse CSNET / Internet schaefer@cse.ogc.edu UUCP ...{sequent,tektronix,verdix}!ogccse!schaefer