home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / mush / part02 < prev    next >
Internet Message Format  |  1991-04-21  |  51KB

  1. From: argv@zipcode.com (Dan Heller)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i059:  mush - Mail User's Shell, Part02/22
  4. Message-ID: <1991Apr21.024849.11090@sparky.IMD.Sterling.COM>
  5. Date: 21 Apr 91 02:48:49 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: d0ba382b 7717811c 9325ecad 7be6c247
  8.  
  9. Submitted-by: Dan Heller <argv@zipcode.com>
  10. Posting-number: Volume 18, Issue 59
  11. Archive-name: mush/part02
  12. Supersedes: mush: Volume 12, Issue 28-47
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file README-7.0 continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 2; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping README-7.0'
  32. else
  33. echo 'x - continuing file README-7.0'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'README-7.0' &&
  35. X    Finally, the tilde-escape ~I has replaced ~H for purposes of
  36. X    including a message and its headers in the letter being composed.
  37. X    This is analagous to the -i and -I options and the ~i escape.
  38. X
  39. my_hdr From: address
  40. X    This is now allowed (it is allowed but neither documented nor correctly
  41. X    used in 6.5.6, and was not allowed previously).  The user's From: header
  42. X    is verified as best mush can, and used if it appears valid.  It is up
  43. X    to the MTA to assure authenticity and/or add a Sender: header.  Mush
  44. X    provides a From: if the user does not or if it cannot verify the one
  45. X    given.
  46. X
  47. pipe -p pattern unix-command
  48. X    The pipe command has been modified to allow its use as a shell script
  49. X    extractor.  See the man page and "pipe -?" for details.  KNOWN BUG:
  50. X    given a list of messages, all are sent to the same unix process.
  51. X    This can cause havoc e.g. when each of the messages is a shell script
  52. X    intended to be run by a virgin shell.  Changes are being discussed.
  53. X    Also, pipe is now affected by $alwaysignore (see below).
  54. X
  55. Pipe
  56. X    See the comments under "write" below.
  57. X
  58. pwd
  59. X    This now prints the actual current working directory rather than
  60. X    simply echoing the value of $cwd.
  61. X
  62. reply
  63. X    Assorted repairs have been made to to take_me_off() (implements the
  64. X    inverse of $metoo) and reply_to().  These include doing a better
  65. X    (though still not perfect) job of getting the name and address to
  66. X    match when replying to forwarded mail.
  67. X
  68. sort
  69. X    The current message now moves with the sort, that is, the same actual
  70. X    message (not necessarily the same message *number*) will be the
  71. X    current message after the sort as was current before the sort.
  72. X
  73. save/copy
  74. X    The 'p' (printed) and 'f' (forwarded) Status flags are now properly
  75. X    saved when messages are saved/copied, and restored when the folders
  76. X    are read.  Also, a "-f" (force) flag has been added, which has the
  77. X    same meaning as the old "!" flag, that is, overwrite the file rather
  78. X    than appending to it.  "save !" is still supported.
  79. X
  80. undigest -p pattern
  81. X    The specified pattern is used as the article separator for unpacking
  82. X    digests.  The default is "--------".  A literal match (no regexps or
  83. X    wildcards) is done at beginning-of-line.
  84. X
  85. write
  86. X    The write command (and other commands such as Pipe that omit message
  87. X    headers) no longer outputs the blank line that separates the message
  88. X    body from the headers, and also does not output the trailing blank
  89. X    line that separates messages from one another.  (This applies only
  90. X    when MSG_SEPARATOR is not defined during compilation.)  This makes
  91. X    the command more useful for saving multi-part uuencoded files, etc.
  92. X
  93. $$
  94. $name:l
  95. $name:u
  96. $name:<number>
  97. X    Four new variable forms.  The first returns the PID of the running
  98. X    mush; the second converts all alphabetics in the value of $name to
  99. X    lower case; the third converts all alphabetics in the value of $name
  100. X    to uppercase; the fourth splits the value into words and returns the
  101. X    <number>th word.  Only one modifier can be used at a time.
  102. X
  103. $[%fmt]
  104. X    This special variable form expands %fmt (a string with no spaces) as
  105. X    a hdr_format format.  E.g., $h%a is the author of the current message.
  106. X    Any colon-modifier may be applied, e.g.
  107. X    $[%n]:1        First name of author of current message
  108. X
  109. $(%c)
  110. X    This special variable form expands %c (c is a character) as a prompt
  111. X    format.  E.g., $(%T) is the current time.  Colon-modifiers apply.
  112. X
  113. $alwaysignore
  114. X    This variable now actually works as documented.  If you've gotten used
  115. X    to the old behavior, you'll need to set this.  Note, however, that the
  116. X    documented behavior has changed slightly.  The (erroneous) behavior of
  117. X    Mush 6.5.6 when this variable was UNset is now achieved by:
  118. X    set alwaysignore = "include,forward,pipe"
  119. X    Setting this variable with no value has the same effect as in 6.5.6.
  120. X
  121. $autosign
  122. X    You can now specify a program to be run, whose output will sign the
  123. X    letter; the syntax is
  124. X    set autosign = '|program-name'
  125. X    This syntax has not been finalized and may change.  The argument list
  126. X    passed to the program is the list of addresses that will go to the MTA,
  127. X    in exactly the same form as that which will be used for the MTA (e.g.,
  128. X    there may be a comma after each address).
  129. X
  130. $complete
  131. X    Mush now supports filename completion and will eventually support
  132. X    command completion as well.  This variable has a two-character "string"
  133. X    value; the first character is used for name completion, the second for
  134. X    listing, ala ESC and ^D in 4.3 BSD csh.
  135. X
  136. $domain_route
  137. X    This variable allows the user to specify that domain short-circuiting
  138. X    should be done in conjunction with auto_route.  Addresses that are
  139. X    already in RFC822 domain form (user@domain) are not normally changed.
  140. X    UUCP paths that contain fully-qualified domains are short-circuited
  141. X    to the rightmost such domain.  Optionally, domain_route may be set
  142. X    to a string, in which case all addresses are rewritten to UUCP form,
  143. X    short-circuited, and the given string is then prepended as the first
  144. X    host in the path.  This variable is intended for use at RFC976 Class 3
  145. X    UUCP hosts, or UUCP sites with a connection to a Class 3 host.
  146. X
  147. $fignore
  148. X    This variable modifies the behavior of file completion by specifying
  149. X    file name forms that should NOT be completed.  See the man page for
  150. X    more details.
  151. X
  152. $hdr_format
  153. X    A new formatting string now allows access to *any* message header.
  154. X    The format is:    %?header-name?
  155. X    For example,
  156. X    set hdr_format='%n "%?x-mailer?"'
  157. X    might display
  158. X    1 >   Barton E. Schaefer "Mail User's Shell (7.0.0 12/10/89)"
  159. X    This can be used to avoid mush's TO: display for messages you
  160. X    authored; just replace "%f" with "%?from?".
  161. X
  162. $lister
  163. X    Has been removed.  The "folders" command now supplies its own set
  164. X    of flags to ls, and "cmd ls 'ls ...'" suffices for other uses.
  165. X
  166. $quiet
  167. X    This variable now has a value of one to six comma-delimited words.
  168. X    For compatibility with previous versions, setting quiet without a
  169. X    value has the original behavior of suppressing the startup message.
  170. X    The recognized words are:
  171. X    autosign    Don't tell me when a signature is appended
  172. X    await        Await command doesn't ring for new mail
  173. X    complete    Word completion doesn't ring on failure
  174. X    fortune        Don't tell me when a fortune is appended
  175. X    startup        Don't print the startup message
  176. X    tool        Tool mode doesn't ring for new mail
  177. X    Errors in autosigning or fortunes are still reported.  (Some beta
  178. X    releases assigned three of these fields, with the on/off sense
  179. X    reversed, to a variable named $bell; that variable is gone.)
  180. X
  181. $version
  182. X    The version string, as printed on startup.
  183. ____________
  184. X
  185. MMDF Changes and File Locking Improvements
  186. ------------------------------------------
  187. X
  188. The MMDF support code has been modified to use the MMDF library calls for
  189. file locking.  The files makefile.* were modified to make the need to link
  190. in the MMDF library more obvious, and the comments in config.h-dist now
  191. reflect the current (simpler) installation instructions for MMDF sites.
  192. X
  193. In the course of these updates, the structure of the file locking calls
  194. was reworked to make open and lock a single (non-atomic) operation.  Many
  195. thanks to lmjm@doc.imperial.ac.uk (Lee McLoughlin) and marc@virginia.edu
  196. (Marc Rouleau) for instigation and help with implementation and testing of
  197. these changes.
  198. X
  199. In the course of making these changes, a number of errors were discovered
  200. and repaired:
  201. X
  202. X    An "update" would remove empty files and then try to reload them,
  203. X    generating error messages.  The copyback() function now returns -1 if
  204. X    it removes a file; folder() recognizes this and does not attempt to
  205. X    load_folder() on a removed file.
  206. X
  207. X    There was a remote possibility of a race condition in in copyback()
  208. X    because open-and-lock is non-atomic.  copyback() now checks for new
  209. X    mail AFTER locking the spool file; this guarantees the MTA can't
  210. X    slip a new message into the file just before it gets truncated.  The
  211. X    check_new_mail() function has been broken into three specialized
  212. X    parts to allow this:  get_new_mail() and show_new_mail() work as you
  213. X    probably expect, and check_new_mail() now calls them.
  214. X
  215. X    The mbox file ($HOME/mbox or whatever) is locked by copyback(), and
  216. X    all folders are locked by save_msg().
  217. X
  218. X    The dead.letter file is locked by dead_letter().
  219. X
  220. X    "Reinitializing" of a folder that was modified behind mush's back
  221. X    would do pretty strange things in curses mode.  It now behaves more
  222. X    sensibly.  Also, if your spool folder shrinks while you are using a
  223. X    non-spool folder, mush won't incorrectly re-initialize the current
  224. X    folder (a bug no one ever saw, we hope).
  225. X
  226. X    All mailboxes are locked for reading when they are first loaded or
  227. X    when new mail comes in, whenever possible (DOT_LOCK and old Xenix
  228. X    installations cannot read-lock).  If the MTA also uses a compatible
  229. X    locking scheme (as one would hope), this should prevent "truncation"
  230. X    of new messages without unduly restricting the reading of folders.
  231. X
  232. X    NOTE:  All this precautionary locking has its drawbacks.  Sending
  233. X    mail can deadlock if you mention the same file twice in the list
  234. X    of addresses.  (Of course, before the advent of locking, this would
  235. X    cause interleaved writes; which is the lesser evil?)  Be careful.
  236. X
  237. Additional changes apply to installations where SYSV is defined:
  238. X
  239. X    Because lockf() requires a file open for writing, the locking code
  240. X    has been rewritten to call fcntl(F_SETLK) directly.  Read and write
  241. X    locks are used as appropriate.
  242. X
  243. X    This locking code has been only minimally tested, because none of the
  244. X    authors has direct access to a true SysV machine.  Bug reports with
  245. X    suggestions for improvement are requested.
  246. SHAR_EOF
  247. echo 'File README-7.0 is complete' &&
  248. chmod 0600 README-7.0 ||
  249. echo 'restore of README-7.0 failed'
  250. Wc_c="`wc -c < 'README-7.0'`"
  251. test 15679 -eq "$Wc_c" ||
  252.     echo 'README-7.0: original size 15679, current size' "$Wc_c"
  253. rm -f _shar_wnt_.tmp
  254. fi
  255. # ============= README-7.1 ==============
  256. if test -f 'README-7.1' -a X"$1" != X"-c"; then
  257.     echo 'x - skipping README-7.1 (File already exists)'
  258.     rm -f _shar_wnt_.tmp
  259. else
  260. > _shar_wnt_.tmp
  261. echo 'x - extracting README-7.1 (Text)'
  262. sed 's/^X//' << 'SHAR_EOF' > 'README-7.1' &&
  263. This is release 7.1.0 of the SunView implementation of mush.
  264. X
  265. Version 7.1.0 differs from 7.0.4 mostly in the appearance of the screen
  266. and the additional functionality that is allowed to show through to the
  267. tool from the underlying interpreter.  This is a significant enough change
  268. in "look and feel" that the revision number was increased from 0 to 1.
  269. X
  270. Thanks to Bill Randle <billr@saab.cna.tek.com> for extensive SunOS 3.5
  271. testing, and to Bill and also Don Lewis <del@mlb.semi.harris.com> for
  272. their contributions to the new toolmode composition features and function
  273. key handling.
  274. X
  275. Tool mode changes include:
  276. X    * Compilation now keys on definitions of SUN_4_1, SUN_4_0 or SUN_3_5
  277. X      in makefile.sun, rather than assuming SunOS4.0 when SIGRET=void.
  278. X      You still have to define SUNTOOL to get the tool mode capability.
  279. X      If you define SUNTOOL but not the others, SUN_4_0 is assumed.
  280. X    * The header summary display window has a scrollbar; the <Prev> and
  281. X      <Next> buttons for scrolling are gone.
  282. X    * The placement of buttons and items has changed a lot.  Buttons and
  283. X      items dealing with folders and general setup have moved to the top
  284. X      of the frame, and items dealing with individual messages and with
  285. X      composition have been placed in a single row between the headers
  286. X      and messsage display subwindows.
  287. X    * The <Folders> and <Save> buttons each have a text entry item.
  288. X      Furthermore, file completion with the ESC key works in those items.
  289. X    * The <Sort> menu has been unscrambled, so you actually get the sort
  290. X      criteria that you select.  (Don't ask.)
  291. X    * The <Aliases> and <Headers> buttons have moved into a menu under
  292. X      the <Options> button.  This clears up some confusion about exactly
  293. X      what it was that <Headers> meant, and provides a hook for future
  294. X      addition of a window for defining your own outgoing message headers.
  295. X    * The <Display> button is gone; its operations are now handled by
  296. X      opening the <Options> frame and toggling show_deleted or no_reverse.
  297. X    * The small one-line print window is gone; messages previously shown
  298. X      there now go to the scrollable status window.  There may be some
  299. X      remaining bugs with missing newlines here.  This frees up some more
  300. X      file descriptors in SunOS 3.5, to keep other things working longer.
  301. X    * Function keys are recognized in most parts of the main frame.  In
  302. X      anticipation of the day when window manager function keys can be
  303. X      redefined, the messages about "L7 not defined" etc. are still shown
  304. X      unless suppressed through $quiet (see below).
  305. X    * The composition frame has more control buttons, providing more of
  306. X      the functions of line and curses mode message composition.  Some
  307. X      of the "chattiness" of message composition has gone away.  In fact,
  308. X      the whole chatty subwindow in the compose frame has gone away,
  309. X      possibly to return in a later patch when a better way to decide
  310. X      what frame a message should go to has been worked out.  In the
  311. X      meantime, all messages go to the main frame.
  312. X    * Tilde escapes are supported in the tool mode composition textsw,
  313. X      with a few minor exceptions accessible from the control buttons.
  314. X    * Typing a <return> while entering header field text in tool mode
  315. X      will move automatically to the next header when this is sensible.
  316. X      The cursor becomes a bent arrow to indicate that this will happen.
  317. X    * User-definable icons can be installed through the $mail_icon and
  318. X      $newmail_icon variables, and $quiet has a field to suppress the
  319. X      message-number label so your pretty pictures won't be trashed.
  320. X    * Files that are not readable as folders are left out of the menus
  321. X      for the <Folder> and <Save> items.
  322. X
  323. General changes include:
  324. X
  325. X    * There is a new defined constant, DIRECTORY, which indicates whether
  326. X      your system has BSD-compatible directory-access routines.  It turns
  327. X      out to be much too hard to figure this out on an OS-by-OS basis.  
  328. X      DIRECTORY is automatically defined when BSD is defined, and is in
  329. X      the default CFLAGS in makefile.hpux; you others are on your own.
  330. X    * Some compilers were confused by "/*" appearing in the META string
  331. X      defined in glob.h.  The characters in META have been rearranged.
  332. X    * Using "exit" in a nested "if" in a source/init file no longer
  333. X      causes error messages about "missing endif".
  334. X    * Redefining "folder" via a "cmd" in .mushrc no longer causes the
  335. X      initial folder load to bomb.  Similarly with "sort".
  336. X    * Date parsing and sorting now understand timezones.  There may
  337. X      still be some rough edges in date parsing on some of the less
  338. X      common date formats, but RFC-822 and ctime (From_ line) dates
  339. X      are handled correctly.  If the dates mush displays are really
  340. X      off the wall, the order of the sscanf's in parse_date() may need
  341. X      to be changed, or we may need to add some cases rather than
  342. X      using partial matches to skip missing timezone fields.  There
  343. X      are also some strange nonstandard abbreviations out there (what,
  344. X      for example, is ECT?) which will all be treated as GMT unless
  345. X      you hack them into the tables in dates.c.  Missing timezones are
  346. X      treated as the local zone to get the date-received right (the
  347. X      From_ line ctime-date almost never has a timezone).
  348. X    * Mush now warns you if a file you attempt to load does not "look
  349. X      like" a folder (i.e. no messages can be read).  If you are already
  350. X      in the shell, this leaves you in an empty folder as it did before.
  351. X      If you are just starting up (e.g. with "mush -f"), mush will exit.
  352. X    * Additional checking is now done when collecting new mail and when
  353. X      updating folders to detect corruptions, warn the user, and allow
  354. X      a chance to recover.  Mush still reinitializes the spool folder if
  355. X      it shrinks, but if this is detected at update time (as opposed to
  356. X      new-mail-check time), the user is allowed to abort the update and
  357. X      salvage the current folder contents.
  358. X    * Curses mode now respects the user's presetting of $crt, unless the
  359. X      user's value is larger than the actual screen size.  This allows
  360. X      "set crt=2" to be used to force use of $pager.
  361. X
  362. Changes in commands:
  363. X
  364. mush -h -
  365. X    The -h (-draft) option will now accept "-" as a filename indicating
  366. X    standard input.  Note that this causes the input message to be sent
  367. X    immediately; interactive use cannot be combined with redirected input.
  368. X    The internal "mail -h" command will NOT interpret "-" as standard in.
  369. X
  370. alts *user
  371. X    This syntax, analogous to the $autosign2 syntax, allows you to specify
  372. X    any user name anywhere as "you" for purposes of $metoo, etc.
  373. X
  374. folder -n
  375. X    This command changes folders without updating; it replaces the old
  376. X    "folder !" notation, though the old form is still supported.  See
  377. X    also the general notes above for behavior on attempts to load files
  378. X    that are not folders.
  379. X
  380. from pattern
  381. X    Given an argument that is not parseable as a message list, "from" will
  382. X    automatically invoke "pick -f pattern".  Mixing message lists and
  383. X    patterns is slightly counter-intuitive; if the message list precedes
  384. X    the pattern, it will restrict the pattern search to that list, e.g.
  385. X    "from 3-7 johnsmith" will show those messages in the range 3-7 that
  386. X    are from johnsmith.  If the message list follows the pattern, it will
  387. X    not be detected at all, but will be considered part of the pattern.
  388. X    Also, "from jim bob sally" will treat the entire "jim bob sally" list
  389. X    as a single pattern, as "pick" would; this may change in the future.
  390. X
  391. pipe -p /pat1/,/pat2/
  392. X    The pattern supplied may now have the form /pat1/,/pat2/ to indicate
  393. X    that extraction should begin at pat1 and end at pat2, inclusive.
  394. X    Patterns are still matched literally at beginning-of-line (no regex
  395. X    matching), and there is not currently any way to imbed a slash in
  396. X    patterns of this form.  To allow searching for file paths, slashes
  397. X    are significant only if the second slash is followed by a comma.
  398. X
  399. save/copy
  400. X    Unless told to clobber the file (-f), these commands now check that
  401. X    the file to which they are appending "looks like" a folder.  If the
  402. X    file seems to be something else, the user is prompted to confirm the
  403. X    save or copy.
  404. X
  405. set
  406. X    Several minor fixes.  Piping to "set" now clears the variable if the
  407. X    input message list is empty, rather than leaving the old value.  For
  408. X    backwards compatibility, however, an unset variable does not become
  409. X    set when an empty message list is piped to it.  Also, some of the
  410. X    more esoteric abuses of the variable=value syntax have either been
  411. X    made legal (`set var=' is the same as `set var') or made illegal
  412. X    (`set var=value = value' won't create a variable named "var=value").
  413. X
  414. sort
  415. X    Sorting by multiple criteria at once is now supported.  The flags to
  416. X    sort have changed; "-" to reverse sorting is now obsolete, replaced
  417. X    by "-r", and all the sort criteria should now be prefixed with a "-"
  418. X    (-a,-d,-l,-R,-s,-S) like options to any other command.  A significant
  419. X    subset of the old syntax is still recognized as a special case.
  420. X
  421. New/changed variables:
  422. X
  423. X    $cmd_help
  424. X    (Also $tool_help)  The path given for this variable may contain
  425. X    the usual filename metacharacters (~+).
  426. X
  427. X    $hangup
  428. X    When set, mush updates the folder on SIGHUP instead of saving
  429. X    the tempfile.  This is a bit dangerous -- in rare circumstances
  430. X    (mainly when two or more MUAs are modifying the same folder)
  431. X    some new mail could be lost.  Old mail should never be lost.
  432. X
  433. X    $hdr_format
  434. X    The format spec %Z returns the time zone part of the date.
  435. X
  436. X    $mail_icon
  437. X    Names an icon file to be used in the normal case, when no new
  438. X    mail is present.  This icon will replace the mailbox with the
  439. X    flag down.
  440. X
  441. X    $newmail_icon
  442. X    Names an icon file to be used when new mail is present, replacing
  443. X    the mailbox with the flag up.
  444. X
  445. X    $output
  446. X    The message-list output of the last successful command is stored
  447. X    in this variable.  This allows easy recovery from broken pipes
  448. X    etc.  Note that any successful command that does not produce a
  449. X    message list will clear $output (e.g. "echo").
  450. X
  451. X    $quiet
  452. X    If the field "newmail" is present in the multi-value, the usual
  453. X    "New mail (#X): ..." messages are not displayed.  The new mail
  454. X    is still automatically incorporated into the mailbox.  In tool
  455. X    mode, this shuts off the new mail bell (the "tool" field still
  456. X    silences ALL tool mode bells).
  457. X
  458. X    If the field "fkey" is present in tool mode, warning messages
  459. X    about unbound keys are not printed.
  460. X
  461. X    If the field "iconlabel" is present in tool mode, the current
  462. X    number of messages is not displayed in the mush icon.
  463. X    
  464. X    $status
  465. X    This is set to the success (0) or failure (-1) status of the
  466. X    previously executed command.  Note that some curses-mode commands
  467. X    return a failure status to indicate that the display has been
  468. X    corrupted even if the command itself succeeded, so this variable
  469. X    is mostly useful in scripts.
  470. SHAR_EOF
  471. chmod 0644 README-7.1 ||
  472. echo 'restore of README-7.1 failed'
  473. Wc_c="`wc -c < 'README-7.1'`"
  474. test 11036 -eq "$Wc_c" ||
  475.     echo 'README-7.1: original size 11036, current size' "$Wc_c"
  476. rm -f _shar_wnt_.tmp
  477. fi
  478. # ============= README-7.2.0 ==============
  479. if test -f 'README-7.2.0' -a X"$1" != X"-c"; then
  480.     echo 'x - skipping README-7.2.0 (File already exists)'
  481.     rm -f _shar_wnt_.tmp
  482. else
  483. > _shar_wnt_.tmp
  484. echo 'x - extracting README-7.2.0 (Text)'
  485. sed 's/^X//' << 'SHAR_EOF' > 'README-7.2.0' &&
  486. X
  487. This is release 7.2.0 of the SunView implementation of mush.
  488. X
  489. Version 7.2.0 differs from 7.1.2 in additions to general functionality
  490. and in bug fixes.  There are no significant changes to the appearance
  491. of any of the interfaces.  The changes to add certain enhancements were
  492. significant enough that the revision number was increased from 1 to 2.
  493. X
  494. New/changed commands:
  495. X
  496. X    about
  497. X    This command produces an informational message about the program
  498. X    and its authors.  It is available as a help menu selection in
  499. X    tool mode.
  500. X
  501. X    alts user@host
  502. X    This new alternates syntax is provided to make the behavior a
  503. X    little more intuitive.  It is equivalent to
  504. X        alts !host!user
  505. X    and will be displayed in that form in the alternates list or
  506. X    in "saveopts" option dumps.
  507. X
  508. X    headers -H:m
  509. X    The :m modifier (which can be used as a standalone command, as
  510. X    with other such modifiers) selects messages having a temporary
  511. X    mark.  See below.
  512. X
  513. X    mark
  514. X    mark -[priority]
  515. X    unmark
  516. X    The "mark" command sets user-defined flag bits on messages.
  517. X    With no arguments (or only a message list), it attaches a
  518. X    temporary mark, not saved across updates.  With a -priority
  519. X    argument, where priority is a letter A through E, a permanent
  520. X    priority is assigned.  Priorities are removed by "mark -".
  521. X    Temporary marks are removed by "unmark".
  522. X
  523. X    For the curses interface, the `*' key is now bound by default
  524. X    to the new curses-command "mark".  This command toggles the
  525. X    temporary mark on the current message.
  526. X
  527. X    pick -p priority
  528. X    The -p option selects messages with priority specified by an
  529. X    integer A through E.  Multiple -p options may be used, e.g.
  530. X        pick -p B -p D
  531. X    will select messages having either priority B or priority D.
  532. X
  533. X    An additional change to the pick command is that some option
  534. X    or pattern must be specified.  Using "pick" with no arguments
  535. X    to repeat the last pattern search is no longer supported.  It
  536. X    was never supported completely (only the pattern was retained,
  537. X    not other information about where to look for it) and has been
  538. X    eliminated to prevent confusion.
  539. X
  540. X    sort -p
  541. X    The -p option orders messages by priority, A first, E last.
  542. X    Marked messages (having the temporary mark) are treated as
  543. X    highest priority for purposes of this ordering.  The ordering
  544. X    can be reversed by using "sort -rp".  Also, the default status
  545. X    sort now uses priority when status is otherwise the same.
  546. X
  547. New/changed variables:
  548. X
  549. X    $cdpath
  550. X    It is no longer necessary to include "." in $cdpath.
  551. X
  552. X    $prompt
  553. X    The values of variables can now be included in the prompt at
  554. X    the time it is displayed.  The format syntax "%$variable",
  555. X    where "variable" is some variable name, will insert the value
  556. X    into the prompt.  Remember to use single quotes when setting
  557. X    prompt strings to protect such variable references.
  558. X
  559. Details of general changes:
  560. X
  561. X    * The "preserve" command is now closer in behavior to UCB Mail and
  562. X      Sun Mailtool, and mush now properly retains preserved status set
  563. X      by either of those mailers.  Preserving a message no longer causes
  564. X      it to be marked "U" (unread) when the folder is reloaded.
  565. X
  566. X    * In addition to the usual set of status bits, six user-defined bits
  567. X      have been added.  The first is a `mark' bit, which shows up as a
  568. X      `+' following the message number in the header display.  This bit
  569. X      is not retained across folder update.  The other five bits are
  570. X      `priority' bits A through E, displayed in the same spot if the mark
  571. X      is not present.  These bits are retained across update in a Priority:
  572. X      header placed just above the Status: header.  Priorities can be used
  573. X      to select messages by using the "pick -p" command.  Marked messages
  574. X      can be selected by the ":m" command.  The "sort -p" command orders
  575. X      messages by priority (A highest, E lowest).  Marks and priorities
  576. X      are attached to messages via the "mark" command.
  577. X
  578. X    * The "update" command now retains the "N" (new) status of messages
  579. X      across the write-back to the folder.  The "quit" command still
  580. X      changes the status to "U" (unread) on write-back, but new status
  581. X      can be retained even across exit/restart by using "update;quit"
  582. X      to exit from mush.
  583. X
  584. X    * Systems in European time zones using the /etc/timezone database
  585. X      report daylight savings time in a two-word format, e.g. "MET DST".
  586. X      The date parser has been fixed to recognize those formats in both
  587. X      RFC822-compatible and ctime(3)-compatible date lines.  If you find
  588. X      that you receive two-word time zones in one of the more exotic
  589. X      date line styles that mush attempts to recognize, you'll have to
  590. X      fix dates.c yourself.
  591. X
  592. X    * The cmd_help file now contains an entry with information of general
  593. X      interest about the program and its authors.  This information is
  594. X      accessed via a new command, "about", or via "help about".
  595. X
  596. Bugs fixed:
  597. X
  598. X    * The header display for mixed-format addresses now works as it has
  599. X      been advertised to work since 7.1.2.
  600. X    * Lock files are now properly removed for DOT_LOCK systems.
  601. X    * History keyword searches now work properly for SysV systems.
  602. X    * User-supplied From: lines for outgoing mail (via "my_hdr From:") 
  603. X      are now properly inserted regardless of the value of $edit_hdrs.
  604. X    * When composing mail, the escape character (normally tilde, `~')
  605. X      is not treated as an escape if line wrap ($wrapcolumn) causes it
  606. X      to become the first character on a line.
  607. X    * If the .signature file does not have a terminating newline, mush
  608. X      will provide one.
  609. X    * Sending mail from the tool no longer leaves <defunct> processes
  610. X      to accumulate in the process table.
  611. X    * When changing directories, the current directories is always
  612. X      searched first; "." in $cdpath is ignored.
  613. X    * MIPS and other BSD-SYSV hybrid systems that use the getwd() call
  614. X      instead of the usual SysV getcwd() can define GETWD in config.h
  615. X      to select the correct call.
  616. X
  617. Tool mode changes:
  618. X
  619. X    * The new mail flag in the mush mailbox icon now goes up whenever
  620. X      new mail arrives in the spool mailbox, even if the current folder
  621. X      is not the spool mailbox.  Also, if the current folder is not the
  622. X      spool but the size of the spool shrinks -- that is, the spool is
  623. X      updated from another mush or mail session -- the flag will go up
  624. X      to notify the user that "someone else" has modified his spool.
  625. X
  626. X    * When mushtool is started up or changed to a new folder, the first
  627. X      new/unread message in the folder is automatically displayed.  In
  628. X      previous versions, this would cause the message to be marked as
  629. X      read, so that message would be saved to the user's mbox on the
  630. X      next update, even if that message had previously been "preserved"
  631. X      for storage in the spool file.  In 7.2, the message is still
  632. X      displayed, but its preserved status is not changed unless it is
  633. X      explicitly read by the user at a later time.
  634. X
  635. X    * There is a new panel button in the header panel to toggle marks
  636. X      and set priorities.
  637. X
  638. ===========================================================================
  639. X
  640. Information on the compose frame when the variable "compose_icon"
  641. is set.
  642. X
  643. The compose frame is created as its own base frame, rather than a
  644. child frame of the tool frame. The advantage of this is that the
  645. compose window can be closed to an icon, rather than closed to
  646. invisibleness.
  647. X
  648. The compose frame is opened by clicking on the "Compose" or "Reply"
  649. buttons in the main mushtool panel or by clicking on or opening the
  650. compose window icon (if it is visible). The very first the time
  651. compose window is opened it must be done with the Compose or Reply
  652. buttons in order to create the frame.
  653. X
  654. The compose frame can be closed by using the SunView frame popup
  655. menu or by clicking on the "Close" button in the compose frame
  656. panel.  It may be destroyed by choosing "Quit Compose Frame" from
  657. the "Close" button menu or the "Quit" selection from the SunView
  658. frame popup menu.
  659. X
  660. Repeated sequences of creating and destroying compose frames will
  661. use up file descriptors in Sun OS 3.5, due to a bug where a destroyed
  662. ttysw does not free up its fd's.  This appears to have been fixed
  663. in later versions of SunOS.
  664. X
  665. The compose frame icon may be changed via the options menu and
  666. mushrc files in the same manner that the tool icons are changable.
  667. X
  668. Closing the base tool with the "Done" button will also close the
  669. compose frame (if it is open). The compose frame may be opened by
  670. itself if all the user needs to do is compose/send a message.
  671. Quiting mushtool also destroys the compose frame.
  672. X
  673. The default compose icon is the "textedit" icon with a label of
  674. "mush" added to it.  To use your own custom icon, set "compose_icon"
  675. to the path of the icon file.
  676. X
  677. X
  678. X    -Bill Randle
  679. X    billr@saab.CNA.TEK.COM
  680. X    4 December 1990
  681. SHAR_EOF
  682. chmod 0644 README-7.2.0 ||
  683. echo 'restore of README-7.2.0 failed'
  684. Wc_c="`wc -c < 'README-7.2.0'`"
  685. test 8799 -eq "$Wc_c" ||
  686.     echo 'README-7.2.0: original size 8799, current size' "$Wc_c"
  687. rm -f _shar_wnt_.tmp
  688. fi
  689. # ============= README-7.2.2 ==============
  690. if test -f 'README-7.2.2' -a X"$1" != X"-c"; then
  691.     echo 'x - skipping README-7.2.2 (File already exists)'
  692.     rm -f _shar_wnt_.tmp
  693. else
  694. > _shar_wnt_.tmp
  695. echo 'x - extracting README-7.2.2 (Text)'
  696. sed 's/^X//' << 'SHAR_EOF' > 'README-7.2.2' &&
  697. X
  698. This is release 7.2.2 of the Mail User's Shell (mush).
  699. X
  700. Mush has not been posted as a complete package since 7.1.1.  Before that,
  701. the last complete posting was 6.5.6.  If your version of mush is older
  702. than 7.1, refer to README-7.0 and README-7.1 for lists of other changes.
  703. Some of the changes discussed here were available in 7.2.1, but no summary
  704. was ever compiled for that version.  See README-7.2.0 for changes from
  705. 7.1.1 to 7.2.  The summary here covers changes since 7.2.0.
  706. X
  707. Changes in compilation:
  708. X
  709. X  * config.h-dist has been reorganized to bring the most-frquently-
  710. X    changed definitions to the top.
  711. X
  712. X  * SCO UNIX 3.2 users should now define DIRECTORY and SELECT, and should
  713. X    _not_ link with the -lx library.
  714. X
  715. X  * The preprocessor definition PRINTER_OPT can now be used to specify
  716. X    the option used by your lpr to specify the target printer.  Formerly,
  717. X    defining SYSV forced "lpr -dprinter" and otherwise "lpr -Pprinter"
  718. X    was used.  Defining PRINTER_OPT forces use of the option defined
  719. X    there; leaving PRINTER_OPT undefined passes through whichever of -d
  720. X    or -P is given to mush's "lpr" command.
  721. X
  722. X  * The default version of SunOS that mush assumes when SUNTOOL is defined
  723. X    has changed from 4.0 to 4.1.  If you have an older version of SunOS,
  724. X    you must explictly define SUN_3_5 or SUN_4_0.
  725. X
  726. New/changed commands:
  727. X
  728. X    Amazingly, there aren't any.
  729. X
  730. New/changed variables:
  731. X
  732. X    complete
  733. X    If both characters of the value of complete are the same, e.g.
  734. X    set complete='\E\E', then mush will complete unique filename
  735. X    matches, but non-unique matches will produce a listing before
  736. X    completing the match as far as possible.  This has no effect
  737. X    in tool mode.
  738. X
  739. X    compose_icon
  740. X    In tool mode, setting this variable permits the compose window
  741. X    to be separately iconified, and optionally specifies the icon
  742. X    to be used for the compose window's iconic form.
  743. X
  744. X    hdr_format
  745. X    The new format %u returns the user name part of the sender's
  746. X    address.
  747. X
  748. X    indent_str
  749. X    This string can now contain hdr_format references, just as
  750. X    pre_indent_str and post_indent_str always have.
  751. X
  752. Details of general changes:
  753. X
  754. X  * A simple comparison against the file names of all currently locked
  755. X    files is performed before attempting to get a new lock.  This helps
  756. X    prevent deadlock when the the same file is given more than once as
  757. X    a target for a copy of an outgoing message.  Note that deadlock will
  758. X    still occur if the same file is referenced twice under two different
  759. X    names, i.e. one of the names is a link.
  760. X
  761. Bugs fixed:
  762. X
  763. X  * The tool mode header display repaints properly when all messages in
  764. X    the folder have been deleted.
  765. X  * The tool mode Options (Variables) window no longer gets out of sync
  766. X    with the actual values of the variables.  Thanks to Bill Randle.
  767. X  * Using mush pipes in tool mode fkey functions doesn't improperly
  768. X    attempt to redraw the header display, and hence doesn't core dump.
  769. X  * Setting $tool_help in the Mushrc or .mushrc actually works now.
  770. X  * Curses mode won't let you scroll into negative message numbers when
  771. X    all messages in the folder have been deleted.
  772. X  * Some obscure date formats are handled better.
  773. X  * Using "folder -N" in curses mode works sensibly.
  774. X  * File locking on folders blocks properly on SYSV machines.  This is
  775. X    especially important for SCO UNIX, because of MMDF.
  776. X  * The last (we hope) of the overlapping strcpy's has been purged.
  777. X  * INTERNAL_MALLOC should be a little more robust.
  778. X  * Warnings (as in "set warning") are now properly turned on and off
  779. X    around "folder" commands.
  780. X  * Sending a SIGHUP to a suspended mush no longer triggers a SIGTTOU.
  781. X    Instead, mush exits relatively nicely, but without printing the
  782. X    usual error messages.
  783. X
  784. Tool mode changes:
  785. X
  786. X  * The compose frame may optionally be separately iconified.  See the
  787. X    remarks under the compose_icon variable.  Thanks to Bill Randle.
  788. X
  789. NOTE:
  790. X
  791. X    Some copies of 7.2.2 dated 3/26/91 or earlier have a bug in malloc.c.
  792. X    If you are not using INTERNAL_MALLOC this will have no effect on the
  793. X    behavior of the program, so the patchelevel was not changed.  The bug
  794. X    will cause mush to allocate memory continuously as it runs (free() is
  795. X    effectively disabled).  If you have such a copy, line 230 of malloc.c
  796. X    will look like this:
  797. X
  798. X    230:    if (cp == NULL || debug < 5)
  799. X
  800. X    It should read:
  801. X
  802. X    230:    if (cp == NULL || debug > 4)
  803. X
  804. X    Correct versions can be obtained as usual from cse.ogi.edu, and have
  805. X    the date 4/12/91 in version.h.
  806. SHAR_EOF
  807. chmod 0644 README-7.2.2 ||
  808. echo 'restore of README-7.2.2 failed'
  809. Wc_c="`wc -c < 'README-7.2.2'`"
  810. test 4503 -eq "$Wc_c" ||
  811.     echo 'README-7.2.2: original size 4503, current size' "$Wc_c"
  812. rm -f _shar_wnt_.tmp
  813. fi
  814. # ============= addrs.c ==============
  815. if test -f 'addrs.c' -a X"$1" != X"-c"; then
  816.     echo 'x - skipping addrs.c (File already exists)'
  817.     rm -f _shar_wnt_.tmp
  818. else
  819. > _shar_wnt_.tmp
  820. echo 'x - extracting addrs.c (Text)'
  821. sed 's/^X//' << 'SHAR_EOF' > 'addrs.c' &&
  822. /* addrs.c -- copyright (c) Dan Heller 1/25/1989 */
  823. X
  824. #include "mush.h"
  825. X
  826. /*
  827. X * Check to see if all addressees in list1 is in list2.
  828. X * The lists must be as clean as the driven snow (no comments, aliases
  829. X * must have been expanded, all are separated by whitespace (for mk_argv).
  830. X *
  831. X * "user" matches "user" and "user@localhost"
  832. X * "*user" matches "user" at any address whatsoever."
  833. X * !host matches any user destined for the specified host.
  834. X * !some!path is the same, but can be more specifiec in the path.
  835. X * @dom.ain can match any user destined for any host within the domain.
  836. X *      @berkeley.edu would match: dheller@cory.berkeley.edu
  837. X */
  838. compare_addrs(list1, list2, ret_buf)
  839. char *list1, *list2, ret_buf[];
  840. {
  841. X    register char    *p;
  842. X    char        **addrv, **listv, buf[256]; /* addrs aren't long */
  843. X    int            addrc, listc, a, l, h, ret_val;
  844. X
  845. X    /* autosign2 list contains non-comment addresses */
  846. X    listv = mk_argv(list1, &listc, FALSE);
  847. X    addrv = mk_argv(list2, &addrc, FALSE);
  848. X
  849. X    /* loop thru both lists and convert addresses to !-format
  850. X     * then remove ourhost names so "user" matches "user!local"
  851. X     * also remove possible trailing commas (from list).
  852. X     */
  853. X    for (a = 0; a < addrc; a++) {
  854. X    if (a != addrc-1 && (p = index(addrv[a], ',')) && !p[1])
  855. X        *p = 0;
  856. X    if (addrv[a][0] == '!' || addrv[a][0] == '@')
  857. X        continue;
  858. X    (void) bang_form(buf, addrv[a]);
  859. X    if (strcmp(addrv[a], buf)) /* if they differ... */
  860. X        (void) strcpy(addrv[a], buf); /* save new version */
  861. X    }
  862. X    for (l = 0; l < listc; l++) {
  863. X    if (l != listc-1 && (p = index(listv[l], ',')) && !p[1])
  864. X        *p = 0;
  865. X    if (listv[l][0] == '!' || listv[l][0] == '@')
  866. X        continue;
  867. X    (void) bang_form(buf, listv[l]);
  868. X    if (strcmp(listv[l], buf)) /* if they differ... */
  869. X        (void) strdup(listv[l], buf); /* save new version */
  870. X    }
  871. X
  872. X    Debug("\nlist1 = "), print_argv(listv);
  873. X    Debug("list2 = "), print_argv(addrv), putchar('\n');
  874. X
  875. X    /* loop thru each list comparing each element with the
  876. X     * other, if necessary.
  877. X     */
  878. X    for (l = 0; l < listc; l++) {
  879. X    ret_val = 0;
  880. X    /* check if local recipient with was specified. */
  881. X    if (!(p = rindex(listv[l], '!')))
  882. X        for (a = 0; a < addrc; a++) {
  883. X        /* we have a local user so far.  If addrv[] is
  884. X         * not remote, then strcmp() immediately.
  885. X         * Note that "!" with no host indicates *all*
  886. X         * local users!!!
  887. X         */
  888. X        if (addrv[a][0] == '*') {
  889. X            /* "*user" == "user" or "*" == login */
  890. X            if (!addrv[a][1] && !lcase_strncmp(listv[l], login, -1) ||
  891. X            !lcase_strncmp(listv[l], addrv[a]+1, -1))
  892. X            ret_val = 1;
  893. X        } else if (addrv[a][0] != '!') {
  894. X           if (!lcase_strncmp(addrv[a], listv[l], -1) || !addrv[a][1])
  895. X            ret_val = 1;
  896. X        } else for (h = 0; ourname && ourname[h]; h++)
  897. X            if (!lcase_strncmp(addrv[a]+1, ourname[h], -1)) {
  898. X            ret_val = 1;
  899. X            break;
  900. X            }
  901. X        if (ret_val)
  902. X            break;
  903. X        }
  904. X    /* else this is a remote user */
  905. X    else {
  906. X        /* check all the addresses for @dom.ain stuff or
  907. X         * !path!name type stuff only.
  908. X         */
  909. X        /* first back up p to the previous '!' */
  910. X        char *start, *user = p + 1;
  911. X        while (p > listv[l] && *--p != '!')
  912. X        ;
  913. X        start = p; /* Where to start for _domain_ addrs */
  914. X        for (a = 0; a < addrc; a++) {
  915. X        int len;
  916. X        char *path;
  917. X
  918. X        /* first check the cases of address unmodified by @ and !
  919. X         * or check to see if  *user  is specified.
  920. X         */ 
  921. X        if (addrv[a][0] != '@' && addrv[a][0] != '!') {
  922. X            if (addrv[a][0] == '*') {
  923. X            /* we saved the username at "user" declaration. */
  924. X            /* if "*" is by itself, check against user's login */
  925. X            if (!addrv[a][1] && !lcase_strncmp(user, login, -1) ||
  926. X                addrv[a][1] && !lcase_strncmp(user,addrv[a]+1,-1)){
  927. X                ret_val = 1;
  928. X                break;
  929. X            }
  930. X            } else if (!lcase_strncmp(addrv[a], listv[l], -1)) {
  931. X            ret_val = 1;
  932. X            break;
  933. X            }
  934. X            continue;
  935. X        }
  936. X        path = addrv[a]+1;
  937. X        while (addrv[a][0] == '@' && *path == '.')
  938. X            path++;
  939. X        if ((len = strlen(path)) == 0)
  940. X            continue; /* localhost stuff only -- can't match */
  941. X        /* first check against specified domains */
  942. X        if (addrv[a][0] == '@') {
  943. X            for (p = start; p; (p = index(p, '.')) && ++p)
  944. X            if (!lcase_strncmp(p, path, len) &&
  945. X                (p[len] == '.' || p[len] == 0 || p[len] == '!')) {
  946. X                ret_val = 1;
  947. X                break;
  948. X            }
  949. X        } else if (addrv[a][0] == '!') {
  950. X            /* for !path style, start at head of addr */
  951. X            for (p = listv[l]; p; (p = index(p, '!')) && ++p)
  952. X            if (!lcase_strncmp(p, path, len) &&
  953. X                (p[len] == '!' || p[len] == 0)) {
  954. X                ret_val = 1;
  955. X                break;
  956. X            }
  957. X        }
  958. X        /* If address is in autosign2, goto next addr */
  959. X        if (ret_val)
  960. X            break;
  961. X        }
  962. X    }
  963. X    if (!ret_val) {
  964. X        /* this address isn't in autosign2 list */
  965. X        if (ret_buf)
  966. X        (void) strcpy(ret_buf, listv[l]);
  967. X        break;
  968. X    }
  969. X    }
  970. X    free_vec(listv);
  971. X    free_vec(addrv);
  972. X
  973. X    return ret_val;
  974. }
  975. X
  976. /*
  977. X * Parser for stupidly-formed RFC822 addresses.  It has been tested on
  978. X * several bizzare cases as well as the normal stuff and uucp paths.  It
  979. X * takes a string which is a bunch of addresses and unscrambles the first
  980. X * one in the string.  It returns a pointer to the first char past what it
  981. X * unscrambled and copies the unscrambled address to its second argument.
  982. X * 
  983. X * It does NOT deal with trailing (comment) strings --
  984. X *         <whoever@somewhere> (This is a comment)
  985. X *                            ^unscramble_addr return points here
  986. X * 
  987. X * It also does not deal well with malformed <addresses> --
  988. X *         <whoever@somewhere,nowhere>
  989. X *                           ^unscramble_addr return points here
  990. X * 
  991. X * In each of the above cases, the string "whoever@somewhere" is copied
  992. X * to the second argument.
  993. X * 
  994. X * Nothing is done to un-<>ed route-less RFC822/976 addresses, nor to
  995. X * uucp paths, nor to mixed-mode addresses not containing a route.
  996. X * Hopelessly scrambled addresses are not handled brilliantly --
  997. X *     @some.dumb.place,@any.other.place:sys2!user%sys3@sys1
  998. X * parses to
  999. X *     sys2!user%sys3@sys1
  1000. X * i.e., the route is simply dropped.
  1001. X *
  1002. X * If UUCP is defined, a little more work is done with @: routes.  The
  1003. X * mangled address given above will unwind to
  1004. X *    some.dumb.place!any.other.place!sys1!sys2!sys3!user
  1005. X * thanks to intelligence in bang_form().
  1006. X */
  1007. char *
  1008. unscramble_addr(addr, naddr)
  1009. char *addr;
  1010. char *naddr;
  1011. {
  1012. X    char *i, *r, *at;
  1013. X    char s[BUFSIZ], t[BUFSIZ];
  1014. X    int anglebrace = 0;
  1015. X
  1016. X    /* Make a copy of the address so we can mangle it freely. */
  1017. X    if (addr && *addr) {
  1018. X    /* Skip any leading whitespace. */
  1019. X    for (i = addr; *i && index(" \t", *i); i++)
  1020. X        ;
  1021. X    if (*i == '\0')
  1022. X        return NULL;
  1023. X    /* Skip any leading double-quoted comment. */
  1024. X    if (*i == '"') {
  1025. X        if ((i = index(i + 1, '"')) && (*i == '\0' || *(++i) == '\0'))
  1026. X            return NULL;
  1027. X    }
  1028. X    /* Skip any more whitespace. */
  1029. X    while (*i && index(" \t", *i))
  1030. X        i++;
  1031. X    if (*i == '\0')
  1032. X        return NULL;
  1033. X    /* Check for angle braces around the address. */
  1034. X    if (*i == '<') {
  1035. X        if (*(++i) == '\0')
  1036. X        return NULL;
  1037. X        ++anglebrace;
  1038. X    }
  1039. X    /*
  1040. X     * Look for a route.  A route is a comma-separated set of @-tagged
  1041. X     *  domains terminated by a colon.  Later versions might try to use
  1042. X     *  the route, but for now it confuses too many mailers.
  1043. X     */
  1044. X    if ((*i == '@') && (r = any(i, " \t:"))) {
  1045. X        if (*r != ':')
  1046. X        return NULL;
  1047. X        if (*(r + 1) == '\0')
  1048. X        return NULL;
  1049. #ifndef UUCP
  1050. X        /*
  1051. X         * Back up to the rightmost @-tagged domain
  1052. X         *  (see note below about unwinding)
  1053. X         */
  1054. X        *r = '\0';
  1055. X        i = rindex(i, '@');
  1056. X        *r = ':';
  1057. #endif /* !UUCP */
  1058. X    }
  1059. X    /* Remember how much we've skipped, and copy the rest. */
  1060. X    at = i;
  1061. X    (void) strncpy(t, i, sizeof t);
  1062. X    t[sizeof t - 1] = 0;
  1063. X    /* Strip from a trailing angle brace, if present. */
  1064. X    if (anglebrace) {
  1065. X        if (r = any(t, "> \t")) {
  1066. X        if (r == t || *r != '>')
  1067. X            return NULL;
  1068. X        else
  1069. X            *r = '\0';
  1070. X        --anglebrace;
  1071. X        } else
  1072. X        return NULL;
  1073. X    }
  1074. X    if (t[0] == '@') {
  1075. X        /* Chop off any invalid stuff after the address. */
  1076. X        if (r = any(index(t, ':'), " \t,(<"))
  1077. X        *r = '\0';
  1078. X    }
  1079. X    } else
  1080. X    return NULL;
  1081. X    /* Remember where we are so we can return it. */
  1082. X    at += strlen(t) + 1;
  1083. X    /*
  1084. X     * Unscramble the route, if present.
  1085. X     *  NOTE:  We assume that a route is present in only two cases:
  1086. X     *   1) addr was taken from the "From " line of a stupid mailer
  1087. X     *   2) addr was a well-formed, <> enclosed RFC822 address
  1088. X     */
  1089. X    if (t[0] == '@') {
  1090. #ifdef UUCP
  1091. X    if (!bang_form(s, t))
  1092. X        return NULL;
  1093. #else /* UUCP */
  1094. X    if (r = index(t, ':'))
  1095. X        r++;
  1096. X    else
  1097. X        return NULL;
  1098. X    /* Delete the route if extraneous, otherwise unwind it. */
  1099. X    if (i = index(r, '@'))
  1100. X        (void) strcpy(s, r);
  1101. X    else {
  1102. X        /*
  1103. X         * NOTE:  Unwinding currently uses only the rightmost domain
  1104. X         *  in the route.  This will break for mailers that need the
  1105. X         *  entire route.  Complete unwinding would require the use
  1106. X         *  of % characters, which are avoided for other reasons.
  1107. X         */
  1108. X        (void) strcpy(s, r);
  1109. X        *(--r) = '\0';
  1110. X        (void) strcat(s, t);
  1111. X    }
  1112. #endif /* UUCP */
  1113. X    } else
  1114. X    (void) strcpy(s, t);
  1115. X    /*
  1116. X     * Ok, now the address should be in the form user@domain and
  1117. X     *  is held in buffer s (t[] is not copied directly to naddr
  1118. X     *  to allow future additional processing to be added here).
  1119. X     */
  1120. X    if (debug > 1) /* Don't dump this on trivial debugging */
  1121. X    wprint("Converting \"%s\" to \"%s\"\n", addr, s);
  1122. X    (void) strcpy(naddr, s);
  1123. X    return at;
  1124. }
  1125. X
  1126. /*
  1127. X * Convert RFC822 or mixed addresses to RFC976 `!' form,
  1128. X *  copying the new address to d.  The source address is
  1129. X *  translated according to RFC822 rules.
  1130. X * Return a pointer to the end (nul terminus) of d.
  1131. X */
  1132. char *
  1133. bang_form (d, s)
  1134. char *d, *s;
  1135. {
  1136. X    char *r, *t, *ab = NULL;
  1137. X
  1138. X    *d = '\0';
  1139. X    /* If nothing to do, quit now */
  1140. X    if (!s || !*s) {
  1141. X    return d;
  1142. X    }
  1143. X    /* Avoid any angle braces */
  1144. X    if (*s == '<') {
  1145. X    if (ab = index(s + 1, '>'))
  1146. X        s++, *ab = '\0';
  1147. X    else
  1148. X        return NULL;
  1149. X    }
  1150. X    /*
  1151. X     * Look backwards for the first `@'; this gives us the
  1152. X     * primary domain of the RFC822 address
  1153. X     */
  1154. X    if (*s == '@') {
  1155. X    /* An RFC-822 "@domain1,@domain2:" routing */
  1156. X    if (t = any(++s, ",:")) {
  1157. X        char c = *t;
  1158. X        *t = '\0';
  1159. X        d += Strcpy(d, s);
  1160. X        *d++ = '!';
  1161. X        *t++ = c;
  1162. X        r = bang_form(d, t);
  1163. X    } else
  1164. X        r = NULL;
  1165. X    } else if ((t = rindex(s, '@')) && t != s) {
  1166. X    /* Copy the RFC822 domain as the UUCP head */
  1167. X    d += Strcpy(d, t + 1);
  1168. X    *d++ = '!';
  1169. X    *t = '\0';
  1170. X    r = bang_form(d, s);
  1171. X    *t = '@';
  1172. X    } else if (t = index(s, '!')) {
  1173. X    /* A normal UUCP path */
  1174. X    *t = '\0';
  1175. X    d += Strcpy(d, s);
  1176. X    *t++ = *d++ = '!';
  1177. X    r = bang_form(d, t);
  1178. X    } else if (t = rindex(s, '%')) {
  1179. X    /* An imbedded `%' -- treat as low-priority `@' */
  1180. X    *t = '@';
  1181. X    r = bang_form(d, s);
  1182. X    *t = '%';
  1183. X    } else
  1184. X    r = d + Strcpy(d, s);  /* No `@', `!', or `%' */
  1185. X    if (ab)
  1186. X    *ab = '>';
  1187. X    return r;
  1188. }
  1189. X
  1190. /*
  1191. X * Route addresses according to certain criteria.  This function is really
  1192. X * just a front end for improve_uucp_paths() which does routing (differently).
  1193. X * If "route" is null, this routine is being called incorrectly.
  1194. X * If route is an address, just call improve_uucp_paths() and return.
  1195. X * If route is the null string, then route all addresses via the sender's
  1196. X * which is the first name/address on the To: list. If he's on a remote
  1197. X * machine, chances are that the addresses of everyone else he mailed to
  1198. X * are addresses from his machine.  Reconstruct those addresses to route
  1199. X * thru the senders machine first.
  1200. X */
  1201. route_addresses(to, cc, route_path)
  1202. char *to, *cc, *route_path;
  1203. {
  1204. X    char pre_path[256], sender[HDRSIZ], tmp[256];
  1205. X    register char *next, *p;
  1206. X    int c;
  1207. X
  1208. X    Debug("route_addresses()\n");
  1209. X    if (!route_path)
  1210. X    return;
  1211. X    if (*route_path) {
  1212. X    improve_uucp_paths(to, HDRSIZ, route_path);
  1213. X    improve_uucp_paths(cc, HDRSIZ, route_path);
  1214. X    return;
  1215. X    }
  1216. X
  1217. X    pre_path[0] = 0;
  1218. X    /* Get the address of the sender (which is always listed first) */
  1219. X    if (!(next = get_name_n_addr(to, NULL, NULL)))
  1220. X    return;
  1221. X    c = *next, *next = 0;
  1222. X    (void) strcpy(sender, to);
  1223. X    *next = c;
  1224. X    /* fix up the sender's address; improve_uucp_paths to optimize pre_path */
  1225. X    improve_uucp_paths(sender, sizeof sender, NULL);
  1226. X
  1227. X    /* check to see if there is only one addr on To: line and no Cc: header */
  1228. X    if (!*next && (!cc || !*cc)) {
  1229. X    (void) strcpy(to, sender);
  1230. X    return;
  1231. X    }
  1232. X    /* otherwise, get the pre_path */
  1233. X    if (p = get_name_n_addr(sender, NULL, tmp))
  1234. X    c = p - sender; /* save the original length */
  1235. X    if (*tmp) {
  1236. X    (void) bang_form(pre_path, tmp);
  1237. X    if (p = rindex(pre_path, '!')) {
  1238. X        *p = 0;
  1239. X        Debug("Routing thru \"%s\"\n", pre_path);
  1240. X    } else
  1241. X        pre_path[0] = 0;
  1242. X    } else
  1243. X    pre_path[0] = 0;
  1244. X
  1245. X    while (*next == ',' || isspace(*next))
  1246. X    next++;
  1247. X    improve_uucp_paths(next, HDRSIZ - (int)(next - to), pre_path);
  1248. X    improve_uucp_paths(cc, HDRSIZ, pre_path);
  1249. SHAR_EOF
  1250. true || echo 'restore of addrs.c failed'
  1251. fi
  1252. echo 'End of  part 2'
  1253. echo 'File addrs.c is continued in part 3'
  1254. echo 3 > _shar_seq_.tmp
  1255. exit 0
  1256. exit 0 # Just in case...
  1257. -- 
  1258. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1259. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1260. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1261. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1262.