[comp.sources.unix] v15i086: Mush

rsalz@uunet.uu.net (Rich Salz) (07/07/88)

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

[  You will have to do
	cat Diffs.6.3.[abc] | patch
   to install these patches.  --r$  ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Diffs.6.3.a' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Diffs.6.3.a'\"
else
echo shar: Extracting \"'Diffs.6.3.a'\" \(57387 characters\)
sed "s/^X//" >'Diffs.6.3.a' <<'END_OF_FILE'
X*** OLD/Makefile	Fri Jun 10 12:38:05 1988
X--- Makefile	Thu Jun 30 13:05:31 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,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 Mailrc
X  MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
X  
X  CFLAGS= -O -DCURSES -DBSD
X*** OLD/README	Fri Jun 10 12:38:05 1988
X--- README	Tue Jun 28 21:37:48 1988
X***************
X*** 9,22 ****
X  
X  When sending mail, mail to the addresses in the order given.
X  
X! Contained is the source for "Mail User's Shell" (MUSH), an interface
X! for the sending, viewing and managing of electronic mail on UNIX(tm) systems.
X  Redistribution of this code is permitted as long as all copyright notices
X  remain intact and all other identifying notices remain in the code and
X  in the binary.  This includes message headers on outgoing mail and
X! the startup message.  Failing to adhere to this reflects on your poor
X! sense of fair play and bad attitude -- you will probably fail in your
X! social and business affairs with little honor and respect from your peers.
X  
X  With that out of the way...
X  
X--- 9,28 ----
X  
X  When sending mail, mail to the addresses in the order given.
X  
X! Mush is a Mail User Agent (MUA).  That is, it is used by the user to read mail,
X! arrange it, delete it, or act as an interface to send mail to other users.
X! A Mail Transport Agent (MTA) is the program that mush talks to.  The MTA
X! actually delivers the mail to the destination (usually in the asynchronously
X! with mush).
X! 
X! Contained is the source for "Mail User's Shell" (MUSH), an MUA that is
X! designed to manage electronic mail on most UNIX(tm) systems.
X  Redistribution of this code is permitted as long as all copyright notices
X  remain intact and all other identifying notices remain in the code and
X  in the binary.  This includes message headers on outgoing mail and
X! the startup message.  Future releases will extract the release version
X! from the message headers of mush-originated messages to aid in implementing
X! features and providing backwards complatibility with previous versions.
X  
X  With that out of the way...
X  
X***************
X*** 24,30 ****
X  "config.h" (probably "config.h-dist") COPY it to config.h, edit it to reflect
X  the system dependencines described there.  Decide which makefile applies
X  to you.  makefile.sun applies only to suns and creates a binary called
X! "mush."  If the binary ends in "tool", then the graphics (tool) mode will
X  be used by default on invocation. Otherwise, you must specify -t for toolmode
X  on sun workstations.  The SUNTOOL define must be set in the makefile.sun
X  in order to compile the suntools version.  You don't need to be running
X--- 30,36 ----
X  "config.h" (probably "config.h-dist") COPY it to config.h, edit it to reflect
X  the system dependencines described there.  Decide which makefile applies
X  to you.  makefile.sun applies only to suns and creates a binary called
X! "mush."  If the binary ends in "tool", then the graphics (suntools) mode will
X  be used by default on invocation. Otherwise, you must specify -t for toolmode
X  on sun workstations.  The SUNTOOL define must be set in the makefile.sun
X  in order to compile the suntools version.  You don't need to be running
X***************
X*** 36,42 ****
X  files not be compiled so the binary will be made smaller.
X  
X  The files makefile.x286 and makefile.x386 were created especially for
X! xenix machines.  Depending on the configuration of your particular xenix box,
X  some tweeking of the makefile flags may be necessary.  If your xenix
X  release is 2.2 or higher then you must define USG. Libraries to use should
X  be -ltinfo *not* -lcurses -ltermlib.  This is because the curses package
X--- 42,48 ----
X  files not be compiled so the binary will be made smaller.
X  
X  The files makefile.x286 and makefile.x386 were created especially for
X! XENIX machines.  Depending on the configuration of your particular xenix box,
X  some tweeking of the makefile flags may be necessary.  If your xenix
X  release is 2.2 or higher then you must define USG. Libraries to use should
X  be -ltinfo *not* -lcurses -ltermlib.  This is because the curses package
X***************
X*** 48,58 ****
X  BSD and probably running a system-v flavor of unix -- this defines USG
X  so that termio will be used.  Some older unix systems have SYSV defined
X  in /usr/include/curses.h (which is used if you are compiling with CURSES)
X! In most cases, these only generate annoying warning messages and does not
X! effect the compilation of the code.
X  
X! Mush was designed to use sendmail as the Mail Transport Agent. However,
X! other MTA's will work.  The MTA you use should be defined in config.h
X  under the MAIL_DELIVERY macro define. By default, /usr/lib/sendmail -i
X  is used -- the option, -i, tells sendmail not to accept "." on a line
X  by itself as an end-of-file marker.
X--- 54,81 ----
X  BSD and probably running a system-v flavor of unix -- this defines USG
X  so that termio will be used.  Some older unix systems have SYSV defined
X  in /usr/include/curses.h (which is used if you are compiling with CURSES)
X! In most cases, these may generate annoying warning messages but do not
X! affect the compilation of the code.
X  
X! When you decide on an appropriate makefile, _copy_ it to a new file called
X! Makefile.
X! 
X! When it comes to "compile-time definitions", you may use one of two methods:
X!     -DDEFINITION  /* in your makefile */
X!     #define DEFINITION /* in the config.h file */
X! If the definition is of the form MACRO="string", then use:
X!     -DMACRO=string
X!     #define MACRO string
X! For example, if you are on a system V machine, you may need to define
X! SIGRET to be of type void because the signal() function doesn't return
X! anything useful (or, a "void" type).  To define this, your makefile may
X! have (as part of the CFLAGS setting):
X!     -DSIGRET=void
X! or your config.h file should have somewhere in it (doesn't matter where):
X! #define SIGRET void
X! 
X! Mush was originally designed to use sendmail as the Mail Transport Agent.
X! However, other MTA's will work.  The MTA you use should be defined in config.h
X  under the MAIL_DELIVERY macro define. By default, /usr/lib/sendmail -i
X  is used -- the option, -i, tells sendmail not to accept "." on a line
X  by itself as an end-of-file marker.
X***************
X*** 84,92 ****
X  Some MTA's, especially older ones like /bin/mail or execmail (xenix), do
X  not conform to RFC822 and provide the required headers: From: and Date:.
X  To remedy either #define OLD_MAILER in config.h or add the -D option
X! OLD_MAILER in the appropriate makefile: -DOLD_MAILER as part of the CFLAGS
X! variable.
X  
X  If your mailer does NOT have a verbose option, then you should not have
X  VERBOSE_ARG defined.  Otherwise, define it to be whatever the
X  verbose argument is for your mailer.
X--- 107,125 ----
X  Some MTA's, especially older ones like /bin/mail or execmail (xenix), do
X  not conform to RFC822 and provide the required headers: From: and Date:.
X  To remedy either #define OLD_MAILER in config.h or add the -D option
X! OLD_MAILER in the appropriate makefile: -DOLD_MAILER
X  
X+ If your machine talks to other computers via uucp _and_ you have the
X+ macro OLD_MAILER defined,  then you may want to define UUCP.  This will
X+ change the From: line to have your return address look like "host!user"
X+ rather than "user@host" (which is the default).
X+ 
X+ If your mailer does *NOT* like commas between addresses (smail, xenix and
X+ xenix machines), then you should define NO_COMMAS.
X+ 
X+ If your signal() returns void, SIGRET should be defined to be "void".
X+ This mostly applies to SVR3.  By default, SIGRET is defined to be "int".
X+ 
X  If your mailer does NOT have a verbose option, then you should not have
X  VERBOSE_ARG defined.  Otherwise, define it to be whatever the
X  verbose argument is for your mailer.
X***************
X*** 151,165 ****
X  
X  Maintenance:
X  
X! If you want to use dbx or any other debugger, the undocumented flag, -e
X! should be used as command line argument when you run the binary under
X! the debugger.  What this flag does is prevents your echo from being
X! turned off and leaving cbreak on, thus, keeping your tty in a sane state.
X! Beware of curses mode tho, since it must be turned off for that -- e.g.
X! the -e flag is overridden if you enter curses mode.  The -e flag can be
X! used in general usage anyway, but there's no difference known to the user
X! except for the fact that you can not type control characters.
X! 
X  If you have memory allocation checking and validation (sun 3.0+ ?) then
X  define M_DEBUG in the makefile (main.c) and add the library
X  /usr/lib/debug/malloc.o to the library list. Do this only if you are
X--- 184,198 ----
X  
X  Maintenance:
X  
X! If you want to use dbx or any other debugger, or to use your default tty
X! driver, -e may be used as command line argument when you run the program.
X! What this flag does is prevents your echo from being turned off and leaving
X! cbreak off, thus, keeping your tty in a sane state.
X! Beware of curses mode tho, since it will be automatically turned off for
X! that mode.  The -e flag is discouraged for future use (when automatic
X! filename completion is introduced in the next version and other keyboard
X! accelerators are introduced).
X!     
X  If you have memory allocation checking and validation (sun 3.0+ ?) then
X  define M_DEBUG in the makefile (main.c) and add the library
X  /usr/lib/debug/malloc.o to the library list. Do this only if you are
X***************
X*** 169,174 ****
X--- 202,211 ----
X  the sunwindows program will get a SIGXCPU (cpu time limit exceeded)
X  because of the large amount of opening and closing large pixrects and
X  devices.  For this reason, SIGXPCPU is is caught in main.c.
X+ 
X+ The "warning" variable may be set (at runtime in your .mushrc or as
X+ a command: "set warning") to aid in finding runtime errors that aren't
X+ fatal.
X  
X  If you ever get "Message N has bad date: <date string>" then note
X  the FORMAT of that date and edit dates.c.  There are a number of
X*** OLD/bind.c	Fri Jun 10 12:38:06 1988
X--- bind.c	Tue Jun 28 21:37:49 1988
X***************
X*** 185,191 ****
X  {
X      char buf[MAX_BIND_LEN], buf2[256];
X      register int x;
X!     int (*oldint)(), (*oldquit)();
X      int unbind = (argv && **argv == 'u');
X      int ret = -1; /* return value */
X  
X--- 185,191 ----
X  {
X      char buf[MAX_BIND_LEN], buf2[256];
X      register int x;
X!     SIGRET (*oldint)(), (*oldquit)();
X      int unbind = (argv && **argv == 'u');
X      int ret = -1; /* return value */
X  
X*** OLD/bindings.h	Fri Jun 10 12:38:06 1988
X--- bindings.h	Tue Jun 28 21:37:49 1988
X***************
X*** 6,11 ****
X--- 6,14 ----
X  #define A_PREFIX_B	2
X  #define B_PREFIX_A	3
X  
X+ #ifdef NULL_MAP
X+ #undef NULL_MAP
X+ #endif /* NULL_MAP */
X  #define NULL_MAP	(struct cmd_map *)0
X  #define C_NULL		0
X  #define C_GOTO_MSG	1
X*** OLD/cmd_help	Thu May 12 21:14:24 1988
X--- cmd_help	Tue Jun 28 21:37:51 1988
X***************
X*** 162,168 ****
X  
X  %sort_help%
X  usage: sort [-] [d | a | s | S | R]
X!   d         sort according to date received
X    a         author (alphabetical)
X    s         subject ignoring Re: as part of the subject
X    R         subject (alphabetical)
X--- 162,168 ----
X  
X  %sort_help%
X  usage: sort [-] [d | a | s | S | R]
X!   d         sort according to date
X    a         author (alphabetical)
X    s         subject ignoring Re: as part of the subject
X    R         subject (alphabetical)
X***************
X*** 170,176 ****
X  The optional `-' flag will reverse the order of sorting
X  By default (no arguments), sort sorts messages by status:
X  New, unread messages are first, followed by preserved messages
X! and finally the deleted messages are placed at the end
X  %%
X  
X  %pick%
X--- 170,180 ----
X  The optional `-' flag will reverse the order of sorting
X  By default (no arguments), sort sorts messages by status:
X  New, unread messages are first, followed by preserved messages
X! and finally the deleted messages are placed at the end.
X! 
X! If "date_received" is set, sorting by date is sorted by
X! the date you received the message.  Otherwise, messages
X! are sorted by date sent by the original author.
X  %%
X  
X  %pick%
X***************
X*** 280,303 ****
X  
X  %headers%
X  usage: headers [+ | - | N] [-H:c]
X! print out a screenful of headers.
X! +  print the next screenful.
X! -  print the previous screenful.
X! N  (where N is a number) print a screenful starting at N.
X! set show_deleted to list deleted messages.
X! cmd h headers        look like UCB-Mail
X! cmd H Headers        show deleted messages (or set show_deleted)
X! cmd z headers +      `z' is next screenful
X  
X! Arguments to the headers command include -H:c where `c' is one of
X!     n    just print messages headers of NEW messages
X      d    deleted messages
X      u    unread messages
X      o    old messages
X!     r    messages that have been replied to
X      a    all messages (mostly for the command line argument -H:c)
X! 
X! piping to headers will print the headers of the "output" messages.
X  %%
X  
X  %hdr_format%
X--- 284,308 ----
X  
X  %headers%
X  usage: headers [+ | - | N] [-H:c]
X!      print out a screenful of headers.
X  
X! Arguments include:
X!     +  print the next screenful (or use the 'z' command).
X!     -  print the previous screenful (or use 'z-' ).
X!     N  print a screenful starting at message number N.
X! 
X! "set show_deleted" to list deleted messages.
X! 
X! headers -H:c where `c' is one of
X!     n    new messages
X      d    deleted messages
X      u    unread messages
X      o    old messages
X!     r    replied-to messages
X!     s    saved messages
X!     p    preserved messages
X      a    all messages (mostly for the command line argument -H:c)
X! The command, ":r" is equivalent to "headers -H:r"
X  %%
X  
X  %hdr_format%
X*** OLD/commands.c	Thu May 12 21:14:26 1988
X--- commands.c	Tue Jul  5 12:08:11 1988
X***************
X*** 107,113 ****
X      }
X      if (x)
X  	if (!strcmp(p, "top"))
X! 	    turnon(flg, TOP);
X  	else if (*p == '+') {
X  	    turnon(flg, NO_PAGE);
X  	    turnon(flg, NO_HEADER);
X--- 107,113 ----
X      }
X      if (x)
X  	if (!strcmp(p, "top"))
X! 	    turnon(flg, M_TOP);
X  	else if (*p == '+') {
X  	    turnon(flg, NO_PAGE);
X  	    turnon(flg, NO_HEADER);
X***************
X*** 124,130 ****
X  				    isoff(msg[current_msg].m_flags, UNREAD))
X  	    current_msg++;
X  	if (p && (*p == '-' || !strcmp(p, "previous"))) {
X! 	    while (--current_msg >= 0 && ison(msg[current_msg].m_flags, DELETE))
X  		;
X  	    if (current_msg < 0) {
X  		print("No previous message.\n");
X--- 124,132 ----
X  				    isoff(msg[current_msg].m_flags, UNREAD))
X  	    current_msg++;
X  	if (p && (*p == '-' || !strcmp(p, "previous"))) {
X! 	    while (--current_msg >= 0 &&
X! 		(ison(msg[current_msg].m_flags, DELETE) ||
X! 		 ison(msg[current_msg].m_flags, SAVED)))
X  		;
X  	    if (current_msg < 0) {
X  		print("No previous message.\n");
X***************
X*** 141,147 ****
X  	    /* "type" or "print" prints the current only -- "next" goes on.. */
X  	    if (!p || !*p || *p == 'n')
X  		while (current_msg < msg_cnt &&
X! 		    ison(msg[current_msg].m_flags, DELETE))
X  			current_msg++;
X  	    if (current_msg >= msg_cnt) {
X  		print("No more messages.\n");
X--- 143,150 ----
X  	    /* "type" or "print" prints the current only -- "next" goes on.. */
X  	    if (!p || !*p || *p == 'n')
X  		while (current_msg < msg_cnt &&
X! 		    (ison(msg[current_msg].m_flags, DELETE) ||
X! 		     ison(msg[current_msg].m_flags, SAVED)))
X  			current_msg++;
X  	    if (current_msg >= msg_cnt) {
X  		print("No more messages.\n");
X***************
X*** 207,213 ****
X      register FILE	*pp;
X      register long 	flags = 0;
X      char		print_cmd[128], *printer, c, *cmd;
X!     int			total = 0, (*oldint)(), (*oldquit)();
X  
X      turnon(flags, NO_IGNORE);
X      if (!(printer = do_set(set_options, "printer")) || !*printer)
X--- 210,217 ----
X      register FILE	*pp;
X      register long 	flags = 0;
X      char		print_cmd[128], *printer, c, *cmd;
X!     int			total = 0;
X!     SIGRET		(*oldint)(), (*oldquit)();
X  
X      turnon(flags, NO_IGNORE);
X      if (!(printer = do_set(set_options, "printer")) || !*printer)
X***************
X*** 319,345 ****
X  	turnon(flg, NO_HEADER);
X      else
X  	turnon(flg, UPDATE_STATUS);
X-     if (do_set(set_options, "keepsave"))
X- 	firstchar = 'c';
X      for (n = msg_number = 0; msg_number < msg_cnt; msg_number++)
X  	if (msg_bit(list, msg_number)) {
X              print("%sing msg %d... ",
X  		(firstchar == 's')? "Sav" : "Writ", msg_number+1);
X  	    print_more("(%d lines)\n", copy_msg(msg_number, mail_fp, flg));
X- 	    /* only mark "deleted" if mailfile is /usr/spool/mail and
X- 	     * we're not "copying.  If keepsave is set, then firstchar
X- 	     * will have already been changed to 'c'
X- 	     */
X- 	    if (!strcmp(mailfile, spoolfile) && firstchar != 'c' &&
X- 		isoff(glob_flags, READ_ONLY))
X- 		turnon(msg[msg_number].m_flags, DELETE);
X  	    n++;
X  	}
X      fclose(mail_fp);
X      print_more("%s %d msg%s to %s\n",
X  	    (*mode == 'a')? "Appended" : "Saved", n, (n != 1)? "s": "", file);
X-     if (!strcmp(mailfile, spoolfile))
X- 	turnon(glob_flags, DO_UPDATE);
X  #ifdef SUNTOOL
X      if (istool) {
X  	unlock_cursors();
X--- 323,342 ----
X  	turnon(flg, NO_HEADER);
X      else
X  	turnon(flg, UPDATE_STATUS);
X      for (n = msg_number = 0; msg_number < msg_cnt; msg_number++)
X  	if (msg_bit(list, msg_number)) {
X              print("%sing msg %d... ",
X  		(firstchar == 's')? "Sav" : "Writ", msg_number+1);
X  	    print_more("(%d lines)\n", copy_msg(msg_number, mail_fp, flg));
X  	    n++;
X+ 	    if (isoff(msg[msg_number].m_flags, SAVED) && firstchar != 'c') {
X+ 		turnon(glob_flags, DO_UPDATE);
X+ 		turnon(msg[msg_number].m_flags, SAVED);
X+ 	    }
X  	}
X      fclose(mail_fp);
X      print_more("%s %d msg%s to %s\n",
X  	    (*mode == 'a')? "Appended" : "Saved", n, (n != 1)? "s": "", file);
X  #ifdef SUNTOOL
X      if (istool) {
X  	unlock_cursors();
X***************
X*** 414,420 ****
X      do  {
X  	if (cdpath) {
X  	    char c;
X! 	    if (p2 = any(cdpath, " \t"))
X  		c = *p2, *p2 = 0;
X  	    (void) sprintf(buf, "%s/%s", cdpath, p);
X  	    if (cdpath = p2) /* assign and compare to NULL */
X--- 411,417 ----
X      do  {
X  	if (cdpath) {
X  	    char c;
X! 	    if (p2 = any(cdpath, " \t:"))
X  		c = *p2, *p2 = 0;
X  	    (void) sprintf(buf, "%s/%s", cdpath, p);
X  	    if (cdpath = p2) /* assign and compare to NULL */
X***************
X*** 514,520 ****
X      /* goto next available message if current was just deleted.
X       * If there are no more messages, turnoff prnt_next.
X       */
X!     if (!iscurses && !undel && ison(msg[current_msg].m_flags, DELETE))
X  	next_msg();
X  
X      if (prnt_next && !undel && !iscurses)
X--- 511,519 ----
X      /* goto next available message if current was just deleted.
X       * If there are no more messages, turnoff prnt_next.
X       */
X!     if (!iscurses && !undel &&
X! 	ison(msg[current_msg].m_flags, DELETE) ||
X! 	ison(msg[current_msg].m_flags, SAVED))
X  	next_msg();
X  
X      if (prnt_next && !undel && !iscurses)
X***************
X*** 602,612 ****
X  	error(buf);
X  	return -1;
X      }
X!     turnon(glob_flags, IGN_SIGS);
X!     while (fgets(buf, 127, pp))
X! 	wprint(buf);
X      (void) pclose(pp);
X!     turnoff(glob_flags, IGN_SIGS);
X      return 0;
X  }
X  
X--- 601,611 ----
X  	error(buf);
X  	return -1;
X      }
X!     (void) do_pager(NULL, TRUE);
X!     while (fgets(buf, 127, pp) && do_pager(buf, FALSE) != EOF)
X! 	;
X      (void) pclose(pp);
X!     (void) do_pager(NULL, FALSE);
X      return 0;
X  }
X  
X*** OLD/curs_io.c	Fri Jun 10 12:38:09 1988
X--- curs_io.c	Tue Jun 28 21:37:56 1988
X***************
X*** 54,59 ****
X--- 54,61 ----
X      register int c, literal_next = FALSE;
X      int count = offset;
X  
X+     fflush(stdout); /* make sure everything is flushed before getting input */
X+ 
X      while ((c = getchar()) != '\n' && c != '\r' && c != EOF &&
X  	isoff(glob_flags, WAS_INTR)) {
X  	/* echo isn't set, so whatever the character, enter it */
X*** OLD/curses.c	Thu May 12 21:14:28 1988
X--- curses.c	Tue Jun 28 21:37:59 1988
X***************
X*** 341,347 ****
X  		    (c == C_DELETE_MSG || c == C_DELETE_LIST)? "":"un", list);
X  		    putchar('\n');
X  		}
X! 		if (ison(msg[current_msg].m_flags, DELETE))
X  		    (void) next_msg();
X  		if (isoff(msg[current_msg].m_flags, DELETE) &&
X  		    do_set(set_options, "autoprint"))
X--- 341,348 ----
X  		    (c == C_DELETE_MSG || c == C_DELETE_LIST)? "":"un", list);
X  		    putchar('\n');
X  		}
X! 		if (ison(msg[current_msg].m_flags, DELETE) ||
X! 		    ison(msg[current_msg].m_flags, SAVED))
X  		    (void) next_msg();
X  		if (isoff(msg[current_msg].m_flags, DELETE) &&
X  		    do_set(set_options, "autoprint"))
X***************
X*** 471,477 ****
X  	/* change to a new folder */
X  	when C_FOLDER :
X  	    for (;;) {
X! 		int (*oldint)(), (*oldquit)();
X  		on_intr();
X  		print("New folder (?=list): ");
X  		c = Getstr(file, COLS-22, 0);
X--- 472,478 ----
X  	/* change to a new folder */
X  	when C_FOLDER :
X  	    for (;;) {
X! 		SIGRET (*oldint)(), (*oldquit)();
X  		on_intr();
X  		print("New folder (?=list): ");
X  		c = Getstr(file, COLS-22, 0);
X***************
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--- 719,725 ----
X      int n;
X  
X      for (n = 0; n < COLS; n++)
X! 	if ((buf[n] = (mvinch(line, n) & A_CHARTEXT)) == '\0')
X  	    break;
X      buf[n] = '\0';
X  #endif /* A_CHARTEXT */
X*** OLD/dates.c	Wed Mar  9 12:26:28 1988
X--- dates.c	Tue Jun 28 21:37:59 1988
X***************
X*** 80,92 ****
X       */
X  
X      /* else, get the "date" line, if that fails, get the date in "From" line */
X!     if ((p = header_field(n, "date")) && (p2 = parse_date(p)))
X  	return p2;
X  
X!     (void) fseek(tmpf, msg[n].m_offset, L_SET);
X!     (void) fgets(line, BUFSIZ, tmpf);
X!     if (!(p = index(line, ' ')) || !(p2 = index(p+1, ' ')))
X  	return NULL;
X      p = p2;
X  
X      if (!(p2 = parse_date(p)))
X--- 80,97 ----
X       */
X  
X      /* else, get the "date" line, if that fails, get the date in "From" line */
X!     if (
X! #ifndef MSG_SEPARATOR
X! 	isoff(glob_flags, DATE_RECV) &&
X! #endif /* MSG_SEPARATOR */
X! 	(p = header_field(n, "date")) && (p2 = parse_date(p)))
X  	return p2;
X  
X! #ifndef MSG_SEPARATOR
X!     if (fseek(tmpf, msg[n].m_offset, L_SET) == -1 || !fgets(line, BUFSIZ, tmpf)
X!     || !(p = index(line, ' ')) || !(p2 = index(p+1, ' ')))
X  	return NULL;
X+ #endif /* MSG_SEPARATOR */
X      p = p2;
X  
X      if (!(p2 = parse_date(p)))
X*** OLD/doproc.c	Sat Apr  2 16:13:34 1988
X--- doproc.c	Tue Jun 28 21:38:00 1988
X***************
X*** 192,198 ****
X  		print("Type in Main Panel Window a filename to save message");
X  		return;
X  	    }
X! 	else if (value <= 1) {
X  	    register char *p = panel_get_value(file_item);
X  	    register char *p2 = panel_get_value(msg_num_item);
X  	    if ((!p || !*p) && (!(p = do_set(set_options, "mbox")) || !*p))
X--- 192,198 ----
X  		print("Type in Main Panel Window a filename to save message");
X  		return;
X  	    }
X! 	else if (value == 0) {
X  	    register char *p = panel_get_value(file_item);
X  	    register char *p2 = panel_get_value(msg_num_item);
X  	    if ((!p || !*p) && (!(p = do_set(set_options, "mbox")) || !*p))
X*** OLD/execute.c	Fri Jun 10 12:38:11 1988
X--- execute.c	Tue Jun 28 21:38:01 1988
X***************
X*** 22,30 ****
X      union wait status;
X  #endif /* SYSV */
X  #ifdef SIGCONT
X!     int	(*oldstop)(), (*oldcont)();
X  #endif /* SIGCONT */
X!     int pid, (*oldint)(), (*oldquit)();
X  
X  #ifdef SUNTOOL
X      if (istool) {
X--- 22,31 ----
X      union wait status;
X  #endif /* SYSV */
X  #ifdef SIGCONT
X!     SIGRET (*oldstop)(), (*oldcont)();
X  #endif /* SIGCONT */
X!     int pid;
X!     SIGRET (*oldint)(), (*oldquit)();
X  
X  #ifdef SUNTOOL
X      if (istool) {
X***************
X*** 81,86 ****
X--- 82,88 ----
X      turnoff(glob_flags, IGN_SIGS);
X  }
X  
X+ SIGRET
X  sigchldcatcher()
X  {
X  #ifdef SUNTOOL
X*** OLD/hdrs.c	Thu Apr 28 22:48:02 1988
X--- hdrs.c	Tue Jul  5 12:46:40 1988
X***************
X*** 51,57 ****
X  register char **argv, list[];
X  {
X      register int   pageful = 0, fnd;
X!     int 	   (*oldint)(), (*oldquit)(), show_deleted;
X      static int     cnt;
X      register char  *p;
X      char 	   first_char = (argc) ? **argv: 'h';
X--- 51,58 ----
X  register char **argv, list[];
X  {
X      register int   pageful = 0, fnd;
X!     SIGRET 	   (*oldint)(), (*oldquit)();
X!     int		   show_deleted;
X      static int     cnt;
X      register char  *p;
X      char 	   first_char = (argc) ? **argv: 'h';
X***************
X*** 191,197 ****
X  	    when 'o': special = OLD;
X  	    when 'd': special = DELETE;
X  	    when 'r': special = REPLIED;
X! 	    otherwise: print("choose from n,u,o,d,r, or a"); return -1;
X  	}
X      if (debug)
X  	(void) check_flags(special);
X--- 192,200 ----
X  	    when 'o': special = OLD;
X  	    when 'd': special = DELETE;
X  	    when 'r': special = REPLIED;
X! 	    when 's': special = SAVED;
X! 	    when 'p': special = PRESERVE;
X! 	    otherwise: print("choose from n,u,o,d,r,s,p or a"); return -1;
X  	}
X      if (debug)
X  	(void) check_flags(special);
X***************
X*** 249,267 ****
X  char *
X  compose_hdr(cnt)
X  {
X!     static char buf[256];
X!     register char *p, *b;
X!     char from[256], subject[256], date[17], lines[16], chars[16], line[256];
X      char to[256], addr[256], name[256], status[2];
X!     char Day[3], Mon[4], Tm[8], Yr[5], Wkday[4], *date_p;
X  
X      /* status of the message */
X      if (ison(msg[cnt].m_flags, DELETE))
X  	status[0] = '*';
X-     else if (ison(msg[cnt].m_flags, OLD) && ison(msg[cnt].m_flags, UNREAD))
X- 	status[0] = 'U';
X      else if (ison(msg[cnt].m_flags, PRESERVE))
X  	status[0] = 'P';
X      else if (isoff(msg[cnt].m_flags, UNREAD))
X  	status[0] = ' ';
X      else
X--- 252,273 ----
X  char *
X  compose_hdr(cnt)
X  {
X!     static char		buf[256];
X!     register char	*p, *p2, *b;
X!     int			len, do_pad = FALSE, val, pad, got_dot, isauthor = 0;
X!     char from[256], subject[256], date[17], lines[16], chars[16];
X      char to[256], addr[256], name[256], status[2];
X!     char Day[3], Mon[4], Tm[8], Yr[5], Wkday[4], *date_p, *p3;
X  
X      /* status of the message */
X      if (ison(msg[cnt].m_flags, DELETE))
X  	status[0] = '*';
X      else if (ison(msg[cnt].m_flags, PRESERVE))
X  	status[0] = 'P';
X+     else if (ison(msg[cnt].m_flags, SAVED))
X+ 	status[0] = 'S';
X+     else if (ison(msg[cnt].m_flags, OLD) && ison(msg[cnt].m_flags, UNREAD))
X+ 	status[0] = 'U';
X      else if (isoff(msg[cnt].m_flags, UNREAD))
X  	status[0] = ' ';
X      else
X***************
X*** 273,279 ****
X  	status[1] = ' ';
X  
X      to[0] = from[0] = subject[0] = date[0] = lines[0] = chars[0] = addr[0] =
X!     name[0] = line[0] = Day[0] = Mon[0] = Tm[0] = Yr[0] = Wkday[0] = 0;
X  
X      /* who's the message to */
X      if ((p = header_field(cnt, "to")) ||
X--- 279,285 ----
X  	status[1] = ' ';
X  
X      to[0] = from[0] = subject[0] = date[0] = lines[0] = chars[0] = addr[0] =
X!     name[0] = Day[0] = Mon[0] = Tm[0] = Yr[0] = Wkday[0] = 0;
X  
X      /* who's the message to */
X      if ((p = header_field(cnt, "to")) ||
X***************
X*** 281,306 ****
X  	(p = header_field(cnt, "apparently-to")))
X  	Strncpy(to, p);
X  
X!     /* who the messages is from--
X!      * %f		From field
X!      * %a		From address
X!      * %n		From name
X       */
X      if (!(p = header_field(cnt, "from"))) {
X! 	/* if all else fails, then get the first token in "From" line */
X! 	register char *p2;
X! 	p = ""; /* just in case */
X! 	if (fseek(tmpf, msg[cnt].m_offset, L_SET) == -1 ||
X! 	    !(p2 = fgets(line, sizeof(line), tmpf))) {
X! 	    error("fseek in %s (msg %d, folder=%s)", tempfile, cnt+1, mailfile);
X! 	    turnon(glob_flags, READ_ONLY);
X! 	} else if (!(p = index(p2, ' ')))
X! 	    print("Fudged \"From\" line: %s", p2);
X! 	else if (p2 = any(++p, " \t"))
X! 	    *p2 = 0;
X      }
X!     skipspaces(0);
X!     (void) no_newln(p);
X      /* if the "from" line produced the user's login name, then the message is
X       * from the user -- attempt to give more useful information by telling
X       * to whom the message was sent.  This is not possible if the "to" header
X--- 287,321 ----
X  	(p = header_field(cnt, "apparently-to")))
X  	Strncpy(to, p);
X  
X!     /*
X!      * Read the "From " line first. If it's from us, login's will match.
X!      * Also, we have the date received at our disposal.
X       */
X+ #ifndef MSG_SEPARATOR
X+     p = ""; /* just in case */
X+     if (fseek(tmpf, msg[cnt].m_offset, L_SET) == -1 ||
X+ 	!(p2 = fgets(from, sizeof(from), tmpf))) {
X+ 	error("fseek in %s (msg %d, folder=%s)", tempfile, cnt+1, mailfile);
X+ 	turnon(glob_flags, READ_ONLY);
X+     } else if (!(p = index(p2, ' ')))
X+ 	print("Fudged \"From\" line: %s", p2);
X+     else {
X+ 	skipspaces(1);
X+ 	if (p2 = any(p, " \t")) {
X+ 	    /* p now points to null terminated login name */
X+ 	    for (*p2++ = 0; isspace(*p2); p2++)
X+ 		; /* p2 points to date received */
X+ 	    Strncpy(buf, p2); /* buf is only used till "date" is filled */
X+ 	    p2 = buf;
X+ 	}
X+     }
X+ #else
X      if (!(p = header_field(cnt, "from"))) {
X! 	wprint("Error in msg %d's format. No \"From:\" line.\n", cnt+1);
X! 	return "               "; /* Real bad news here.... */
X      }
X! #endif /* MSG_SEPARATOR */
X! 
X      /* if the "from" line produced the user's login name, then the message is
X       * from the user -- attempt to give more useful information by telling
X       * to whom the message was sent.  This is not possible if the "to" header
X***************
X*** 307,325 ****
X       * failed to get info (which is probably impossible).
X       */
X      if (!strcmp(p, login) && *to) {
X! 	(void) strcpy(from, "TO: ");
X! 	(void) strncpy(from+4, to, sizeof(from)-4), from[sizeof(from)-4] = 0;
X! 	(void) get_name_n_addr(from+4, name+4, addr+4);
X! 	if (name[4])
X! 	    (void) strncpy(name,"TO: ",4); /* strncpy doesn't null terminate */
X  	if (addr[4])
X! 	    (void) strncpy(addr,"TO: ",4); /* don't overwrite name there */
X      } else {
X! 	Strncpy(from, p);
X  	(void) get_name_n_addr(from, name, addr);
X      }
X  
X!     if (date_p = msg_date(cnt))
X  	/* don't take weekday unless specified explicitly.  See 'D' below */
X  	date_to_string(date_p, Yr, Mon, Day, NULL, Tm, date);
X  
X--- 322,355 ----
X       * failed to get info (which is probably impossible).
X       */
X      if (!strcmp(p, login) && *to) {
X! 	isauthor = TRUE;
X! 	(void) get_name_n_addr(to, name+4, addr+4);
X  	if (addr[4])
X! 	    (void) strncpy(addr, "TO: ", 4);
X! 	if (name[4]) {  /* check to see if a name got added */
X! 	    (void) strncpy(name, "TO: ", 4);
X! 	    Strncpy(from, name);
X! 	} else
X! 	    Strncpy(from, addr);
X      } else {
X! #ifndef MSG_SEPARATOR
X! 	if (p = header_field(cnt, "from"))
X! #endif /* MSG_SEPARATOR */
X! 	    Strncpy(from, p);
X  	(void) get_name_n_addr(from, name, addr);
X      }
X  
X! #ifndef MSG_SEPARATOR
X!     /* hackers note: p2 already points to a ctime(3) string with weekday
X!      * name and month and all that -- I'm inefficiently converting to
X!      * a different format just to be converted back again later. Change this.
X!      */
X!     if (ison(glob_flags, DATE_RECV))
X! 	date_p = parse_date(p2);
X!     else
X! #endif /* MSG_SEPARATOR */
X! 	date_p = msg_date(cnt);
X!     if (date_p)
X  	/* don't take weekday unless specified explicitly.  See 'D' below */
X  	date_to_string(date_p, Yr, Mon, Day, NULL, Tm, date);
X  
X***************
X*** 357,364 ****
X  	else if (*p == '%') {
X  	    char fmt[64];
X  	    register char *p2 = fmt;
X- 	    int len, got_dot = FALSE;
X  
X  	    *p2++ = '%';
X  	    if (p[1] != '-')
X  		*p2++ = '-';
X--- 387,395 ----
X  	else if (*p == '%') {
X  	    char fmt[64];
X  	    register char *p2 = fmt;
X  
X+ 	    /* first check for string padding: %5n, %.4a, %10.5f, %-.3l etc. */
X+ 	    do_pad = pad = val = got_dot = 0;
X  	    *p2++ = '%';
X  	    if (p[1] != '-')
X  		*p2++ = '-';
X***************
X*** 366,389 ****
X  		*++p;
X  	    while (isdigit(*++p) || !got_dot && *p == '.') {
X  		if (*p == '.')
X! 		    got_dot = TRUE;
X  		*p2++ = *p;
X  	    }
X  	    if (!got_dot && isdigit(p[-1])) {
X- 		int val;
X  		*p2 = 0; /* assure null termination */
X  		val = atoi(fmt+1);
X! 		p2 += strlen(sprintf(p2, ".%d", (val >= 0 ? val : -val)));
X  	    }
X  	    *p2++ = 's', *p2 = 0;
X  	    switch (*p) {
X! 		case 'f': p2 = from;
X  		when 'a':
X  		    if (!*(p2 = addr))
X  			p2 = from;
X  		when 'n':
X  		    if (!*(p2 = name))
X! 			p2 = from;
X  		when '%': p2 = "%";
X  		when 't': p2 = to;
X  		when 's': p2 = subject;
X--- 397,425 ----
X  		*++p;
X  	    while (isdigit(*++p) || !got_dot && *p == '.') {
X  		if (*p == '.')
X! 		    got_dot = TRUE, val = pad, pad = 0;
X! 		else
X! 		    pad = pad * 10 + *p - '0';
X  		*p2++ = *p;
X  	    }
X  	    if (!got_dot && isdigit(p[-1])) {
X  		*p2 = 0; /* assure null termination */
X  		val = atoi(fmt+1);
X! 		if (val < 0)
X! 		    val = -val;
X! 		p2 += strlen(sprintf(p2, ".%d", val));
X  	    }
X+ 	    pad = min(pad, val);
X  	    *p2++ = 's', *p2 = 0;
X  	    switch (*p) {
X! 		case 'f': p2 = from, do_pad = TRUE;
X  		when 'a':
X  		    if (!*(p2 = addr))
X  			p2 = from;
X+ 		    do_pad = TRUE;
X  		when 'n':
X  		    if (!*(p2 = name))
X! 			p2 = from, do_pad = TRUE;
X  		when '%': p2 = "%";
X  		when 't': p2 = to;
X  		when 's': p2 = subject;
X***************
X*** 406,411 ****
X--- 442,465 ----
X  		}
X  		otherwise: continue; /* unknown formatting char */
X  	    }
X+ 	    if (do_pad && pad && strlen(p2) > pad) {
X+ 		char *old_p2 = p2;
X+ 		/* if addr is too long, move pointer forward till the
X+ 		 * "important" part is readable only for ! paths/addresses.
X+ 		 */
X+ 		while (p3 = index(p2, '!')) {
X+ 		    p2 = p3+1;
X+ 		    if (strlen(p2) + isauthor*4 < pad) {
X+ 			if (isauthor && (p2 -= 4) < old_p2)
X+ 			    p2 = old_p2;
X+ 			break;
X+ 		    }
X+ 		}
X+ 		if (isauthor && p2 > old_p2+4 && !p3 && strlen(p2) + 4 > pad)
X+ 		    p2 -= 4;
X+ 		if (old_p2 != p2 && isauthor)
X+ 		    (void) strncpy(p2, "TO: ", 4); /* doesn't null terminate */
X+ 	    }
X  	    len = strlen(sprintf(b, fmt, p2));
X  	    cnt += len, b += len;
X  	    /* Get around a bug in 5.5 IBM RT which pads with NULL's not ' ' */
X***************
X*** 816,836 ****
X  	else if (*addr && Alts && *Alts && chk_two_lists(login,addr, "!@%=")) {
X  	    /* To be in this block, there must be a remote address */
X  	    i = 0; /* initialize 'i' in case while loop is skipped */
X- #ifndef SYSV
X  	    /* see if the hostnames match our hostname. */
X  	    while (i < MAX_HOST_NAMES && ourname[i])
X  		if (chk_two_lists(addr, ourname[i++], "!@%="))
X  		    break;
X- #endif /* SYSV */
X  	    /* If one of the hostnames in the address is one of user's
X  	     * hostnames, remove this address. If the alternates
X  	     * hostnames listed contains a hostname in the address, remove
X  	     * from the list.
X  	     */
X! 	    if (
X! #ifndef SYSV
X! 		i < MAX_HOST_NAMES && ourname[i] ||
X! #endif /* SYSV */
X  		*Alts == '*' || !chk_two_lists(addr, Alts, "!@%= \t,"))
X  		    rm_me = TRUE;
X  	}
X--- 870,885 ----
X  	else if (*addr && Alts && *Alts && chk_two_lists(login,addr, "!@%=")) {
X  	    /* To be in this block, there must be a remote address */
X  	    i = 0; /* initialize 'i' in case while loop is skipped */
X  	    /* see if the hostnames match our hostname. */
X  	    while (i < MAX_HOST_NAMES && ourname[i])
X  		if (chk_two_lists(addr, ourname[i++], "!@%="))
X  		    break;
X  	    /* If one of the hostnames in the address is one of user's
X  	     * hostnames, remove this address. If the alternates
X  	     * hostnames listed contains a hostname in the address, remove
X  	     * from the list.
X  	     */
X! 	    if (i < MAX_HOST_NAMES && ourname[i] ||
X  		*Alts == '*' || !chk_two_lists(addr, Alts, "!@%= \t,"))
X  		    rm_me = TRUE;
X  	}
X*** OLD/init.c	Thu Apr  7 22:46:51 1988
X--- init.c	Tue Jun 28 21:38:07 1988
X***************
X*** 101,113 ****
X  #include <netdb.h>
X  #endif /* BSD */
X  
X  void
X  init()
X  {
X!     char 		*home;
X      extern char		*getlogin();
X  #ifdef SYSV
X      extern struct passwd *getpwuid();  /* sys-v forgot this in pwd.h! */
X  #else
X      char ourhost[128];
X  #endif /* SYSV */
X--- 101,119 ----
X  #include <netdb.h>
X  #endif /* BSD */
X  
X+ #ifdef SYSV
X+ #include <sys/utsname.h>
X+ #endif /* SYSV */
X+ 
X  void
X  init()
X  {
X!     char 		*home, *realname;
X      extern char		*getlogin();
X+     char		buf[MAXPATHLEN];
X  #ifdef SYSV
X      extern struct passwd *getpwuid();  /* sys-v forgot this in pwd.h! */
X+     struct utsname ourhost;
X  #else
X      char ourhost[128];
X  #endif /* SYSV */
X***************
X*** 118,124 ****
X      struct hostent 	*hp;
X  #endif /* BSD */
X  
X!     home = getenv ("HOME");
X  
X      if (!(entry = getpwuid(getuid())))
X  	if (p = getlogin())
X--- 124,131 ----
X      struct hostent 	*hp;
X  #endif /* BSD */
X  
X!     home = getenv("HOME");
X!     realname = getenv("NAME");
X  
X      if (!(entry = getpwuid(getuid())))
X  	if (p = getlogin())
X***************
X*** 131,136 ****
X--- 138,147 ----
X  	strdup(login, entry->pw_name);
X  	if (!home || !*home)
X  	    home = entry->pw_dir;
X+ 	if (!realname && (realname = entry->pw_gecos)) {
X+ 	    if (p = index(realname, ','))
X+ 		*p = 0;
X+ 	}
X  	endpwent();
X      }
X      if (!home || !*home || Access(home, W_OK)) {
X***************
X*** 139,154 ****
X  	else
X  	    print("No home!? ");
X  	print_more("Using \"%s\" as home.\n", ALTERNATE_HOME);
X!     } else {
X! 	char buf[MAXPATHLEN];
X! 	cmd_line(sprintf(buf, "set home=\"%s\"", home), msg_list);
X!     }
X      crt = 25;
X      screen = 18;
X      escape = DEF_ESCAPE;
X      prompt = DEF_PROMPT;
X  
X! #ifndef SYSV
X      (void) gethostname(ourhost, sizeof ourhost);
X      if (!(hp = gethostbyname(ourhost)))
X  	error("gethostbyname: %s", ourhost);
X--- 150,165 ----
X  	else
X  	    print("No home!? ");
X  	print_more("Using \"%s\" as home.\n", ALTERNATE_HOME);
X!     } else
X! 	(void) cmd_line(sprintf(buf,"set home=\"%s\"", home), msg_list);
X!     if (realname)
X! 	(void) cmd_line(sprintf(buf,"set realname=\"%s\"", realname), msg_list);
X      crt = 25;
X      screen = 18;
X      escape = DEF_ESCAPE;
X      prompt = DEF_PROMPT;
X  
X! #ifdef BSD
X      (void) gethostname(ourhost, sizeof ourhost);
X      if (!(hp = gethostbyname(ourhost)))
X  	error("gethostbyname: %s", ourhost);
X***************
X*** 156,166 ****
X--- 167,185 ----
X  	      p = hp->h_aliases[cnt++])
X  	ourname[cnt] = savestr(p);
X      endhostent();
X+ #endif /* BSD */
X+ #ifdef SYSV
X+     if (uname (&ourhost) >= 0)
X+ 	ourname[0] = savestr(ourhost.nodename);
X  #endif /* SYSV */
X  
X  #ifdef CURSES
X      init_bindings();
X  #endif /* CURSES */
X+ 
X+     if (ourname[0])
X+ 	(void) cmd_line(sprintf(buf,
X+ 			"set hostname=\"%s\"", ourname[0]), msg_list);
X  }
X  
X  /*
X***************
X*** 274,299 ****
X  		goto bad;
X  	    }
X  	    /* "lhs" is the left hand side of the equation
X! 	     * In this instance, we're doing case 2 above.
X  	     */
X  	    if (*lhs == '!') {
X- 		int tmp = argc;
X  		equals = FALSE;
X! 		if (!*++lhs)
X! 		    if (!(lhs = newargv[2])) {
X! 			print("%s: %d: syntax error: \"if ! <what?>\"\n",
X! 			    file, line_no);
X! 			goto bad;
X! 		    } else
X! 			tmp--;
X! 		if (tmp > 2) {
X! 		    print("%s: %d: syntax error: \"if !<expr> <more junk>\"\n",
X  			file, line_no);
X  		    goto bad;
X  		}
X! 	    } else if (argc > 2) {
X  		if (argc != 4) {
X! 		    print("%s: %d: argument count error: line has %d args.\n",
X  			file, line_no, argc);
X  		    goto bad;
X  		}
X--- 293,327 ----
X  		goto bad;
X  	    }
X  	    /* "lhs" is the left hand side of the equation
X! 	     * In this instance, we're doing case 2 above (check for negation).
X  	     */
X  	    if (*lhs == '!') {
X  		equals = FALSE;
X! 		if (!*++lhs && !(lhs = newargv[2])) {
X! 		    print("%s: line %d: syntax error: \"if ! <what?>\"\n",
X  			file, line_no);
X  		    goto bad;
X  		}
X! 	    }
X! 	    if (*lhs == '-' && (lhs[1] == 'e' || lhs[1] == 'z') && !lhs[2]) {
X! 		char *path;
X! 		int n = 1; /* ignore ENOENT, I'll handle it here */
X! 		struct stat statb;
X! 
X! 		/* check for existence or zero-length folders/files */
X! 		if (argc > 4) {
X! 		    print("%s: line %d: if %s \"filename\"\n",
X! 			file, line_no, lhs);
X! 		    goto bad;
X! 		}
X! 		path = getpath(newargv[argc-1], &n);
X! 		parsing = !equals ^ (n == -1 || n == 1 && lhs[1] == 'e' ||
X! 		    !stat(path, &statb) && (lhs[1] == 'e' || !statb.st_size));
X! 		goto bad; /* it's not bad, but we're done anyway */
X! 	    }
X! 	    if (equals && argc > 2) {
X  		if (argc != 4) {
X! 		    print("%s: %d: argument count error: %d args.\n",
X  			file, line_no, argc);
X  		    goto bad;
X  		}
X***************
X*** 301,307 ****
X  		if (!strcmp(newargv[2], "!="))
X  		    equals = FALSE;
X  		else if (strcmp(newargv[2], "==")) {
X! 		    print("%s: %d: use `==' or `!=' only.\n", file, line_no);
X  		    goto bad;
X  		}
X  		rhs = newargv[3];
X--- 329,335 ----
X  		if (!strcmp(newargv[2], "!="))
X  		    equals = FALSE;
X  		else if (strcmp(newargv[2], "==")) {
X! 		    print("%s: %d: use `==' or `!=' only.\n", file,line_no);
X  		    goto bad;
X  		}
X  		rhs = newargv[3];
X*** OLD/loop.c	Thu May 12 21:14:31 1988
X--- loop.c	Tue Jun 28 21:38:08 1988
X***************
X*** 58,64 ****
X  			   SIG_DFL
X  #endif /* SYSV */
X  			   );
X-     (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
X  
X      turnoff(glob_flags, IGN_SIGS);
X      if (hist_size == 0) /* if user didn't set history in .rc file */
X--- 58,63 ----
X***************
X*** 877,882 ****
X--- 876,886 ----
X      register int	list_num = TRUE, num_of_hists = hist_size;
X      register int	reverse = FALSE;
X      struct history	*hist = hist_tail;
X+ 
X+     if (!hist) {
X+ 	print("No history yet.\n");
X+ 	return;
X+     }
X  
X      while (*++argv && *argv[0] == '-') {
X  	n = 1;
X*** OLD/mail.c	Mon Jun 13 15:38:27 1988
X--- mail.c	Tue Jul  5 22:48:43 1988
X***************
X*** 32,38 ****
X  static char Subject[BUFSIZ],To[BUFSIZ],Cc[BUFSIZ],Bcc[BUFSIZ],in_reply_to[256];
X  static int killme;
X  static u_long flags;
X! static int (*oldterm)(), (*oldint)(), (*oldquit)();
X  static void send_it();
X  static jmp_buf cntrl_c_buf;
X  FILE *ed_fp;
X--- 32,38 ----
X  static char Subject[BUFSIZ],To[BUFSIZ],Cc[BUFSIZ],Bcc[BUFSIZ],in_reply_to[256];
X  static int killme;
X  static u_long flags;
X! static SIGRET (*oldterm)(), (*oldint)(), (*oldquit)();
X  static void send_it();
X  static jmp_buf cntrl_c_buf;
X  FILE *ed_fp;
X***************
X*** 155,161 ****
X  	turnoff(flgs, NEW_SUBJECT);
X  	if (subj = subject_to(current_msg, buf))
X  	    subj = strcpy(Subject, buf + 4*(lower(firstchar) != 'r'));
X!     } else if (isoff(flgs, NEW_SUBJECT) && do_set(set_options, "ask"))
X  	turnon(flgs, NEW_SUBJECT);
X      if (argv && *argv) {
X  	char buf[BUFSIZ];
X--- 155,162 ----
X  	turnoff(flgs, NEW_SUBJECT);
X  	if (subj = subject_to(current_msg, buf))
X  	    subj = strcpy(Subject, buf + 4*(lower(firstchar) != 'r'));
X!     } else if (isoff(flgs, NEW_SUBJECT) &&
X! 	(do_set(set_options, "ask") || do_set(set_options, "asksub")))
X  	turnon(flgs, NEW_SUBJECT);
X      if (argv && *argv) {
X  	char buf[BUFSIZ];
X***************
X*** 163,169 ****
X  	fix_up_addr(buf);
X  	to = &To[strlen(To)];
X  	if (*To)
X! 	    to += Strcpy(to-1, ", ") - 1;
X  	(void) strcpy(to, buf);
X  	to = To;
X      }
X--- 164,170 ----
X  	fix_up_addr(buf);
X  	to = &To[strlen(To)];
X  	if (*To)
X! 	    *to++ = ',', *to++ = ' ';
X  	(void) strcpy(to, buf);
X  	to = To;
X      }
X***************
X*** 410,416 ****
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--- 411,418 ----
X  	 */
X  	(void) setjmp(cntrl_c_buf);
X  	while (Getstr(line, sizeof(line), 0) > -1) {
X! 	    if (!istool) /* toolmode checks on a timer -- don't do it here */
X! 		(void) check_new_mail(); /* if new mail comes in, get it */
X  	    if ((i = add_to_letter(line)) <= 0)
X  		break;
X  	}
X***************
X*** 564,570 ****
X  	    if (!(p2 = do_set(set_options, p)))
X  		wprint("(%s isn't set)\n", p);
X  	    else
X! 		fprintf(ed_fp, "%s\n", p2);
X  	}
X  	when ':': {
X  	    char new[MAXMSGS_BITS];
X--- 566,572 ----
X  	    if (!(p2 = do_set(set_options, p)))
X  		wprint("(%s isn't set)\n", p);
X  	    else
X! 		putstring(p2, ed_fp);
X  	}
X  	when ':': {
X  	    char new[MAXMSGS_BITS];
X***************
X*** 851,860 ****
X  		return 1;
X  	    } else if (line[1] == '?') {
X  		register int x;
X! 		for (x = 0; tilde_commands[x]; x++)
X! 		    wprint("%s%s\n", escape, tilde_commands[x]);
X! 		wprint("%s%s\t\tbegin a line with a single %s\n",
X  		    escape, escape, escape);
X  #ifdef SUNTOOL
X  		if (istool)
X  		    (void) help(0, "compose", tool_help);
X--- 853,877 ----
X  		return 1;
X  	    } else if (line[1] == '?') {
X  		register int x;
X! 		if (!istool)
X! 		    (void) do_pager(NULL, TRUE); /* start pager */
X! 		for (x = 0; tilde_commands[x]; x++) {
X! 		    (void) sprintf(buf, "%s%s\n", escape, tilde_commands[x]);
X! 		    if (!istool) {
X! 			if (do_pager(buf, FALSE))
X! 			    break;
X! 		    } else
X! 			wprint(buf);
X! 		}
X! 		(void) sprintf(buf, "%s%s\t\tbegin a line with a single %s\n",
X  		    escape, escape, escape);
X+ 		if (istool)
X+ 		    wprint(buf);
X+ 		else {
X+ 		    if (tilde_commands[x] == NULL)
X+ 			(void) do_pager(buf, FALSE);
X+ 		    (void) do_pager(NULL, FALSE); /* end pager */
X+ 		}
X  #ifdef SUNTOOL
X  		if (istool)
X  		    (void) help(0, "compose", tool_help);
X***************
X*** 970,975 ****
X--- 987,993 ----
X      int next_file = 1; /* reserve files[0] for the mail delivery program */
X      char buf[3*BUFSIZ];
X      char expand = !do_set(set_options, "no_expand");
X+     int fork_err = 0;
X  
X      if (!istool) {
X  	(void) signal(SIGINT, oldint);
X***************
X*** 1047,1053 ****
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--- 1065,1071 ----
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, DO_FORTUNE)) &&
X  	isoff(glob_flags, REDIRECT) && isoff(flags, FORWARD))
X  	sign_letter(addr_list);
X  
X***************
X*** 1070,1079 ****
X  	}
X      }
X  
X! #ifdef OLD_MAILER
X      for (p = buf; p = index(p, ','); p++)
X  	*p = ' ';
X! #endif /* OLD_MAILER */
X  
X      Debug("mail command: %s\n", buf);
X  
X--- 1088,1097 ----
X  	}
X      }
X  
X! #ifdef NO_COMMAS
X      for (p = buf; p = index(p, ','); p++)
X  	*p = ' ';
X! #endif /* NO_COMMAS */
X  
X      Debug("mail command: %s\n", buf);
X  
X***************
X*** 1105,1117 ****
X  		break;
X  	    case -1:
X  		error("fork failed trying to send mail");
X  	    default:
X  		if (isoff(glob_flags, REDIRECT))
X  		    fclose(ed_fp);
X  #ifdef SUNTOOL
X                  if (istool) {
X! 		    wprint("Letter sent.");
X! 		    print("Letter sent.");
X  		    type_cursor(PIX_CLR);
X  		}
X  #endif /* SUNTOOL */
X--- 1123,1138 ----
X  		break;
X  	    case -1:
X  		error("fork failed trying to send mail");
X+ 		fork_err++;
X  	    default:
X  		if (isoff(glob_flags, REDIRECT))
X  		    fclose(ed_fp);
X  #ifdef SUNTOOL
X                  if (istool) {
X! 		    if (!fork_err) {
X! 			wprint("Letter sent.");
X! 			print("Letter sent.");
X! 		    }
X  		    type_cursor(PIX_CLR);
X  		}
X  #endif /* SUNTOOL */
X***************
X*** 1142,1165 ****
X  
X      /* Make folders conform to RFC-822 by adding From: and Date: headers.
X       * Some older mailers (binmail, execmail, delivermail), don't add
X!      * these headers to the MTA, so add them for OLD_MAILER systems.
X       */
X!     for (size = 0; size < next_file; size++) {
X  	time_t t;
X  #ifndef OLD_MAILER
X! 	if (size == 0)
X! 	    continue;
X  #endif /* OLD_MAILER */
X! 	(void) time(&t);
X! 	if (size > 0) {
X  #ifndef MSG_SEPARATOR
X! 	    fprintf(files[size], "From %s %s", login, ctime(&t));
X  #else /* MSG_SEPARATOR */
X! 	    fprintf(files[size], "%s\n", MSG_SEPARATOR);
X  #endif /* MSG_SEPARATOR */
X  	}
X- 	fprintf(files[size], "From: %s\n", login);
X- 	fprintf(files[size], "Date: %s", ctime(&t));
X      }
X  
X      /* first print users own message headers */
X--- 1163,1206 ----
X  
X      /* Make folders conform to RFC-822 by adding From: and Date: headers.
X       * Some older mailers (binmail, execmail, delivermail), don't add
X!      * these headers, so add them for #define OLD_MAILER
X       */
X!     {
X  	time_t t;
X+ 	char From_buf[256], *pF = From_buf;
X+ 	char *host = do_set(set_options, "hostname");
X+ 
X+ 	pF += Strcpy(From_buf, "From: ");
X+ 	if (!host)
X+ 	    host = ourname[0];
X+ #ifdef UUCP
X+ 	if (host && *host)
X+ 	    pF += strlen(sprintf(pF, "%s!", host));
X+ #endif /* UUCP */
X+ 	pF += Strcpy(pF, login);
X+ #ifndef UUCP
X+ 	if (host && *host)
X+ 	    pF += strlen(sprintf(pF, "@%s", host));
X+ #endif /* UUCP */
X+ 	if (p = do_set(set_options, "realname"))
X+ 	    pF += strlen(sprintf(pF, " (%s)", p));
X+ 	*pF++ = '\n', *pF++ = 0;
X+ 	(void) time(&t);
X+ 	for (size = 0; size < next_file; size++) {
X  #ifndef OLD_MAILER
X! 	    if (size == 0)
X! 		continue;
X  #endif /* OLD_MAILER */
X! 	    if (size > 0) {
X  #ifndef MSG_SEPARATOR
X! 		fprintf(files[size], "From %s %s", login, ctime(&t));
X  #else /* MSG_SEPARATOR */
X! 		fprintf(files[size], "%s\n", MSG_SEPARATOR);
X  #endif /* MSG_SEPARATOR */
X+ 	    }
X+ 	    fputs(From_buf, files[size]);
X+ 	    fprintf(files[size], "Date: %s", ctime(&t));
X  	}
X      }
X  
X      /* first print users own message headers */
X***************
X*** 1203,1210 ****
X--- 1244,1253 ----
X       */
X      while (fgets(buf, BUFSIZ, ed_fp))
X  	for (size = 0; size < next_file; size++) {
X+ #ifdef MSG_SEPARATOR
X  	    if (!strncmp(buf, "From ", 5))
X  		fputc('>', files[size]);
X+ #endif /* MSG_SEPARATOR */
X  	    fputs(buf, files[size]);
X  	}
X  
X***************
X*** 1230,1235 ****
X--- 1273,1279 ----
X  }
X  
X  /* ARGSUSED */
X+ SIGRET
X  rm_edfile(sig)
X  {
X      if (sig > 0 && !killme) {
X***************
X*** 1419,1429 ****
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--- 1463,1476 ----
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! 		putstring(p+1, ed_fp);
X! 		wprint("\n");
X! 	    }
X! 	else if (*buf == '\\') {
X! 	    putstring(buf, ed_fp);
X! 	    wprint("\n");
X! 	} else
X  	    file_to_fp(buf, ed_fp, "r");
X      }
X  
X*** OLD/main.c	Thu May 12 21:14:34 1988
X--- main.c	Tue Jun 28 21:38:11 1988
X***************
X*** 20,25 ****
X--- 20,29 ----
X  }
X  #endif /* sun && DEBUG */
X  
X+ #ifdef DOT_LOCK
X+ int sgid;
X+ #endif /* DOT_LOCK */
X+ 
X  /*ARGSUSED*/   /* we ignore envp */
X  main(argc, argv)
X  char **argv;
X***************
X*** 38,43 ****
X--- 42,48 ----
X  
X      (void) signal(SIGBUS,  bus_n_seg);
X      (void) signal(SIGSEGV, bus_n_seg);
X+     (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
X  
X      f_flags[0] = 0;
X      mailfile = "";
X***************
X*** 58,67 ****
X      n = 0; /* don't ignore no such file or directory */
X      p = getpath(COMMAND_HELP, &n);
X  
X!     if (n) {
X! 	fprintf(stderr, "Warning: can't read %s: %s\n", COMMAND_HELP, p);
X  	cmd_help = "cmd_help";
X!     } else
X  	strdup(cmd_help, p);
X  
X      init(); /* must be done before checking mail since "login" is set here */
X--- 63,71 ----
X      n = 0; /* don't ignore no such file or directory */
X      p = getpath(COMMAND_HELP, &n);
X  
X!     if (n)
X  	cmd_help = "cmd_help";
X!     else
X  	strdup(cmd_help, p);
X  
X      init(); /* must be done before checking mail since "login" is set here */
X***************
X*** 130,135 ****
X--- 134,144 ----
X  	}
X      }
X  
X+ #ifdef DOT_LOCK
X+     sgid = getegid();
X+     setgid(getgid());
X+ #endif DOT_LOCK
X+ 
X      for (++argv; *argv && **argv == '-'; argv++)
X  	switch (argv[0][1]) {
X  	    case 'e':
X***************
X*** 391,402 ****
X  #ifdef SUNTOOL
X      if (istool) {
X  	n = 0;
X! 	p = getpath(TOOL_HELP, &n);
X! 	if (n) {
X! 	    fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
X! 	    tool_help = "tool_help";
X! 	} else
X! 	    strdup(tool_help, p);
X  	if (time_out < 30)
X  	    time_out = 60;
X  	turnoff(glob_flags, IGN_SIGS);
X--- 400,413 ----
X  #ifdef SUNTOOL
X      if (istool) {
X  	n = 0;
X! 	if (!tool_help) {
X! 	    p = getpath(TOOL_HELP, &n);
X! 	    if (n) {
X! 		fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
X! 		tool_help = "tool_help";
X! 	    } else
X! 		strdup(tool_help, p);
X! 	}
X  	if (time_out < 30)
X  	    time_out = 60;
X  	turnoff(glob_flags, IGN_SIGS);
X*** OLD/makefile.bsd	Thu May 12 21:14:35 1988
X--- makefile.bsd	Tue Jun 28 21:38:12 1988
X***************
X*** 8,14 ****
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--- 8,14 ----
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 README-6.3 mush.1 cmd_help
X  
X  MAKES= makefile.bsd makefile.x286 makefile.x386 makefile.sys.v
X  
X*** OLD/makefile.sun	Thu May 12 21:14:36 1988
X--- makefile.sun	Thu Jun 30 13:05:54 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 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--- 17,24 ----
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 README-6.3 \
X! 	mush.1 cmd_help tool_help
X  
X  MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.x286 makefile.x386
X  
X***************
X*** 31,37 ****
X  	@cc $(LDFLAGS) $(OBJS) $(LIBES) -o mush
X  
X  tar:
X! 	@tar fcv MUSH $(HELP_FILES) $(MAKES) $(IMAGES) $(HDRS) $(SRCS)
X  
X  lint:
X  	make -f makefile.bsd lint
X--- 32,38 ----
X  	@cc $(LDFLAGS) $(OBJS) $(LIBES) -o mush
X  
X  tar:
X! 	@tar fcv MUSH $(HELP_FILES) $(MAKES) $(IMAGES) $(HDRS) $(SRCS) Mailrc
X  
X  lint:
X  	make -f makefile.bsd lint
X*** OLD/makefile.x286	Thu May 12 21:14:37 1988
X--- makefile.x286	Tue Jun 28 21:38:13 1988
X***************
X*** 10,17 ****
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  LDFLAGS= -X -Mle -lx -F 4000
X--- 10,17 ----
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 README-6.3 mush.1 cmd_help
X! MAKES= makefile.sys.v makefile.x286 makefile.x386 makefile.bsd
X  
X  CFLAGS= -O -DSYSV -Mle -DCURSES -DREGCMP -DUSG
X  LDFLAGS= -X -Mle -lx -F 4000
X*** OLD/makefile.x386	Thu May 12 21:14:37 1988
X--- makefile.x386	Tue Jun 28 21:38:14 1988
X***************
X*** 10,17 ****
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  LDFLAGS= -X -M3 -lx
X--- 10,17 ----
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 README-6.3 mush.1 cmd_help
X! MAKES= makefile.sys.v makefile.286 makefile.x386 makefile.bsd
X  
X  CFLAGS= -O -DSYSV -M3e -DCURSES -DREGCMP -DUSG 
X  LDFLAGS= -X -M3 -lx
X*** OLD/misc.c	Thu May 12 21:14:38 1988
X--- misc.c	Tue Jun 28 21:38:15 1988
X***************
X*** 23,31 ****
X  }
X  
X  /*
X!  * loop thru all msgs starting with current_msg and find next undeleted
X!  * message.  If the variable "wrap" is set, wrap to the beginning of the
END_OF_FILE
if test 57387 -ne `wc -c <'Diffs.6.3.a'`; then
    echo shar: \"'Diffs.6.3.a'\" unpacked with wrong size!
fi
# end of 'Diffs.6.3.a'
fi
echo shar: End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.