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