[comp.sources.misc] v18i059: mush - Mail User's Shell, Part02/22

argv@zipcode.com (Dan Heller) (04/21/91)

Submitted-by: Dan Heller <argv@zipcode.com>
Posting-number: Volume 18, Issue 59
Archive-name: mush/part02
Supersedes: mush: Volume 12, Issue 28-47

#!/bin/sh
# do not concatenate these parts, unpack them in order with /bin/sh
# file README-7.0 continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 2; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping README-7.0'
else
echo 'x - continuing file README-7.0'
sed 's/^X//' << 'SHAR_EOF' >> 'README-7.0' &&
X	Finally, the tilde-escape ~I has replaced ~H for purposes of
X    including a message and its headers in the letter being composed.
X    This is analagous to the -i and -I options and the ~i escape.
X
my_hdr From: address
X    This is now allowed (it is allowed but neither documented nor correctly
X    used in 6.5.6, and was not allowed previously).  The user's From: header
X    is verified as best mush can, and used if it appears valid.  It is up
X    to the MTA to assure authenticity and/or add a Sender: header.  Mush
X    provides a From: if the user does not or if it cannot verify the one
X    given.
X
pipe -p pattern unix-command
X    The pipe command has been modified to allow its use as a shell script
X    extractor.  See the man page and "pipe -?" for details.  KNOWN BUG:
X    given a list of messages, all are sent to the same unix process.
X    This can cause havoc e.g. when each of the messages is a shell script
X    intended to be run by a virgin shell.  Changes are being discussed.
X    Also, pipe is now affected by $alwaysignore (see below).
X
Pipe
X    See the comments under "write" below.
X
pwd
X    This now prints the actual current working directory rather than
X    simply echoing the value of $cwd.
X
reply
X    Assorted repairs have been made to to take_me_off() (implements the
X    inverse of $metoo) and reply_to().  These include doing a better
X    (though still not perfect) job of getting the name and address to
X    match when replying to forwarded mail.
X
sort
X    The current message now moves with the sort, that is, the same actual
X    message (not necessarily the same message *number*) will be the
X    current message after the sort as was current before the sort.
X
save/copy
X    The 'p' (printed) and 'f' (forwarded) Status flags are now properly
X    saved when messages are saved/copied, and restored when the folders
X    are read.  Also, a "-f" (force) flag has been added, which has the
X    same meaning as the old "!" flag, that is, overwrite the file rather
X    than appending to it.  "save !" is still supported.
X
undigest -p pattern
X    The specified pattern is used as the article separator for unpacking
X    digests.  The default is "--------".  A literal match (no regexps or
X    wildcards) is done at beginning-of-line.
X
write
X    The write command (and other commands such as Pipe that omit message
X    headers) no longer outputs the blank line that separates the message
X    body from the headers, and also does not output the trailing blank
X    line that separates messages from one another.  (This applies only
X    when MSG_SEPARATOR is not defined during compilation.)  This makes
X    the command more useful for saving multi-part uuencoded files, etc.
X
$$
$name:l
$name:u
$name:<number>
X    Four new variable forms.  The first returns the PID of the running
X    mush; the second converts all alphabetics in the value of $name to
X    lower case; the third converts all alphabetics in the value of $name
X    to uppercase; the fourth splits the value into words and returns the
X    <number>th word.  Only one modifier can be used at a time.
X
$[%fmt]
X    This special variable form expands %fmt (a string with no spaces) as
X    a hdr_format format.  E.g., $h%a is the author of the current message.
X    Any colon-modifier may be applied, e.g.
X	$[%n]:1		First name of author of current message
X
$(%c)
X    This special variable form expands %c (c is a character) as a prompt
X    format.  E.g., $(%T) is the current time.  Colon-modifiers apply.
X
$alwaysignore
X    This variable now actually works as documented.  If you've gotten used
X    to the old behavior, you'll need to set this.  Note, however, that the
X    documented behavior has changed slightly.  The (erroneous) behavior of
X    Mush 6.5.6 when this variable was UNset is now achieved by:
X	set alwaysignore = "include,forward,pipe"
X    Setting this variable with no value has the same effect as in 6.5.6.
X
$autosign
X    You can now specify a program to be run, whose output will sign the
X    letter; the syntax is
X	set autosign = '|program-name'
X    This syntax has not been finalized and may change.  The argument list
X    passed to the program is the list of addresses that will go to the MTA,
X    in exactly the same form as that which will be used for the MTA (e.g.,
X    there may be a comma after each address).
X
$complete
X    Mush now supports filename completion and will eventually support
X    command completion as well.  This variable has a two-character "string"
X    value; the first character is used for name completion, the second for
X    listing, ala ESC and ^D in 4.3 BSD csh.
X
$domain_route
X    This variable allows the user to specify that domain short-circuiting
X    should be done in conjunction with auto_route.  Addresses that are
X    already in RFC822 domain form (user@domain) are not normally changed.
X    UUCP paths that contain fully-qualified domains are short-circuited
X    to the rightmost such domain.  Optionally, domain_route may be set
X    to a string, in which case all addresses are rewritten to UUCP form,
X    short-circuited, and the given string is then prepended as the first
X    host in the path.  This variable is intended for use at RFC976 Class 3
X    UUCP hosts, or UUCP sites with a connection to a Class 3 host.
X
$fignore
X    This variable modifies the behavior of file completion by specifying
X    file name forms that should NOT be completed.  See the man page for
X    more details.
X
$hdr_format
X    A new formatting string now allows access to *any* message header.
X    The format is:	%?header-name?
X    For example,
X	set hdr_format='%n "%?x-mailer?"'
X    might display
X	1 >   Barton E. Schaefer "Mail User's Shell (7.0.0 12/10/89)"
X    This can be used to avoid mush's TO: display for messages you
X    authored; just replace "%f" with "%?from?".
X
$lister
X    Has been removed.  The "folders" command now supplies its own set
X    of flags to ls, and "cmd ls 'ls ...'" suffices for other uses.
X
$quiet
X    This variable now has a value of one to six comma-delimited words.
X    For compatibility with previous versions, setting quiet without a
X    value has the original behavior of suppressing the startup message.
X    The recognized words are:
X	autosign	Don't tell me when a signature is appended
X	await		Await command doesn't ring for new mail
X	complete	Word completion doesn't ring on failure
X	fortune		Don't tell me when a fortune is appended
X	startup		Don't print the startup message
X	tool		Tool mode doesn't ring for new mail
X    Errors in autosigning or fortunes are still reported.  (Some beta
X    releases assigned three of these fields, with the on/off sense
X    reversed, to a variable named $bell; that variable is gone.)
X
$version
X    The version string, as printed on startup.
____________
X
MMDF Changes and File Locking Improvements
------------------------------------------
X
The MMDF support code has been modified to use the MMDF library calls for
file locking.  The files makefile.* were modified to make the need to link
in the MMDF library more obvious, and the comments in config.h-dist now
reflect the current (simpler) installation instructions for MMDF sites.
X
In the course of these updates, the structure of the file locking calls
was reworked to make open and lock a single (non-atomic) operation.  Many
thanks to lmjm@doc.imperial.ac.uk (Lee McLoughlin) and marc@virginia.edu
(Marc Rouleau) for instigation and help with implementation and testing of
these changes.
X
In the course of making these changes, a number of errors were discovered
and repaired:
X
X    An "update" would remove empty files and then try to reload them,
X    generating error messages.  The copyback() function now returns -1 if
X    it removes a file; folder() recognizes this and does not attempt to
X    load_folder() on a removed file.
X
X    There was a remote possibility of a race condition in in copyback()
X    because open-and-lock is non-atomic.  copyback() now checks for new
X    mail AFTER locking the spool file; this guarantees the MTA can't
X    slip a new message into the file just before it gets truncated.  The
X    check_new_mail() function has been broken into three specialized
X    parts to allow this:  get_new_mail() and show_new_mail() work as you
X    probably expect, and check_new_mail() now calls them.
X
X    The mbox file ($HOME/mbox or whatever) is locked by copyback(), and
X    all folders are locked by save_msg().
X
X    The dead.letter file is locked by dead_letter().
X
X    "Reinitializing" of a folder that was modified behind mush's back
X    would do pretty strange things in curses mode.  It now behaves more
X    sensibly.  Also, if your spool folder shrinks while you are using a
X    non-spool folder, mush won't incorrectly re-initialize the current
X    folder (a bug no one ever saw, we hope).
X
X    All mailboxes are locked for reading when they are first loaded or
X    when new mail comes in, whenever possible (DOT_LOCK and old Xenix
X    installations cannot read-lock).  If the MTA also uses a compatible
X    locking scheme (as one would hope), this should prevent "truncation"
X    of new messages without unduly restricting the reading of folders.
X
X    NOTE:  All this precautionary locking has its drawbacks.  Sending
X    mail can deadlock if you mention the same file twice in the list
X    of addresses.  (Of course, before the advent of locking, this would
X    cause interleaved writes; which is the lesser evil?)  Be careful.
X
Additional changes apply to installations where SYSV is defined:
X
X    Because lockf() requires a file open for writing, the locking code
X    has been rewritten to call fcntl(F_SETLK) directly.  Read and write
X    locks are used as appropriate.
X
X    This locking code has been only minimally tested, because none of the
X    authors has direct access to a true SysV machine.  Bug reports with
X    suggestions for improvement are requested.
SHAR_EOF
echo 'File README-7.0 is complete' &&
chmod 0600 README-7.0 ||
echo 'restore of README-7.0 failed'
Wc_c="`wc -c < 'README-7.0'`"
test 15679 -eq "$Wc_c" ||
	echo 'README-7.0: original size 15679, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= README-7.1 ==============
if test -f 'README-7.1' -a X"$1" != X"-c"; then
	echo 'x - skipping README-7.1 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README-7.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README-7.1' &&
This is release 7.1.0 of the SunView implementation of mush.
X
Version 7.1.0 differs from 7.0.4 mostly in the appearance of the screen
and the additional functionality that is allowed to show through to the
tool from the underlying interpreter.  This is a significant enough change
in "look and feel" that the revision number was increased from 0 to 1.
X
Thanks to Bill Randle <billr@saab.cna.tek.com> for extensive SunOS 3.5
testing, and to Bill and also Don Lewis <del@mlb.semi.harris.com> for
their contributions to the new toolmode composition features and function
key handling.
X
Tool mode changes include:
X    * Compilation now keys on definitions of SUN_4_1, SUN_4_0 or SUN_3_5
X      in makefile.sun, rather than assuming SunOS4.0 when SIGRET=void.
X      You still have to define SUNTOOL to get the tool mode capability.
X      If you define SUNTOOL but not the others, SUN_4_0 is assumed.
X    * The header summary display window has a scrollbar; the <Prev> and
X      <Next> buttons for scrolling are gone.
X    * The placement of buttons and items has changed a lot.  Buttons and
X      items dealing with folders and general setup have moved to the top
X      of the frame, and items dealing with individual messages and with
X      composition have been placed in a single row between the headers
X      and messsage display subwindows.
X    * The <Folders> and <Save> buttons each have a text entry item.
X      Furthermore, file completion with the ESC key works in those items.
X    * The <Sort> menu has been unscrambled, so you actually get the sort
X      criteria that you select.  (Don't ask.)
X    * The <Aliases> and <Headers> buttons have moved into a menu under
X      the <Options> button.  This clears up some confusion about exactly
X      what it was that <Headers> meant, and provides a hook for future
X      addition of a window for defining your own outgoing message headers.
X    * The <Display> button is gone; its operations are now handled by
X      opening the <Options> frame and toggling show_deleted or no_reverse.
X    * The small one-line print window is gone; messages previously shown
X      there now go to the scrollable status window.  There may be some
X      remaining bugs with missing newlines here.  This frees up some more
X      file descriptors in SunOS 3.5, to keep other things working longer.
X    * Function keys are recognized in most parts of the main frame.  In
X      anticipation of the day when window manager function keys can be
X      redefined, the messages about "L7 not defined" etc. are still shown
X      unless suppressed through $quiet (see below).
X    * The composition frame has more control buttons, providing more of
X      the functions of line and curses mode message composition.  Some
X      of the "chattiness" of message composition has gone away.  In fact,
X      the whole chatty subwindow in the compose frame has gone away,
X      possibly to return in a later patch when a better way to decide
X      what frame a message should go to has been worked out.  In the
X      meantime, all messages go to the main frame.
X    * Tilde escapes are supported in the tool mode composition textsw,
X      with a few minor exceptions accessible from the control buttons.
X    * Typing a <return> while entering header field text in tool mode
X      will move automatically to the next header when this is sensible.
X      The cursor becomes a bent arrow to indicate that this will happen.
X    * User-definable icons can be installed through the $mail_icon and
X      $newmail_icon variables, and $quiet has a field to suppress the
X      message-number label so your pretty pictures won't be trashed.
X    * Files that are not readable as folders are left out of the menus
X      for the <Folder> and <Save> items.
X
General changes include:
X
X    * There is a new defined constant, DIRECTORY, which indicates whether
X      your system has BSD-compatible directory-access routines.  It turns
X      out to be much too hard to figure this out on an OS-by-OS basis.  
X      DIRECTORY is automatically defined when BSD is defined, and is in
X      the default CFLAGS in makefile.hpux; you others are on your own.
X    * Some compilers were confused by "/*" appearing in the META string
X      defined in glob.h.  The characters in META have been rearranged.
X    * Using "exit" in a nested "if" in a source/init file no longer
X      causes error messages about "missing endif".
X    * Redefining "folder" via a "cmd" in .mushrc no longer causes the
X      initial folder load to bomb.  Similarly with "sort".
X    * Date parsing and sorting now understand timezones.  There may
X      still be some rough edges in date parsing on some of the less
X      common date formats, but RFC-822 and ctime (From_ line) dates
X      are handled correctly.  If the dates mush displays are really
X      off the wall, the order of the sscanf's in parse_date() may need
X      to be changed, or we may need to add some cases rather than
X      using partial matches to skip missing timezone fields.  There
X      are also some strange nonstandard abbreviations out there (what,
X      for example, is ECT?) which will all be treated as GMT unless
X      you hack them into the tables in dates.c.  Missing timezones are
X      treated as the local zone to get the date-received right (the
X      From_ line ctime-date almost never has a timezone).
X    * Mush now warns you if a file you attempt to load does not "look
X      like" a folder (i.e. no messages can be read).  If you are already
X      in the shell, this leaves you in an empty folder as it did before.
X      If you are just starting up (e.g. with "mush -f"), mush will exit.
X    * Additional checking is now done when collecting new mail and when
X      updating folders to detect corruptions, warn the user, and allow
X      a chance to recover.  Mush still reinitializes the spool folder if
X      it shrinks, but if this is detected at update time (as opposed to
X      new-mail-check time), the user is allowed to abort the update and
X      salvage the current folder contents.
X    * Curses mode now respects the user's presetting of $crt, unless the
X      user's value is larger than the actual screen size.  This allows
X      "set crt=2" to be used to force use of $pager.
X
Changes in commands:
X
mush -h -
X    The -h (-draft) option will now accept "-" as a filename indicating
X    standard input.  Note that this causes the input message to be sent
X    immediately; interactive use cannot be combined with redirected input.
X    The internal "mail -h" command will NOT interpret "-" as standard in.
X
alts *user
X    This syntax, analogous to the $autosign2 syntax, allows you to specify
X    any user name anywhere as "you" for purposes of $metoo, etc.
X
folder -n
X    This command changes folders without updating; it replaces the old
X    "folder !" notation, though the old form is still supported.  See
X    also the general notes above for behavior on attempts to load files
X    that are not folders.
X
from pattern
X    Given an argument that is not parseable as a message list, "from" will
X    automatically invoke "pick -f pattern".  Mixing message lists and
X    patterns is slightly counter-intuitive; if the message list precedes
X    the pattern, it will restrict the pattern search to that list, e.g.
X    "from 3-7 johnsmith" will show those messages in the range 3-7 that
X    are from johnsmith.  If the message list follows the pattern, it will
X    not be detected at all, but will be considered part of the pattern.
X    Also, "from jim bob sally" will treat the entire "jim bob sally" list
X    as a single pattern, as "pick" would; this may change in the future.
X
pipe -p /pat1/,/pat2/
X    The pattern supplied may now have the form /pat1/,/pat2/ to indicate
X    that extraction should begin at pat1 and end at pat2, inclusive.
X    Patterns are still matched literally at beginning-of-line (no regex
X    matching), and there is not currently any way to imbed a slash in
X    patterns of this form.  To allow searching for file paths, slashes
X    are significant only if the second slash is followed by a comma.
X
save/copy
X    Unless told to clobber the file (-f), these commands now check that
X    the file to which they are appending "looks like" a folder.  If the
X    file seems to be something else, the user is prompted to confirm the
X    save or copy.
X
set
X    Several minor fixes.  Piping to "set" now clears the variable if the
X    input message list is empty, rather than leaving the old value.  For
X    backwards compatibility, however, an unset variable does not become
X    set when an empty message list is piped to it.  Also, some of the
X    more esoteric abuses of the variable=value syntax have either been
X    made legal (`set var=' is the same as `set var') or made illegal
X    (`set var=value = value' won't create a variable named "var=value").
X
sort
X    Sorting by multiple criteria at once is now supported.  The flags to
X    sort have changed; "-" to reverse sorting is now obsolete, replaced
X    by "-r", and all the sort criteria should now be prefixed with a "-"
X    (-a,-d,-l,-R,-s,-S) like options to any other command.  A significant
X    subset of the old syntax is still recognized as a special case.
X
New/changed variables:
X
X    $cmd_help
X	(Also $tool_help)  The path given for this variable may contain
X	the usual filename metacharacters (~+).
X
X    $hangup
X	When set, mush updates the folder on SIGHUP instead of saving
X	the tempfile.  This is a bit dangerous -- in rare circumstances
X	(mainly when two or more MUAs are modifying the same folder)
X	some new mail could be lost.  Old mail should never be lost.
X
X    $hdr_format
X	The format spec %Z returns the time zone part of the date.
X
X    $mail_icon
X	Names an icon file to be used in the normal case, when no new
X	mail is present.  This icon will replace the mailbox with the
X	flag down.
X
X    $newmail_icon
X	Names an icon file to be used when new mail is present, replacing
X	the mailbox with the flag up.
X
X    $output
X	The message-list output of the last successful command is stored
X	in this variable.  This allows easy recovery from broken pipes
X	etc.  Note that any successful command that does not produce a
X	message list will clear $output (e.g. "echo").
X
X    $quiet
X	If the field "newmail" is present in the multi-value, the usual
X	"New mail (#X): ..." messages are not displayed.  The new mail
X	is still automatically incorporated into the mailbox.  In tool
X	mode, this shuts off the new mail bell (the "tool" field still
X	silences ALL tool mode bells).
X
X	If the field "fkey" is present in tool mode, warning messages
X	about unbound keys are not printed.
X
X	If the field "iconlabel" is present in tool mode, the current
X	number of messages is not displayed in the mush icon.
X    
X    $status
X	This is set to the success (0) or failure (-1) status of the
X	previously executed command.  Note that some curses-mode commands
X	return a failure status to indicate that the display has been
X	corrupted even if the command itself succeeded, so this variable
X	is mostly useful in scripts.
SHAR_EOF
chmod 0644 README-7.1 ||
echo 'restore of README-7.1 failed'
Wc_c="`wc -c < 'README-7.1'`"
test 11036 -eq "$Wc_c" ||
	echo 'README-7.1: original size 11036, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= README-7.2.0 ==============
if test -f 'README-7.2.0' -a X"$1" != X"-c"; then
	echo 'x - skipping README-7.2.0 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README-7.2.0 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README-7.2.0' &&
X
This is release 7.2.0 of the SunView implementation of mush.
X
Version 7.2.0 differs from 7.1.2 in additions to general functionality
and in bug fixes.  There are no significant changes to the appearance
of any of the interfaces.  The changes to add certain enhancements were
significant enough that the revision number was increased from 1 to 2.
X
New/changed commands:
X
X    about
X	This command produces an informational message about the program
X	and its authors.  It is available as a help menu selection in
X	tool mode.
X
X    alts user@host
X	This new alternates syntax is provided to make the behavior a
X	little more intuitive.  It is equivalent to
X	    alts !host!user
X	and will be displayed in that form in the alternates list or
X	in "saveopts" option dumps.
X
X    headers -H:m
X	The :m modifier (which can be used as a standalone command, as
X	with other such modifiers) selects messages having a temporary
X	mark.  See below.
X
X    mark
X    mark -[priority]
X    unmark
X	The "mark" command sets user-defined flag bits on messages.
X	With no arguments (or only a message list), it attaches a
X	temporary mark, not saved across updates.  With a -priority
X	argument, where priority is a letter A through E, a permanent
X	priority is assigned.  Priorities are removed by "mark -".
X	Temporary marks are removed by "unmark".
X
X	For the curses interface, the `*' key is now bound by default
X	to the new curses-command "mark".  This command toggles the
X	temporary mark on the current message.
X
X    pick -p priority
X	The -p option selects messages with priority specified by an
X	integer A through E.  Multiple -p options may be used, e.g.
X	    pick -p B -p D
X	will select messages having either priority B or priority D.
X
X	An additional change to the pick command is that some option
X	or pattern must be specified.  Using "pick" with no arguments
X	to repeat the last pattern search is no longer supported.  It
X	was never supported completely (only the pattern was retained,
X	not other information about where to look for it) and has been
X	eliminated to prevent confusion.
X
X    sort -p
X	The -p option orders messages by priority, A first, E last.
X	Marked messages (having the temporary mark) are treated as
X	highest priority for purposes of this ordering.  The ordering
X	can be reversed by using "sort -rp".  Also, the default status
X	sort now uses priority when status is otherwise the same.
X
New/changed variables:
X
X    $cdpath
X	It is no longer necessary to include "." in $cdpath.
X
X    $prompt
X	The values of variables can now be included in the prompt at
X	the time it is displayed.  The format syntax "%$variable",
X	where "variable" is some variable name, will insert the value
X	into the prompt.  Remember to use single quotes when setting
X	prompt strings to protect such variable references.
X
Details of general changes:
X
X    * The "preserve" command is now closer in behavior to UCB Mail and
X      Sun Mailtool, and mush now properly retains preserved status set
X      by either of those mailers.  Preserving a message no longer causes
X      it to be marked "U" (unread) when the folder is reloaded.
X
X    * In addition to the usual set of status bits, six user-defined bits
X      have been added.  The first is a `mark' bit, which shows up as a
X      `+' following the message number in the header display.  This bit
X      is not retained across folder update.  The other five bits are
X      `priority' bits A through E, displayed in the same spot if the mark
X      is not present.  These bits are retained across update in a Priority:
X      header placed just above the Status: header.  Priorities can be used
X      to select messages by using the "pick -p" command.  Marked messages
X      can be selected by the ":m" command.  The "sort -p" command orders
X      messages by priority (A highest, E lowest).  Marks and priorities
X      are attached to messages via the "mark" command.
X
X    * The "update" command now retains the "N" (new) status of messages
X      across the write-back to the folder.  The "quit" command still
X      changes the status to "U" (unread) on write-back, but new status
X      can be retained even across exit/restart by using "update;quit"
X      to exit from mush.
X
X    * Systems in European time zones using the /etc/timezone database
X      report daylight savings time in a two-word format, e.g. "MET DST".
X      The date parser has been fixed to recognize those formats in both
X      RFC822-compatible and ctime(3)-compatible date lines.  If you find
X      that you receive two-word time zones in one of the more exotic
X      date line styles that mush attempts to recognize, you'll have to
X      fix dates.c yourself.
X
X    * The cmd_help file now contains an entry with information of general
X      interest about the program and its authors.  This information is
X      accessed via a new command, "about", or via "help about".
X
Bugs fixed:
X
X    * The header display for mixed-format addresses now works as it has
X      been advertised to work since 7.1.2.
X    * Lock files are now properly removed for DOT_LOCK systems.
X    * History keyword searches now work properly for SysV systems.
X    * User-supplied From: lines for outgoing mail (via "my_hdr From:") 
X      are now properly inserted regardless of the value of $edit_hdrs.
X    * When composing mail, the escape character (normally tilde, `~')
X      is not treated as an escape if line wrap ($wrapcolumn) causes it
X      to become the first character on a line.
X    * If the .signature file does not have a terminating newline, mush
X      will provide one.
X    * Sending mail from the tool no longer leaves <defunct> processes
X      to accumulate in the process table.
X    * When changing directories, the current directories is always
X      searched first; "." in $cdpath is ignored.
X    * MIPS and other BSD-SYSV hybrid systems that use the getwd() call
X      instead of the usual SysV getcwd() can define GETWD in config.h
X      to select the correct call.
X
Tool mode changes:
X
X    * The new mail flag in the mush mailbox icon now goes up whenever
X      new mail arrives in the spool mailbox, even if the current folder
X      is not the spool mailbox.  Also, if the current folder is not the
X      spool but the size of the spool shrinks -- that is, the spool is
X      updated from another mush or mail session -- the flag will go up
X      to notify the user that "someone else" has modified his spool.
X
X    * When mushtool is started up or changed to a new folder, the first
X      new/unread message in the folder is automatically displayed.  In
X      previous versions, this would cause the message to be marked as
X      read, so that message would be saved to the user's mbox on the
X      next update, even if that message had previously been "preserved"
X      for storage in the spool file.  In 7.2, the message is still
X      displayed, but its preserved status is not changed unless it is
X      explicitly read by the user at a later time.
X
X    * There is a new panel button in the header panel to toggle marks
X      and set priorities.
X
===========================================================================
X
Information on the compose frame when the variable "compose_icon"
is set.
X
The compose frame is created as its own base frame, rather than a
child frame of the tool frame. The advantage of this is that the
compose window can be closed to an icon, rather than closed to
invisibleness.
X
The compose frame is opened by clicking on the "Compose" or "Reply"
buttons in the main mushtool panel or by clicking on or opening the
compose window icon (if it is visible). The very first the time
compose window is opened it must be done with the Compose or Reply
buttons in order to create the frame.
X
The compose frame can be closed by using the SunView frame popup
menu or by clicking on the "Close" button in the compose frame
panel.  It may be destroyed by choosing "Quit Compose Frame" from
the "Close" button menu or the "Quit" selection from the SunView
frame popup menu.
X
Repeated sequences of creating and destroying compose frames will
use up file descriptors in Sun OS 3.5, due to a bug where a destroyed
ttysw does not free up its fd's.  This appears to have been fixed
in later versions of SunOS.
X
The compose frame icon may be changed via the options menu and
mushrc files in the same manner that the tool icons are changable.
X
Closing the base tool with the "Done" button will also close the
compose frame (if it is open). The compose frame may be opened by
itself if all the user needs to do is compose/send a message.
Quiting mushtool also destroys the compose frame.
X
The default compose icon is the "textedit" icon with a label of
"mush" added to it.  To use your own custom icon, set "compose_icon"
to the path of the icon file.
X
X
X	-Bill Randle
X	billr@saab.CNA.TEK.COM
X	4 December 1990
SHAR_EOF
chmod 0644 README-7.2.0 ||
echo 'restore of README-7.2.0 failed'
Wc_c="`wc -c < 'README-7.2.0'`"
test 8799 -eq "$Wc_c" ||
	echo 'README-7.2.0: original size 8799, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= README-7.2.2 ==============
if test -f 'README-7.2.2' -a X"$1" != X"-c"; then
	echo 'x - skipping README-7.2.2 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README-7.2.2 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README-7.2.2' &&
X
This is release 7.2.2 of the Mail User's Shell (mush).
X
Mush has not been posted as a complete package since 7.1.1.  Before that,
the last complete posting was 6.5.6.  If your version of mush is older
than 7.1, refer to README-7.0 and README-7.1 for lists of other changes.
Some of the changes discussed here were available in 7.2.1, but no summary
was ever compiled for that version.  See README-7.2.0 for changes from
7.1.1 to 7.2.  The summary here covers changes since 7.2.0.
X
Changes in compilation:
X
X  * config.h-dist has been reorganized to bring the most-frquently-
X    changed definitions to the top.
X
X  * SCO UNIX 3.2 users should now define DIRECTORY and SELECT, and should
X    _not_ link with the -lx library.
X
X  * The preprocessor definition PRINTER_OPT can now be used to specify
X    the option used by your lpr to specify the target printer.  Formerly,
X    defining SYSV forced "lpr -dprinter" and otherwise "lpr -Pprinter"
X    was used.  Defining PRINTER_OPT forces use of the option defined
X    there; leaving PRINTER_OPT undefined passes through whichever of -d
X    or -P is given to mush's "lpr" command.
X
X  * The default version of SunOS that mush assumes when SUNTOOL is defined
X    has changed from 4.0 to 4.1.  If you have an older version of SunOS,
X    you must explictly define SUN_3_5 or SUN_4_0.
X
New/changed commands:
X
X    Amazingly, there aren't any.
X
New/changed variables:
X
X    complete
X	If both characters of the value of complete are the same, e.g.
X	set complete='\E\E', then mush will complete unique filename
X	matches, but non-unique matches will produce a listing before
X	completing the match as far as possible.  This has no effect
X	in tool mode.
X
X    compose_icon
X	In tool mode, setting this variable permits the compose window
X	to be separately iconified, and optionally specifies the icon
X	to be used for the compose window's iconic form.
X
X    hdr_format
X	The new format %u returns the user name part of the sender's
X	address.
X
X    indent_str
X	This string can now contain hdr_format references, just as
X	pre_indent_str and post_indent_str always have.
X
Details of general changes:
X
X  * A simple comparison against the file names of all currently locked
X    files is performed before attempting to get a new lock.  This helps
X    prevent deadlock when the the same file is given more than once as
X    a target for a copy of an outgoing message.  Note that deadlock will
X    still occur if the same file is referenced twice under two different
X    names, i.e. one of the names is a link.
X
Bugs fixed:
X
X  * The tool mode header display repaints properly when all messages in
X    the folder have been deleted.
X  * The tool mode Options (Variables) window no longer gets out of sync
X    with the actual values of the variables.  Thanks to Bill Randle.
X  * Using mush pipes in tool mode fkey functions doesn't improperly
X    attempt to redraw the header display, and hence doesn't core dump.
X  * Setting $tool_help in the Mushrc or .mushrc actually works now.
X  * Curses mode won't let you scroll into negative message numbers when
X    all messages in the folder have been deleted.
X  * Some obscure date formats are handled better.
X  * Using "folder -N" in curses mode works sensibly.
X  * File locking on folders blocks properly on SYSV machines.  This is
X    especially important for SCO UNIX, because of MMDF.
X  * The last (we hope) of the overlapping strcpy's has been purged.
X  * INTERNAL_MALLOC should be a little more robust.
X  * Warnings (as in "set warning") are now properly turned on and off
X    around "folder" commands.
X  * Sending a SIGHUP to a suspended mush no longer triggers a SIGTTOU.
X    Instead, mush exits relatively nicely, but without printing the
X    usual error messages.
X
Tool mode changes:
X
X  * The compose frame may optionally be separately iconified.  See the
X    remarks under the compose_icon variable.  Thanks to Bill Randle.
X
NOTE:
X
X    Some copies of 7.2.2 dated 3/26/91 or earlier have a bug in malloc.c.
X    If you are not using INTERNAL_MALLOC this will have no effect on the
X    behavior of the program, so the patchelevel was not changed.  The bug
X    will cause mush to allocate memory continuously as it runs (free() is
X    effectively disabled).  If you have such a copy, line 230 of malloc.c
X    will look like this:
X
X    230:	if (cp == NULL || debug < 5)
X
X    It should read:
X
X    230:	if (cp == NULL || debug > 4)
X
X    Correct versions can be obtained as usual from cse.ogi.edu, and have
X    the date 4/12/91 in version.h.
SHAR_EOF
chmod 0644 README-7.2.2 ||
echo 'restore of README-7.2.2 failed'
Wc_c="`wc -c < 'README-7.2.2'`"
test 4503 -eq "$Wc_c" ||
	echo 'README-7.2.2: original size 4503, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= addrs.c ==============
if test -f 'addrs.c' -a X"$1" != X"-c"; then
	echo 'x - skipping addrs.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting addrs.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'addrs.c' &&
/* addrs.c -- copyright (c) Dan Heller 1/25/1989 */
X
#include "mush.h"
X
/*
X * Check to see if all addressees in list1 is in list2.
X * The lists must be as clean as the driven snow (no comments, aliases
X * must have been expanded, all are separated by whitespace (for mk_argv).
X *
X * "user" matches "user" and "user@localhost"
X * "*user" matches "user" at any address whatsoever."
X * !host matches any user destined for the specified host.
X * !some!path is the same, but can be more specifiec in the path.
X * @dom.ain can match any user destined for any host within the domain.
X *      @berkeley.edu would match: dheller@cory.berkeley.edu
X */
compare_addrs(list1, list2, ret_buf)
char *list1, *list2, ret_buf[];
{
X    register char	*p;
X    char		**addrv, **listv, buf[256]; /* addrs aren't long */
X    int			addrc, listc, a, l, h, ret_val;
X
X    /* autosign2 list contains non-comment addresses */
X    listv = mk_argv(list1, &listc, FALSE);
X    addrv = mk_argv(list2, &addrc, FALSE);
X
X    /* loop thru both lists and convert addresses to !-format
X     * then remove ourhost names so "user" matches "user!local"
X     * also remove possible trailing commas (from list).
X     */
X    for (a = 0; a < addrc; a++) {
X	if (a != addrc-1 && (p = index(addrv[a], ',')) && !p[1])
X	    *p = 0;
X	if (addrv[a][0] == '!' || addrv[a][0] == '@')
X	    continue;
X	(void) bang_form(buf, addrv[a]);
X	if (strcmp(addrv[a], buf)) /* if they differ... */
X	    (void) strcpy(addrv[a], buf); /* save new version */
X    }
X    for (l = 0; l < listc; l++) {
X	if (l != listc-1 && (p = index(listv[l], ',')) && !p[1])
X	    *p = 0;
X	if (listv[l][0] == '!' || listv[l][0] == '@')
X	    continue;
X	(void) bang_form(buf, listv[l]);
X	if (strcmp(listv[l], buf)) /* if they differ... */
X	    (void) strdup(listv[l], buf); /* save new version */
X    }
X
X    Debug("\nlist1 = "), print_argv(listv);
X    Debug("list2 = "), print_argv(addrv), putchar('\n');
X
X    /* loop thru each list comparing each element with the
X     * other, if necessary.
X     */
X    for (l = 0; l < listc; l++) {
X	ret_val = 0;
X	/* check if local recipient with was specified. */
X	if (!(p = rindex(listv[l], '!')))
X	    for (a = 0; a < addrc; a++) {
X		/* we have a local user so far.  If addrv[] is
X		 * not remote, then strcmp() immediately.
X		 * Note that "!" with no host indicates *all*
X		 * local users!!!
X		 */
X		if (addrv[a][0] == '*') {
X		    /* "*user" == "user" or "*" == login */
X		    if (!addrv[a][1] && !lcase_strncmp(listv[l], login, -1) ||
X			!lcase_strncmp(listv[l], addrv[a]+1, -1))
X			ret_val = 1;
X		} else if (addrv[a][0] != '!') {
X		   if (!lcase_strncmp(addrv[a], listv[l], -1) || !addrv[a][1])
X			ret_val = 1;
X		} else for (h = 0; ourname && ourname[h]; h++)
X		    if (!lcase_strncmp(addrv[a]+1, ourname[h], -1)) {
X			ret_val = 1;
X			break;
X		    }
X		if (ret_val)
X		    break;
X	    }
X	/* else this is a remote user */
X	else {
X	    /* check all the addresses for @dom.ain stuff or
X	     * !path!name type stuff only.
X	     */
X	    /* first back up p to the previous '!' */
X	    char *start, *user = p + 1;
X	    while (p > listv[l] && *--p != '!')
X		;
X	    start = p; /* Where to start for _domain_ addrs */
X	    for (a = 0; a < addrc; a++) {
X		int len;
X		char *path;
X
X		/* first check the cases of address unmodified by @ and !
X		 * or check to see if  *user  is specified.
X		 */ 
X		if (addrv[a][0] != '@' && addrv[a][0] != '!') {
X		    if (addrv[a][0] == '*') {
X			/* we saved the username at "user" declaration. */
X			/* if "*" is by itself, check against user's login */
X			if (!addrv[a][1] && !lcase_strncmp(user, login, -1) ||
X			    addrv[a][1] && !lcase_strncmp(user,addrv[a]+1,-1)){
X			    ret_val = 1;
X			    break;
X			}
X		    } else if (!lcase_strncmp(addrv[a], listv[l], -1)) {
X			ret_val = 1;
X			break;
X		    }
X		    continue;
X		}
X		path = addrv[a]+1;
X		while (addrv[a][0] == '@' && *path == '.')
X		    path++;
X		if ((len = strlen(path)) == 0)
X		    continue; /* localhost stuff only -- can't match */
X		/* first check against specified domains */
X		if (addrv[a][0] == '@') {
X		    for (p = start; p; (p = index(p, '.')) && ++p)
X			if (!lcase_strncmp(p, path, len) &&
X			    (p[len] == '.' || p[len] == 0 || p[len] == '!')) {
X			    ret_val = 1;
X			    break;
X			}
X		} else if (addrv[a][0] == '!') {
X		    /* for !path style, start at head of addr */
X		    for (p = listv[l]; p; (p = index(p, '!')) && ++p)
X			if (!lcase_strncmp(p, path, len) &&
X				(p[len] == '!' || p[len] == 0)) {
X			    ret_val = 1;
X			    break;
X			}
X		}
X		/* If address is in autosign2, goto next addr */
X		if (ret_val)
X		    break;
X	    }
X	}
X	if (!ret_val) {
X	    /* this address isn't in autosign2 list */
X	    if (ret_buf)
X		(void) strcpy(ret_buf, listv[l]);
X	    break;
X	}
X    }
X    free_vec(listv);
X    free_vec(addrv);
X
X    return ret_val;
}
X
/*
X * Parser for stupidly-formed RFC822 addresses.  It has been tested on
X * several bizzare cases as well as the normal stuff and uucp paths.  It
X * takes a string which is a bunch of addresses and unscrambles the first
X * one in the string.  It returns a pointer to the first char past what it
X * unscrambled and copies the unscrambled address to its second argument.
X * 
X * It does NOT deal with trailing (comment) strings --
X *         <whoever@somewhere> (This is a comment)
X *                            ^unscramble_addr return points here
X * 
X * It also does not deal well with malformed <addresses> --
X *         <whoever@somewhere,nowhere>
X *                           ^unscramble_addr return points here
X * 
X * In each of the above cases, the string "whoever@somewhere" is copied
X * to the second argument.
X * 
X * Nothing is done to un-<>ed route-less RFC822/976 addresses, nor to
X * uucp paths, nor to mixed-mode addresses not containing a route.
X * Hopelessly scrambled addresses are not handled brilliantly --
X * 	@some.dumb.place,@any.other.place:sys2!user%sys3@sys1
X * parses to
X * 	sys2!user%sys3@sys1
X * i.e., the route is simply dropped.
X *
X * If UUCP is defined, a little more work is done with @: routes.  The
X * mangled address given above will unwind to
X *	some.dumb.place!any.other.place!sys1!sys2!sys3!user
X * thanks to intelligence in bang_form().
X */
char *
unscramble_addr(addr, naddr)
char *addr;
char *naddr;
{
X    char *i, *r, *at;
X    char s[BUFSIZ], t[BUFSIZ];
X    int anglebrace = 0;
X
X    /* Make a copy of the address so we can mangle it freely. */
X    if (addr && *addr) {
X	/* Skip any leading whitespace. */
X	for (i = addr; *i && index(" \t", *i); i++)
X	    ;
X	if (*i == '\0')
X	    return NULL;
X	/* Skip any leading double-quoted comment. */
X	if (*i == '"') {
X	    if ((i = index(i + 1, '"')) && (*i == '\0' || *(++i) == '\0'))
X		    return NULL;
X	}
X	/* Skip any more whitespace. */
X	while (*i && index(" \t", *i))
X	    i++;
X	if (*i == '\0')
X	    return NULL;
X	/* Check for angle braces around the address. */
X	if (*i == '<') {
X	    if (*(++i) == '\0')
X		return NULL;
X	    ++anglebrace;
X	}
X	/*
X	 * Look for a route.  A route is a comma-separated set of @-tagged
X	 *  domains terminated by a colon.  Later versions might try to use
X	 *  the route, but for now it confuses too many mailers.
X	 */
X	if ((*i == '@') && (r = any(i, " \t:"))) {
X	    if (*r != ':')
X		return NULL;
X	    if (*(r + 1) == '\0')
X		return NULL;
#ifndef UUCP
X	    /*
X	     * Back up to the rightmost @-tagged domain
X	     *  (see note below about unwinding)
X	     */
X	    *r = '\0';
X	    i = rindex(i, '@');
X	    *r = ':';
#endif /* !UUCP */
X	}
X	/* Remember how much we've skipped, and copy the rest. */
X	at = i;
X	(void) strncpy(t, i, sizeof t);
X	t[sizeof t - 1] = 0;
X	/* Strip from a trailing angle brace, if present. */
X	if (anglebrace) {
X	    if (r = any(t, "> \t")) {
X		if (r == t || *r != '>')
X		    return NULL;
X		else
X		    *r = '\0';
X		--anglebrace;
X	    } else
X		return NULL;
X	}
X	if (t[0] == '@') {
X	    /* Chop off any invalid stuff after the address. */
X	    if (r = any(index(t, ':'), " \t,(<"))
X		*r = '\0';
X	}
X    } else
X	return NULL;
X    /* Remember where we are so we can return it. */
X    at += strlen(t) + 1;
X    /*
X     * Unscramble the route, if present.
X     *  NOTE:  We assume that a route is present in only two cases:
X     *   1) addr was taken from the "From " line of a stupid mailer
X     *   2) addr was a well-formed, <> enclosed RFC822 address
X     */
X    if (t[0] == '@') {
#ifdef UUCP
X	if (!bang_form(s, t))
X	    return NULL;
#else /* UUCP */
X	if (r = index(t, ':'))
X	    r++;
X	else
X	    return NULL;
X	/* Delete the route if extraneous, otherwise unwind it. */
X	if (i = index(r, '@'))
X	    (void) strcpy(s, r);
X	else {
X	    /*
X	     * NOTE:  Unwinding currently uses only the rightmost domain
X	     *  in the route.  This will break for mailers that need the
X	     *  entire route.  Complete unwinding would require the use
X	     *  of % characters, which are avoided for other reasons.
X	     */
X	    (void) strcpy(s, r);
X	    *(--r) = '\0';
X	    (void) strcat(s, t);
X	}
#endif /* UUCP */
X    } else
X	(void) strcpy(s, t);
X    /*
X     * Ok, now the address should be in the form user@domain and
X     *  is held in buffer s (t[] is not copied directly to naddr
X     *  to allow future additional processing to be added here).
X     */
X    if (debug > 1) /* Don't dump this on trivial debugging */
X	wprint("Converting \"%s\" to \"%s\"\n", addr, s);
X    (void) strcpy(naddr, s);
X    return at;
}
X
/*
X * Convert RFC822 or mixed addresses to RFC976 `!' form,
X *  copying the new address to d.  The source address is
X *  translated according to RFC822 rules.
X * Return a pointer to the end (nul terminus) of d.
X */
char *
bang_form (d, s)
char *d, *s;
{
X    char *r, *t, *ab = NULL;
X
X    *d = '\0';
X    /* If nothing to do, quit now */
X    if (!s || !*s) {
X	return d;
X    }
X    /* Avoid any angle braces */
X    if (*s == '<') {
X	if (ab = index(s + 1, '>'))
X	    s++, *ab = '\0';
X	else
X	    return NULL;
X    }
X    /*
X     * Look backwards for the first `@'; this gives us the
X     * primary domain of the RFC822 address
X     */
X    if (*s == '@') {
X	/* An RFC-822 "@domain1,@domain2:" routing */
X	if (t = any(++s, ",:")) {
X	    char c = *t;
X	    *t = '\0';
X	    d += Strcpy(d, s);
X	    *d++ = '!';
X	    *t++ = c;
X	    r = bang_form(d, t);
X	} else
X	    r = NULL;
X    } else if ((t = rindex(s, '@')) && t != s) {
X	/* Copy the RFC822 domain as the UUCP head */
X	d += Strcpy(d, t + 1);
X	*d++ = '!';
X	*t = '\0';
X	r = bang_form(d, s);
X	*t = '@';
X    } else if (t = index(s, '!')) {
X	/* A normal UUCP path */
X	*t = '\0';
X	d += Strcpy(d, s);
X	*t++ = *d++ = '!';
X	r = bang_form(d, t);
X    } else if (t = rindex(s, '%')) {
X	/* An imbedded `%' -- treat as low-priority `@' */
X	*t = '@';
X	r = bang_form(d, s);
X	*t = '%';
X    } else
X	r = d + Strcpy(d, s);  /* No `@', `!', or `%' */
X    if (ab)
X	*ab = '>';
X    return r;
}
X
/*
X * Route addresses according to certain criteria.  This function is really
X * just a front end for improve_uucp_paths() which does routing (differently).
X * If "route" is null, this routine is being called incorrectly.
X * If route is an address, just call improve_uucp_paths() and return.
X * If route is the null string, then route all addresses via the sender's
X * which is the first name/address on the To: list. If he's on a remote
X * machine, chances are that the addresses of everyone else he mailed to
X * are addresses from his machine.  Reconstruct those addresses to route
X * thru the senders machine first.
X */
route_addresses(to, cc, route_path)
char *to, *cc, *route_path;
{
X    char pre_path[256], sender[HDRSIZ], tmp[256];
X    register char *next, *p;
X    int c;
X
X    Debug("route_addresses()\n");
X    if (!route_path)
X	return;
X    if (*route_path) {
X	improve_uucp_paths(to, HDRSIZ, route_path);
X	improve_uucp_paths(cc, HDRSIZ, route_path);
X	return;
X    }
X
X    pre_path[0] = 0;
X    /* Get the address of the sender (which is always listed first) */
X    if (!(next = get_name_n_addr(to, NULL, NULL)))
X	return;
X    c = *next, *next = 0;
X    (void) strcpy(sender, to);
X    *next = c;
X    /* fix up the sender's address; improve_uucp_paths to optimize pre_path */
X    improve_uucp_paths(sender, sizeof sender, NULL);
X
X    /* check to see if there is only one addr on To: line and no Cc: header */
X    if (!*next && (!cc || !*cc)) {
X	(void) strcpy(to, sender);
X	return;
X    }
X    /* otherwise, get the pre_path */
X    if (p = get_name_n_addr(sender, NULL, tmp))
X	c = p - sender; /* save the original length */
X    if (*tmp) {
X	(void) bang_form(pre_path, tmp);
X	if (p = rindex(pre_path, '!')) {
X	    *p = 0;
X	    Debug("Routing thru \"%s\"\n", pre_path);
X	} else
X	    pre_path[0] = 0;
X    } else
X	pre_path[0] = 0;
X
X    while (*next == ',' || isspace(*next))
X	next++;
X    improve_uucp_paths(next, HDRSIZ - (int)(next - to), pre_path);
X    improve_uucp_paths(cc, HDRSIZ, pre_path);
SHAR_EOF
true || echo 'restore of addrs.c failed'
fi
echo 'End of  part 2'
echo 'File addrs.c is continued in part 3'
echo 3 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.