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

  1. From: argv@zipcode.com (Dan Heller)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i075:  mush - Mail User's Shell, Part18/22
  4. Message-ID: <1991Apr22.153612.29725@sparky.IMD.Sterling.COM>
  5. Date: 22 Apr 91 15:36:12 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: dab05017 add96bdd 69b50751 c0cb38da
  8.  
  9. Submitted-by: Dan Heller <argv@zipcode.com>
  10. Posting-number: Volume 18, Issue 75
  11. Archive-name: mush/part18
  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 mush.1 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" != 18; 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 mush.1'
  32. else
  33. echo 'x - continuing file mush.1'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'mush.1' &&
  35. or are strings that are automatically generated by pressing a special
  36. key on the terminal.
  37. On the other hand, the timeout can be used intentionally to prevent a
  38. macro from being expanded; simply type the first character of the macro,
  39. then wait for it to echo before typing the next.
  40. This does not work in curses mode, because curses macros
  41. never \*Qtime out.\*U
  42. .PP
  43. In any mode, macros are
  44. .IR recursive ;
  45. that is, if the
  46. .I "key sequence"
  47. of one macro appears in the
  48. .I expansion
  49. of another macro (or even of the same macro), the second key sequence
  50. is recognized when the first macro is expanded, and this new key
  51. sequence is also expanded.
  52. Great care should be taken when creating macros to be certain that
  53. recursive expansions do not happen unintentionally.
  54. Expansion can be prevented in line or composition modes by using a
  55. .I literal-next
  56. character.
  57. .PP
  58. Literal-next characters may be used from the keyboard or embedded
  59. in expansions.
  60. In either case, they prevent the next character
  61. from being interpreted as part of a key sequence.
  62. .I Mush
  63. recognizes the literal-next character from the tty settings of the
  64. terminal, if the \*Qnew\*U BSD-style device driver is available;
  65. otherwise, `^V' (control-V) is recognized as a literal-next.
  66. Note that, if you have a tty literal-next character,
  67. then when typing you need to type
  68. .I two
  69. of them in order to send one to \fIMush\fR; this is because the tty
  70. driver consumes the first one.
  71. It is not necessary to use two literal-nexts in macro expansions
  72. unless you wish to cause the second literal-next to be literal.
  73. .PP
  74. Backslash can be used as a literal-next when typing, and can
  75. sometimes be used as a literal-next in expansions; but use it
  76. with caution, because it also introduces escape sequences
  77. (see \*QMacro syntax,\*U below).
  78. There is no literal-next mechanism for curses mode.
  79. .PP
  80. A macro always aborts whenever
  81. .I any
  82. command called by the macro returns an error.
  83. This includes recursive expansions, so no matter how often a macro has
  84. recurred, it is terminated completely.
  85. Errors in curses mode include illegal cursor movements, such as up from
  86. the top of the screen or down from the last message.
  87. .PP
  88. .BR "Macro syntax" .
  89. .PP
  90. A special syntax is provided for specifying control characters and other
  91. non-printing characters in macro key sequences and expansions.
  92. This syntax is the same as that for bindings, discussed in the
  93. CURSES INTERFACE section; it can be summarized as:
  94. .ta 1.25i
  95. .in +2
  96. .nf
  97. \\CX    control-X (where X is any capital letter)
  98. \\E    the escape character
  99. \\n    a newline (other C-style escapes also work)
  100. .fi
  101. .in -2
  102. .sp
  103. Thus, to create a line mode macro for control-X control-W, as in the
  104. example above, the command is
  105. .sp
  106. .ti +4
  107. map '\\CX\\CW' save
  108. .PP
  109. Also provided is a syntax for executing functions from within macros.
  110. There are two special functions that are effective in all modes;
  111. these are
  112. .I getstr
  113. and
  114. .IR getline .
  115. Both of these functions interrupt expansion of the current macro,
  116. and wait for a newline-terminated string to be entered from the
  117. standard input.
  118. This input string is inserted into the macro expansion.
  119. The functions differ in that
  120. .B getline
  121. retains the newline character (carriage-return) at the end of the
  122. input string, whereas
  123. .B getstr
  124. strips off the newline (one must still be typed to terminate input).
  125. These functions can be executed by surrounding their name with
  126. square brackets
  127. .RB ( [ ,
  128. .BR ] );
  129. for example,
  130. .sp
  131. .ti +4
  132. map '\\CX\\CW' save [getline]
  133. .sp
  134. creates a line mode macro, which is expanded when control-X control-W is
  135. typed, and which displays \*Qsave\*U followed by a space and then waits
  136. for the user to type a line of input; the input line is used as the
  137. arguments to the save command.
  138. .PP
  139. Additional functions are currently available only in the curses mode.
  140. However, the syntax of enclosing the function name in square brackets
  141. applies to all functions, regardless of mode.
  142. Note that
  143. .I ONLY
  144. the function name can appear in the brackets; no whitespace is allowed.
  145. .PP
  146. .BR "Curses mode macros" .
  147. .PP
  148. Macros in curses mode are the most versatile, because they can access the
  149. full range of curses commands quickly and easily.
  150. Every character that appears in the expansion part of a curses mode macro
  151. can reference a curses command or another macro.
  152. Like other curses functions, curses mode macros are created with the
  153. .B bind
  154. command.
  155. For example, to sort your messages by date and then send the most recent
  156. one to the printer, you could use
  157. .sp
  158. .ti +4
  159. bind @ macro 'od$|'
  160. .sp
  161. When the `@' key is typed, this macro first invokes sort
  162. (`o' from the default bindings) and instructs it to use date (d)
  163. for sorting; it then moves the current-message pointer to the last
  164. message ($) and prints that message (|).
  165. .PP
  166. Admittedly, the above macro is somewhat cryptic, and is dependent upon
  167. the bindings for sort, last-msg, and lpr being set to the defaults.
  168. It is better, and possibly more understandable, to refer to the
  169. desired curses functions without using their key bindings.
  170. To allow this, the \*Q[function]\*U syntax described above may be used
  171. in curses mode macros to reference curses functions.
  172. The only function that is prohibited from appearing in the \*Q[\|]\*U
  173. is the special
  174. .I macro
  175. function, which cannot be called when it has no binding.
  176. The example macro can therefore be rewritten as
  177. .sp
  178. .ti +4
  179. bind @ macro [sort]d[last-msg][lpr]
  180. .sp
  181. Such references to curses functions may be made only in curses mode
  182. macros, and are effective only when \fIMush\fR is actually in curses mode.
  183. That may sound strange, but the most common use of curses macros is
  184. to quickly perform functions that require an escape to the line mode.
  185. For example, although there is a variation of the curses mode
  186. .I mail
  187. function that prompts for additional flags, there is no function
  188. to prompt for flags to be passed to
  189. .IR reply .
  190. A macro can easily be created to provide this:
  191. .sp
  192. .ti +4
  193. bind R macro '[line-mode]reply '
  194. .sp
  195. This macro binds `R' to perform an escape to line mode and type
  196. the string \*Qreply\*U followed by a space.
  197. Macro expansion then ends, leaving it up to the user to supply
  198. flags to the command or to backspace over it if a different command
  199. (or none) is desired.
  200. Of course, the macro could also have provided some default arguments:
  201. .sp
  202. .ti +4
  203. bind R macro '[line-mode]reply \-ei '
  204. .PP
  205. Note that, if the
  206. .B getline
  207. or
  208. .B getstr
  209. function is used in a line-mode escape, it is not possible to
  210. erase the text that is typed before the
  211. .IR get ;
  212. that is, if the macro is
  213. .sp
  214. .ti +4
  215. bind R macro '[line-mode]reply \-ei [getline]'
  216. .sp
  217. then the user is forced to use the \-ei flags.
  218. .PP
  219. .BR "Line mode macros" .
  220. .PP
  221. Line mode macros combine some of the convenience of single-keystroke
  222. commands with the versatility of the line-oriented text interface.
  223. As has been noted, the choice of characters for line mode key sequences
  224. should be made carefully, so as not to interfere with normal typing.
  225. Line mode macros are created with the
  226. .B map
  227. command; for example, suppose you frequently forward messages to a
  228. friend named \*Qfred.\*U  You could create a macro to do this:
  229. .sp
  230. .ti +4
  231. map '\\CF' 'mail \-f . fred\\n'
  232. .sp
  233. This macro causes the single keystroke `^F' (control-F) to forward
  234. the current message to \*Qfred.\*U  Note the newline
  235. character \*Q\\n\*U at the end of the expansion;
  236. this causes the command to be executed immediately,
  237. without you having to type a carriage-return.
  238. .PP
  239. The expansion part of a line mode macro echoes to the screen when
  240. it is expanded, so you can see what the macro is doing.
  241. You can therefore use parts of the expansion as a \*Qprompt.\*U  In
  242. the above example, suppose you wished to enter a message list rather
  243. than always forwarding the current message.
  244. Change the macro to:
  245. .sp
  246. .ti +4
  247. map '\\CF' 'mail \-f [getstr] fred\\n'
  248. .sp
  249. This version of the macro prints \*Qmail \-f\*U and a space, then waits
  250. for a newline-terminated string from the standard input.
  251. The newline is stripped, and the string is used as the message list
  252. passed to the \*Qmail \-f\*U command.
  253. The address \*Qfred\*U is also passed to
  254. .BR mail ,
  255. so the messages in the list are forwarded to fred.
  256. .PP
  257. If you want to be able to \*Qchange your mind\*U after starting a
  258. line mode macro, you must leave the \*Q\\n\*U out of the expansion.
  259. Without the newline, the macro is not executed immediately, so
  260. you have a chance erase the line (or part of it) and type
  261. something different.
  262. Remember that the
  263. .B getline
  264. function keeps the newline in the string it gets, so if you don't
  265. want a newline to appear, you must use
  266. .BR getstr .
  267. When using the
  268. .I get
  269. functions, you should also remember that you can
  270. .I never
  271. backspace past the \*Qbeginning\*U of a
  272. .BR getline ,
  273. and you can backspace past the beginning of a
  274. .B getstr
  275. only after the get has been completed.
  276. .PP
  277. When the
  278. .B getstr
  279. function is used in line mode macros,
  280. .I Mush
  281. reprints the current input line so you can see what the whole
  282. thing looks like, but does not redisplay the line mode prompt
  283. (see the entry for
  284. .B prompt
  285. in the VARIABLES section for information on what the
  286. prompt looks like).
  287. Don't let this worry you.
  288. The input line is also reprinted when
  289. .B getline
  290. is used, but the newline in the input string usually results in a
  291. new prompt being displayed.
  292. .PP
  293. .IR NOTE :
  294. Line mode macros are not available when using the line-mode escape
  295. function in curses mode.
  296. It is necessary to escape all the way to line mode (that is, leave
  297. curses mode by typing carriage-return at the `:' prompt) in order
  298. to access line mode macros.
  299. This is to prevent possible confusion when similar macros exist
  300. in both line and curses modes.
  301. .PP
  302. .BR "Composition mode macros" .
  303. .PP
  304. Composition mode macros are very similar to line mode macros, and
  305. provide a \*Qpower typing\*U function when composing messages.
  306. For example, you might want to have the word \*Qpercent\*U inserted
  307. into your message whenever you hit the `%' key:
  308. .sp
  309. .ti +4
  310. map! % percent
  311. .sp
  312. Another use is to simulate the indentation features of editors.
  313. For example, you might
  314. .sp
  315. .ti +4
  316. map! '\\CT' '\ \ \ \ '
  317. .sp
  318. (where the expansion is four spaces, enclosed in single quotes).
  319. This macro causes four spaces to be inserted into the message whenever
  320. control-T is typed.
  321. .PP
  322. Composition mode macros can also be used to execute
  323. .I tilde-escapes
  324. (see the GENERAL USAGE section for a list of these).
  325. For example, you could create a macro to invoke the editor:
  326. .sp
  327. .ti +4
  328. map! '\\CE' '\\n~v\\n'
  329. .sp
  330. When control-E is typed, this macro prints a newline (to be sure that
  331. the tilde-escape is the first thing on a line), then types \*Q~v\*U
  332. followed by another newline, to start the editor.
  333. Similar macros can be created for other tilde-escapes.
  334. .PP
  335. .BR "Mixed mode macros" .
  336. .PP
  337. It is not normally possible to mix macros among the different modes.
  338. However, once expansion has begun, it is interrupted only by an error
  339. or by the appearance of one of the special
  340. .I get
  341. functions.
  342. It is therefore possible to have a macro expansion which causes
  343. the mode to change before the expansion has completed.
  344. In this case, recursive expansions apply to the new mode.
  345. Suppose we are using a variation of the editor-starting macro shown
  346. above for composition mode:
  347. .sp
  348. .ti +4
  349. map! '\\CE' '\\n~v emacs\\n'
  350. .sp
  351. This macro causes the \*Qemacs\*U editor to be started when control-E
  352. is typed in composition mode.
  353. We can now create a line mode macro that makes use of this
  354. composition mode macro:
  355. .sp
  356. .ti +4
  357. map '#' 'reply \-i [getline]~t[getline]\\CE'
  358. .sp
  359. When the `#' key is pressed in line mode, this macro
  360. prints \*Qreply \-i\*U and waits for a message list, then enters
  361. composition mode (by executing the
  362. .B reply
  363. command).
  364. In composition mode, it displays the To: line
  365. (the \*Q~t\*U escape) and waits for other addresses to be added.
  366. Finally, it recursively expands the control-E macro, to
  367. start editing the message with emacs.
  368. .PP
  369. As can be seen from this example, the
  370. .I Mush
  371. macro facility is very powerful.
  372. Be very careful not to accidentally expand recursive macros,
  373. especially when using macros that change modes.
  374. When testing new macros, it is a good idea to start
  375. .I Mush
  376. in
  377. .I read-only
  378. mode (the \-r command line flag) to be sure that messages are
  379. not lost or altered.
  380. .PP
  381. .BR "Getting rid of macros" .
  382. .PP
  383. It is not necessary to delete a macro in order to redefine it.
  384. New expansions for existing key sequences automatically replace
  385. the old expansions.
  386. If it is necessary to remove a macro completely, the commands
  387. .BR unbind ,
  388. .B unmap
  389. and
  390. .B unmap!
  391. can be used to remove curses mode, line mode, and composition mode
  392. macros, respectively.
  393. Remember to use a backslash or other literal-next character to prevent
  394. the expansion of line mode macros when using these commands, especially
  395. .BR unmap .
  396. .SH "MAIL ADDRESSES"
  397. Whenever a command that requires a user address or set of addresses
  398. is specified
  399. .RB ( mail ,
  400. .BR reply ,
  401. .BR alias ,
  402. .BR etc )
  403. the addresses given must be separated by commas.
  404. Most casual users specify addresses that contain no comments or whitespace.
  405. The simplest addresses are just the login names of the users you wish to send
  406. your message to:
  407. .sp
  408. .ti +2
  409. \fBmail\fR fred barney wilma betty
  410. .sp
  411. In these cases,
  412. .I Mush
  413. can figure out that they are separate addresses and
  414. insert commas between addresses automatically.
  415. .sp
  416. .ti +2
  417. To: fred, barney, wilma, betty
  418. .sp
  419. Addresses may also contain `!', `@' and `%' characters which are used
  420. to separate hostnames and the final user name from each other.
  421. This is primarily used to mail to users on other machines.
  422. UUCP addresses are specified as
  423. .sp
  424. .ti +2
  425. host1!host2!user
  426. .sp
  427. where there may be as many hosts as necessary to route the message
  428. to the recipient user.
  429. Here, the user's account is on \*Qhost2\*U
  430. and that machine is connected to \*Qhost1\*U.
  431. .I Domain
  432. addresses (also called Arpanet, Internet, RFC822, and \*Qfully qualified\*U
  433. addresses) are specified as
  434. .sp
  435. .ti +2
  436. user@host.domain
  437. .ti +2
  438. user%host2.domain@host1
  439. .sp
  440. where \*Qdomain\*U is a domain name such as \*Q.berkeley.edu\*U or \*Q.com\*U.
  441. As in the first example, the user is on \*Qhost2\*U, but that machine talks
  442. to \*Qhost1\*U.
  443. It is beyond the scope of this document to discuss in detail the ramifications
  444. of inter-network mailing.
  445. More information can be obtained through your system manager.
  446. .PP
  447. .I Mush
  448. understands addresses containing a comment field.
  449. Comment fields do not affect the destination address of mail being sent.
  450. These fields are purely for
  451. human legibility and may be specified according to the following constraints: 
  452. .sp
  453. Anything within angle brackets is an address; whatever is outside of the
  454. address is considered a comment:
  455. .sp
  456. .ti +2
  457. Dan Heller <zipcode!argv@cad.berkeley.edu>
  458. .ti +2
  459. Dan Heller <argv@zipcode.com>
  460. .sp
  461. Anything that has parentheses is a comment; whatever is outside of the
  462. parentheses is considered the address:
  463. .sp
  464. .ti +2
  465. zipcode!argv (Dan Heller)
  466. .ti +2
  467. argv@zipcode.com (Dan Heller)
  468. .sp
  469. Double quotes (") are treated just like parentheses:
  470. .sp
  471. .ti +2
  472. "Dan Heller" zipcode!argv
  473. .ti +2
  474. "Dan Heller" argv@zipcode.com
  475. .sp
  476. If the comment is to contain a comma, the first case above may not be used;
  477. you must use either the parenthesis or double-quote cases.
  478. .sp
  479. .ti +2
  480. fred@flintstone.bed.rock (Fred Flintstone, Cave Man)
  481. .sp
  482. If the comment contains unbalanced quotes, unpredictable results may occur
  483. .RI ( Mush
  484. won't deliver the mail).
  485. .sp
  486. Since the angle brackets have the highest precedence, quotes or parentheses
  487. may be used in conjunction with one another.
  488. .sp
  489. .ti +2
  490. Yabba Dabba Doo (Fred Flintstone) <fred>
  491. .ti +2
  492. Scoobie "Doobie" Doo <scooby@shaggys.mystery.machine>
  493. .PP
  494. Multiple addresses may appear on a line:
  495. .sp
  496. .in +2
  497. argv@zipcode.com argv@garp.mit.edu dheller
  498. .in -2
  499. .sp
  500. Because there is no indication of comments (parenthesis, angle bracket,
  501. or quotes), it is assumed that these are separate addresses and
  502. .I Mush
  503. inserts commas between these addresses accordingly.
  504. It is for this reason that the user is encouraged to explicitly insert
  505. commas between all mail addresses and not depend on the automation of comma
  506. insertion to correctly separate addresses from one another.
  507. .PP
  508. Mail aliases may contain addresses of the form described above.
  509. .sp
  510. .nf
  511. .in +2
  512. .ta 1.5i
  513. alias george    George Jetson <george@spacely.space.sprockets>
  514. alias jane    Jane Jetson <jane@sky-high.appts>
  515. alias group    george, jane
  516. .in -2
  517. .fi
  518. .sp
  519. You can mail using the alias as an address and it is expanded
  520. accordingly.
  521. You cannot, however, reference an alias and specify a
  522. comment or another address at the same time.
  523. .sp
  524. .ti +2
  525. To: The Jetsons <group>
  526. .sp
  527. The comment \*QThe Jetsons\*U is not retained when the alias \*Qgroup\*U
  528. is expanded, because the entire address and comment are replaced by the
  529. expansion.
  530. .SH FILES
  531. .nf
  532. .ta 2.0i
  533. /usr/spool/mail/*    Directory for incoming mail
  534. ~/Mail    Default \fBfolder\fR directory
  535. ~/mbox    File where old mail is saved
  536. ~/.mushrc    File giving initial \fIMush\fR commands
  537. ~/.mailrc    Alternate initialization file
  538. ~/.edXXXXXXX    Temporary for file for outgoing messages
  539. ~/.mushXXXXXX    Temporary mail file (copy of current folder)
  540. .fi
  541. .PP
  542. Temporary files that are created by the program are always
  543. created with read/write access to the owner only; group and other
  544. permissions are never set.
  545. This is also true for the /usr/spool/mail/* files.
  546. All other files created by the user via commands internal or external
  547. to the program have permissions set by the user's default umask.
  548. If the umask is reset within the program, the mask remains
  549. intact even after exiting.
  550. Remember to set the variable
  551. .B unix
  552. before attempting to set the umask value.
  553. .PP
  554. If your system is using Sun Microsystem's NFS, take special note to
  555. read the manual page for mount(1).
  556. Filesystems mounted for read/write
  557. access should be mounted as \*Qhard\*U NFS mounts or you may lose
  558. mailboxes during a timeout during a write or update.
  559. .PP
  560. Filesystems that use RFS still have bugs to be ironed out in the way
  561. of owners and permissions concerning utime(2).
  562. .SH "SEE ALSO"
  563. .IR Mail (1),
  564. .IR binmail (1),
  565. .IR csh (1),
  566. .IR aliases (5),
  567. .IR mount (1),
  568. .IR mailaddr (7),
  569. .IR sendmail (8),
  570. .IR printf (3),
  571. .IR execl (3),
  572. .IR umask (1),
  573. .IR utime (2).
  574. .SH AUTHOR
  575. The original
  576. .I Mush
  577. was written entirely by Dan Heller.
  578. Code to support macros, line wrapping, and a whole lot of other miscellaneous
  579. details, was written by Bart Schaefer, who gets his name in print
  580. because he updated and proofread this manual.
  581. Numerous others have supplied valuable suggestions
  582. and assorted bits and pieces.
  583. .PP
  584. argv@sun.com       zipcode!argv
  585. .SH DISCLAIMERS
  586. .I Mush
  587. contains no
  588. .IR UNIX (TM)
  589. sources and never has.
  590. It is also not a modified version of any other mail user agent.
  591. Similarities
  592. with any other mailer may have been designed for compatibility reasons.
  593. .PP
  594. .I UNIX
  595. is a trademark of AT&T.
  596. .PP
  597. The Flintstones and The Jetsons are trademarks of Hannah-Barbara Inc.
  598. .SH BUGS
  599. The curses interface uses the curses library.
  600. The routines from the library that are used are the most basic and simple
  601. so as to avoid possible bugginess that
  602. different versions of UNIX might have.
  603. However, one unavoidable problem is the reverse video mode.
  604. Depending on your terminal,
  605. the termcap entry for it, and the version of curses you are running,
  606. the reverse video may make things worse than desired.
  607. In such situations, the user should set the variable
  608. .B no_reverse
  609. to not get reverse video.
  610. \&`^R' may still be entered at runtime in the curses
  611. interface to toggle reverse video.
  612. .PP
  613. Toggling from the curses mode to the line mode to get the full
  614. functionality of the shell/line mode is unfortunately necessary
  615. in order to maintain the display in a sensible manner and to keep the
  616. keystroke-command interface simple and \*Quser friendly\*U.
  617. Mostly, such escapes are only necessary
  618. for piping of commands and using the pick command.
  619. Macros are a big help with this.
  620. .PP
  621. If the program is already running and the system [later] has to swap
  622. and there is no swap space left, there may be problems.
  623. One such problem is sending mail.
  624. If this happens, then sending mail
  625. fails and a segmentation fault from the spawned/forked child may occur
  626. (unless the -v flag was given to mail).
  627. The unsent letter is not removed from the editing file ($home/.edXXXXXX)
  628. and may be recovered.
  629. .PP
  630. Many functions available to the line oriented mode (shell mode)
  631. are not available to the tool mode.
  632. For example,
  633. .B pick
  634. may not be directly accessed although experienced users may find that
  635. typing pick commands within single backquotes in the \*QRange:\*U panel item
  636. above the header window and then selecting a command that uses the range
  637. does indeed pick messages.
  638. This is mostly for selecting the \*Qdelete range\*U item
  639. or the middle mouse button icon in the header panel.
  640. .PP
  641. Version 6.5.6 was the last version designed to run under SunWindows, and is
  642. therefore the most recent version that functioned under SunOS 2.x.
  643. Starting with versions 7.x, the interface used is SunView, and may have
  644. a completely new set of problems in addition to those described below.
  645. Also, some of those described below may have been eliminated, and remain
  646. in this discussion only for completeness.
  647. .PP
  648. Shell escapes (of any kind) may be called only from the \*Qpipe\*U command
  649. in the tool mode, should not be interactive, and should produce
  650. output only to a file.
  651. The reason for this is that there is no tty
  652. .I window
  653. in which to do input/output.
  654. Since the interactive function-key binding interface has gone away, it is
  655. unfortunately only possible to execute commands that have been pre-defined
  656. in the initialization file.
  657. Future revisions may correct these deficiencies.
  658. .PP
  659. The function keys and their ability to
  660. .I work
  661. has been variable depending on the version of SunWindows/SunView
  662. your Sun Workstation has.  From time to time, it works, but when it
  663. doesn't, it seems to be related to other user or system definable
  664. dot-files or whatever.
  665. .PP
  666. Changing the value of the
  667. .BR screen_win ,
  668. .BR crt_win ,
  669. or
  670. .B msg_win
  671. variables after the tool is running simply has no effect.
  672. .PP
  673. When using
  674. .B vi
  675. in the tool mode, the window is periodically one or more
  676. lines \*Qshort.\*U
  677. That is, scrolling is off by one line and you have to redraw the
  678. window (using \*Qz.\*U in vi) to get it in sync again.  The problem
  679. is caused by the window having less than 24 lines in the window.
  680. Having the tty subwindow be
  681. .I exactly
  682. 24 lines usually eliminates the problem.  This is a bug with SunView
  683. and will not be fixed since Sun no longer supports it.
  684. .PP
  685. When running on full filesystems,
  686. .I Mush
  687. may complain or not even run since it needs temporary space with which
  688. to work.
  689. Instead of finding new filesystems on its own,
  690. .I Mush
  691. leaves this task up to the user.
  692. The workaround is to set the variable
  693. .B tmpdir
  694. in the initialization file to be a writable place in a filesystem that
  695. has enough disk space.
  696. Note: some systems' setcwd() system call writes temporary information in
  697. /tmp and this cannot be overridden.  You may get error messages such as
  698. "file system full" even if your
  699. .B tmpdir
  700. variable is set to a directory in a partition other than that of /tmp.
  701. There is nothing to be concerned about; chance are that you changed
  702. directories and the setcwd() system call can't write to its temp file.
  703. .PP
  704. Repeated sequences of creating and destroying compose frames
  705. uses up file descriptors in Sun OS 3.5, due to a bug where a destroyed
  706. ttysw does not free up its fd's.
  707. .PP
  708. Most of the other known and documented bugs
  709. are in the supplied README files accompanying the source.
  710. The source is also an excellent place to look as many known bugs are
  711. documented in comments.
  712. A good way to track suspicious bugs is to use the
  713. .B debug
  714. command, but note that
  715. this command is very difficult to use in curses mode.
  716. SHAR_EOF
  717. echo 'File mush.1 is complete' &&
  718. chmod 0644 mush.1 ||
  719. echo 'restore of mush.1 failed'
  720. Wc_c="`wc -c < 'mush.1'`"
  721. test 191116 -eq "$Wc_c" ||
  722.     echo 'mush.1: original size 191116, current size' "$Wc_c"
  723. rm -f _shar_wnt_.tmp
  724. fi
  725. # ============= mush.h ==============
  726. if test -f 'mush.h' -a X"$1" != X"-c"; then
  727.     echo 'x - skipping mush.h (File already exists)'
  728.     rm -f _shar_wnt_.tmp
  729. else
  730. > _shar_wnt_.tmp
  731. echo 'x - extracting mush.h (Text)'
  732. sed 's/^X//' << 'SHAR_EOF' > 'mush.h' &&
  733. /* @(#)mush.h    (c) copyright 1986 (Dan Heller) */
  734. X
  735. #include "config.h"
  736. X
  737. #ifdef CURSES
  738. X
  739. #ifdef USG
  740. #    define _USG
  741. #    undef USG
  742. #endif /* USG */
  743. #ifdef SYSV
  744. #    define _SYSV
  745. #    undef SYSV
  746. #endif /* SYSV */
  747. #include <curses.h>
  748. #if !defined(USG) && defined(_USG)
  749. #    define USG
  750. #endif /* USG */
  751. #if !defined(SYSV) && defined(_SYSV)
  752. #    define SYSV
  753. #endif /* SYSV */
  754. X
  755. #else /* CURSES */
  756. #include <stdio.h>
  757. #if defined(SYSV) && defined(USG)
  758. #include <termio.h>
  759. #endif /* SYSV && USG */
  760. #endif /* CURSES */
  761. X
  762. #include <ctype.h>
  763. #include <errno.h>
  764. #include <setjmp.h>
  765. #include "strings.h"
  766. X
  767. extern char
  768. X    *malloc(),        /* allocate memory */
  769. X    *calloc(),        /* allocate and clear memory */
  770. X    *realloc();        /* re-allocate memory */
  771. X
  772. extern void
  773. X    free_vec(),        /* free a malloc'ed argv */
  774. X    xfree();        /* free malloc'ed pointers */
  775. X
  776. #if defined(SUNTOOL) || defined(SUN_3_5) || defined(SUN_4_0) || defined(SUN_4_1)
  777. #if !defined(BSD) && !defined(SYSV)
  778. #    define BSD /* default to BSD */
  779. #endif /* !BSD && !SYSV */
  780. #if !defined(SUN_3_5) && !defined(SUN_4_0)
  781. #    ifndef SUN_4_1
  782. #        define SUN_4_1 /* default to sun 4.1 */
  783. #    endif /* SUN_4_1 */
  784. #    define SUN_4_0 /* 4.0 stuff needed too */
  785. #endif /* !SUN_3_5 && !SUN_4_0 */
  786. #ifdef SUN_4_0
  787. #    undef SUN_3_5
  788. #    undef SIGRET
  789. #    define SIGRET void
  790. #endif /* SUN_4_0 */
  791. #endif /* SUNTOOL || SUN_3_5 || SUN_4_0 || SUN_4_1 */
  792. X
  793. #ifdef BSD
  794. #define fputs Fputs    /* See comments in print.c */
  795. #endif /* BSD */
  796. X
  797. #if defined(BSD) || defined(GETWD)
  798. extern char *getwd();
  799. #define GetCwd(buf,len)    getwd(buf)
  800. #else
  801. extern char *getcwd();
  802. #define GetCwd(buf,len) getcwd(buf,len)
  803. #endif /* BSD || GETWD */
  804. X
  805. #ifdef SUNTOOL
  806. #    include <suntool/sunview.h>
  807. #ifdef SUN_4_0
  808. #    include <suntool/alert.h>
  809. #endif /* SUN_4_0 */
  810. #    include <suntool/textsw.h>
  811. #    include <sys/ioctl.h>   /* for ltchars */
  812. #else
  813. #    include <sys/types.h>
  814. #    include <signal.h>
  815. #    ifndef SYSV
  816. #    include <sys/time.h>
  817. #    include <sys/ioctl.h>   /* for ltchars */
  818. #    else
  819. #    include <time.h>
  820. #    include <fcntl.h>
  821. #    endif /* SYSV */
  822. #endif /* SUNTOOL */
  823. X
  824. #include <sys/stat.h>
  825. #include <sys/file.h>
  826. X
  827. #ifdef SUNTOOL
  828. #    include <suntool/panel.h>
  829. #    include <suntool/canvas.h>
  830. #    include <suntool/tty.h>
  831. #    include <suntool/menu.h>
  832. #    include <suntool/icon.h>
  833. #    include <suntool/scrollbar.h>
  834. #    include <suntool/icon_load.h>
  835. #endif /* SUNTOOL */
  836. X
  837. /* if no maximum number of files can be found, we'll use getdtablesize() */
  838. #ifdef _NFILE
  839. #    define MAXFILES _NFILE
  840. #else
  841. #ifdef NOFILE
  842. #    define MAXFILES NOFILE
  843. #endif /* NOFILE */
  844. #endif /* _NFILE */
  845. X
  846. #ifndef MAXPATHLEN
  847. #define MAXPATHLEN BUFSIZ
  848. #endif /* MAXPATHLEN */
  849. X
  850. #ifdef CTRL
  851. #undef CTRL
  852. #endif /* CTRL */
  853. #define CTRL(c)        ((c) & 037)
  854. X
  855. #define ESC         '\033'
  856. X
  857. #define NO_STRING    ""
  858. #ifdef  NULL
  859. #undef  NULL
  860. #endif /* NULL */
  861. #define NULL        (char *)0
  862. #define NULL_FILE    (FILE *)0
  863. #define DUBL_NULL    (char **)0
  864. #define TRPL_NULL    (char ***)0
  865. #ifdef putchar
  866. #undef putchar
  867. #endif /* putchar */
  868. #define putchar(c)    (void) (fputc(c, stdout), fflush(stdout))
  869. #ifdef SUNTOOL
  870. extern int bell();
  871. #else /* SUNTOOL */
  872. #define bell()        (void) (fputc('\007', stderr), fflush(stderr))
  873. #endif /* SUNTOOL */
  874. X
  875. /* For error recovery purposes, send keyboard generated signals to a special
  876. X * routine (interrupt) to set a global flag (WAS_INTR) and return to the
  877. X * calling routine which is responsible for checking the flag.  For both
  878. X * on_intr() and off_intr() macros, initialize WAS_INTR to false.
  879. X */
  880. #define on_intr() \
  881. X    turnoff(glob_flags, WAS_INTR), oldint = signal(SIGINT, intrpt), \
  882. X    oldquit = signal(SIGQUIT, intrpt)
  883. X
  884. #define off_intr() \
  885. X    (void) (turnoff(glob_flags, WAS_INTR), signal(SIGINT, oldint), \
  886. X        signal(SIGQUIT, oldquit))
  887. X
  888. /* Don't flush input when setting echo or cbreak modes (allow typeahead) */
  889. #ifdef TIOCSETN
  890. #ifdef stty
  891. #undef stty
  892. #endif /* stty */
  893. #define stty(fd, sgttybuf)    ioctl(fd, TIOCSETN, sgttybuf)
  894. #endif /* TIOCSETN */
  895. X
  896. /* for system-V machines that run termio */
  897. #if defined(SYSV) && defined(USG)
  898. #ifdef crmode
  899. #undef crmode
  900. #undef nocrmode
  901. #endif /* nocrmode */
  902. X
  903. unsigned char vmin, vtime;
  904. #define sg_erase  c_cc[2]
  905. #define sg_flags  c_lflag
  906. #define sg_kill   c_cc[3]
  907. #define sg_ospeed c_cflag
  908. #define gtty(fd, SGTTYbuf)    ioctl(fd, TCGETA, SGTTYbuf)
  909. #undef stty
  910. #define stty(fd, SGTTYbuf)    ioctl(fd, TCSETAW, SGTTYbuf)
  911. #define echon()    (_tty.sg_flags |= (ECHO|ECHOE),    stty(0, &_tty))
  912. #define echoff()   (_tty.sg_flags &= ~ECHO,   stty(0, &_tty))
  913. #define cbrkon()   \
  914. X    (_tty.sg_flags &= ~ICANON, _tty.c_cc[VMIN] = 1, stty(0, &_tty))
  915. #define cbrkoff()  \
  916. X    (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \
  917. X        _tty.c_cc[VTIME] = vtime, stty(0, &_tty))
  918. #define savetty()  \
  919. X    (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN]
  920. #define cbreak()   cbrkon()
  921. #define nocbreak() cbrkoff()
  922. X
  923. /* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */
  924. #ifndef CURSES
  925. typedef struct termio SGTTY;
  926. #define echom()    echon()
  927. #define noechom()  echoff()
  928. #define crmode()   cbrkon()
  929. #define nocrmode() cbrkoff()
  930. X
  931. #else /* CURSES */
  932. /* If curses is defined, use the echo/cbreak commands in library only
  933. X * if curses is running.  If curses isn't running, use macros above.
  934. X */
  935. #define echom()    ((iscurses) ? echo(): echon())
  936. #define noechom()  ((iscurses) ? noecho(): echoff())
  937. #define crmode()   ((iscurses) ? cbreak() : cbrkon())
  938. #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
  939. #endif /* CURSES */
  940. #endif /* SYSV && USG */
  941. X
  942. #if !defined(USG)
  943. #ifndef CURSES
  944. /* if curses is not defined, simulate the same tty based macros */
  945. typedef struct sgttyb SGTTY;
  946. /* Do real ioctl calls to set the tty modes */
  947. #define crmode()   (_tty.sg_flags |= CBREAK,  stty(0, &_tty))
  948. #define nocrmode() (_tty.sg_flags &= ~CBREAK, stty(0, &_tty))
  949. #define echom()    (_tty.sg_flags |= ECHO,    stty(0, &_tty))
  950. #define noechom()  (_tty.sg_flags &= ~ECHO,   stty(0, &_tty))
  951. #define savetty()  (void) gtty(0, &_tty)
  952. #else /* CURSES */
  953. #define echom()    echo()
  954. #define noechom()  noecho()
  955. #endif /* ~CURSES */
  956. #endif /* ~USG */
  957. X
  958. /* With all that out of the way, we can now declare our tty type */
  959. SGTTY _tty;
  960. X
  961. extern char
  962. X    del_line,        /* tty delete line character */
  963. X    del_word,        /* tty delete word character */
  964. X    del_char,        /* backspace */
  965. X    reprint_line,    /* usually ^R */
  966. X    eofc,        /* usually ^D */
  967. X    lit_next,        /* usually ^V */
  968. X    complete,        /* word completion, usually ESC */
  969. X    complist;        /* completion listing, usually tab */
  970. X
  971. /* These macros now turn on/off echo/cbreak independent of the UNIX running */
  972. #define echo_on()    \
  973. X    if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) nocrmode(), echom()
  974. #define echo_off()    \
  975. X    if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) crmode(), noechom()
  976. X
  977. #define strdup(dst, src) (xfree (dst), dst = savestr(src))
  978. #define Debug        if (debug == 0) {;} else (void) wprint
  979. X
  980. #ifdef SYSV
  981. #ifndef L_SET
  982. #define L_SET    0
  983. #endif /* L_SET */
  984. #ifndef F_OK
  985. #define F_OK    000
  986. #define R_OK    004
  987. #define W_OK    002
  988. #define E_OK    001
  989. #endif /* F_OK */
  990. #ifdef u_long
  991. #undef u_long
  992. #endif /* u_long */
  993. #define u_long    unsigned long
  994. #ifndef HPUX
  995. #define vfork   fork
  996. #endif /* HPUX */
  997. #ifndef SIGCHLD
  998. #define SIGCHLD SIGCLD
  999. #endif /* SIGCHLD */
  1000. #endif /* SYSV */
  1001. X
  1002. #if !defined(SUNTOOL) && !defined(CURSES)
  1003. X
  1004. #define TRUE          1
  1005. #define FALSE          0
  1006. #define print          (void) printf
  1007. #define wprint          (void) printf
  1008. #define print_more      (void) printf
  1009. X
  1010. #endif /* !SUNTOOL && !CURSES */
  1011. X
  1012. #ifndef max
  1013. #define max(a,b) (((a) > (b)) ? (a) : (b))
  1014. #define min(a,b) (((a) < (b)) ? (a) : (b))
  1015. #endif /* max */
  1016. X
  1017. #if defined(CURSES) && (!defined(SUNTOOL))
  1018. #define wprint    (void) printf
  1019. #endif /* CURSES && (!SUNTOOL) */
  1020. X
  1021. #ifdef SUNTOOL
  1022. /* stdout may be closed */
  1023. #define printf wprint
  1024. #else /* !SUNTOOL */
  1025. #define ok_box print
  1026. #endif /* SUNTOOL */
  1027. X
  1028. #if defined(CURSES) || defined(SUNTOOL)
  1029. #define print_more      turnon(glob_flags, CONT_PRNT), print
  1030. void print();    /* printf to window or curses or tty accordingly */
  1031. #endif /* CURSES || SUNTOOL */
  1032. X
  1033. #define ArraySize(o)      (sizeof(o) / sizeof(*o))
  1034. X
  1035. #ifdef SUNTOOL
  1036. X
  1037. #define NO_ITEM        (Panel_item)0
  1038. #define NO_EVENT    (struct inputevent *)0
  1039. #define TIME_OUT    60    /* sleep 60 secs between mailchecks */
  1040. #define PIX_XOR        PIX_SRC ^ PIX_DST
  1041. #define ID        event_id(event)
  1042. #define l_width()    mush_font->pf_defaultsize.x /* width of letter */
  1043. #define l_height()    mush_font->pf_defaultsize.y /* height of letter */
  1044. #define Clrtoeol(w,x,y)    ((void) pw_text(w, x, y, PIX_SRC, mush_font, blank))
  1045. X
  1046. /* Miscellaneous old-SunView cleanup */
  1047. #ifndef TTY_ARGV_DO_NOT_FORK
  1048. #define TTY_ARGV_DO_NOT_FORK (-1)
  1049. #endif
  1050. X
  1051. #endif /* SUNTOOL */
  1052. X
  1053. /* bits and pieces */
  1054. #define turnon(flg,val)   ((flg) |= (u_long)(val))
  1055. #define turnoff(flg,val)  ((flg) &= ~(u_long)(val))
  1056. #define ison(flg,val)     ((u_long)(flg) & (u_long)(val))
  1057. #define isoff(flg,val)    (!ison((flg), (val)))
  1058. #define set_replied(n)      \
  1059. X    if (isoff(msg[n].m_flags, REPLIED)) \
  1060. X        turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
  1061. #define set_isread(n)      \
  1062. X    if (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)) \
  1063. X        turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
  1064. X
  1065. #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
  1066. #define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO))
  1067. #define line_macro(s) (void) (turnon(glob_flags, LINE_MACRO), mac_push(s))
  1068. #define curs_macro(s) (void) (turnon(glob_flags, IN_MACRO), mac_push(s))
  1069. #define Ungetstr(s) (void) (turnon(glob_flags, QUOTE_MACRO), mac_push(s))
  1070. X
  1071. /* global conditions */
  1072. #define is_shell (mailfile && *mailfile)
  1073. X
  1074. /* msg lists represented by bits (8 should be replaced by sizeof(char) */
  1075. #define clear_msg_list(list)      ((void) bzero(list, (msg_cnt+7)/8))
  1076. #define msg_bit(list, n)    ((list[(n) / 8] >> ((n) % 8)) & 1)
  1077. #define set_msg_bit(list, n)    (list[(n) / 8] |= (1 << ((n) % 8)))
  1078. #define unset_msg_bit(list, n)  (list[(n) / 8] &= ~(1 << ((n) % 8)))
  1079. #define bput(S1, S2, Len, op)                   \
  1080. X        do {                         \
  1081. X            register char *s1 = S1, *s2 = S2;         \
  1082. X            register int len = Len;             \
  1083. X            while(len--)                 \
  1084. X            *s2++ op *s1++;             \
  1085. X        } while (0)
  1086. #define bitput(m1,m2,len,op)    bput(m1, m2, (((len)+7)/8), op)
  1087. X
  1088. /* convenience and/or readability */
  1089. #define when          break;case
  1090. #define otherwise      break;default
  1091. #define lower(c)      (isupper(c)? tolower(c): c)
  1092. #define Lower(c)      (c = lower(c))
  1093. #define upper(c)      (islower(c)? toupper(c): c)
  1094. #define Upper(c)      (c = upper(c))
  1095. #define skipspaces(n)     for(p += (n); *p == ' ' || *p == '\t'; ++p)
  1096. #define skipdigits(n)     for(p += (n); isdigit(*p); ++p)
  1097. #define ismsgnum(c)       (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
  1098. #define skipmsglist(n)\
  1099. X    for(p += (n); ismsgnum(*p) || index(" \t,-{`}", *p); ++p)\
  1100. X    if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
  1101. X
  1102. /* define a macro to declare unsigned-long bits */
  1103. #define ULBIT(bit)        ((u_long)1 << (u_long)(bit))
  1104. X
  1105. /* various flags */
  1106. u_long   glob_flags;    /* global boolean flags thruout the whole program */
  1107. #define DO_UPDATE   ULBIT(0) /* folder has been modified -- update it */
  1108. #define REV_VIDEO   ULBIT(1) /* reverse video for curses or toolmode */
  1109. #define CONT_PRNT   ULBIT(2) /* continue to print without a '\n' */
  1110. #define DO_SHELL    ULBIT(3) /* run a shell even if no mail? (true if tool) */
  1111. #define DO_PIPE     ULBIT(4) /* if commands are piping to other commands */
  1112. #define IS_PIPE     ULBIT(5) /* true if commands' "input" comes from a pipe */
  1113. #define IGN_SIGS    ULBIT(6) /* true if catch() should not longjmp */
  1114. #define IGN_BANG    ULBIT(7) /* ignore ! as a history reference */
  1115. #define ECHO_FLAG   ULBIT(8) /* if true, echo|cbreak is ON, echo typing (-e) */
  1116. #define IS_GETTING  ULBIT(9) /* true if we're getting input for a letter */
  1117. #define PRE_CURSES  ULBIT(10) /* true if curses will run, but hasn't started */
  1118. #define READ_ONLY   ULBIT(11) /* -r passed to folder() for read only */
  1119. #define REDIRECT    ULBIT(12) /* true if stdin is being redirected */
  1120. #define WAS_INTR    ULBIT(13) /* catch interrupts, set this flag (signals.c) */
  1121. #define WARNING     ULBIT(14) /* if set, various warning messages are printed */
  1122. #define NEW_MAIL    ULBIT(15) /* new mail has arrived; mush is busy or closed */
  1123. #define CNTD_CMD    ULBIT(16) /* curses.c -- promotes "...continue..." prompt */
  1124. #define IS_SENDING  ULBIT(17) /* was run to send mail, not run as a shell */
  1125. #define MIL_TIME    ULBIT(19) /* if $mil_time is set, use 24hr time fmt */
  1126. #define DATE_RECV   ULBIT(20) /* $date_received: show date received on msgs */
  1127. #define IN_MACRO    ULBIT(21) /* input is currently being read from a macro */
  1128. #define LINE_MACRO  ULBIT(22) /* escape to line mode from curses in progress */
  1129. #define QUOTE_MACRO ULBIT(23) /* protect current macro from recursive expan.. */
  1130. #define NEW_FRAME   ULBIT(24) /* toolmode should build a new frame for pager */
  1131. #define HELP_TEXT   ULBIT(25) /* create textsw frame for paging help messages */
  1132. #define CORRUPTED   ULBIT(26) /* error loading new mail has occurred */
  1133. X
  1134. /* flags to control composition */
  1135. #define VERBOSE        ULBIT(0)  /* verbose flag for sendmail */
  1136. #define INCLUDE        ULBIT(1)  /* include msg in response */
  1137. #define INCLUDE_H    ULBIT(2)  /* include msg with header */
  1138. #define EDIT        ULBIT(3)  /* enter editor by default on mailing */
  1139. #define SIGN        ULBIT(4)  /* auto-include ~/.signature in mail */
  1140. #define DO_FORTUNE    ULBIT(5)  /* add a fortune at end of msgs */
  1141. #define EDIT_HDRS    ULBIT(6)  /* user edits headers using editor */
  1142. #define SEND_NOW    ULBIT(7)  /* send without further changes */
  1143. #define NO_SIGN        ULBIT(8)  /* override SIGN and DO_FORTUNE */
  1144. X
  1145. /* msg flags */
  1146. #define PRINTED        ULBIT(4)  /* sent through lpr command */
  1147. #define NO_HEADER    ULBIT(6)  /* don't print header of message */
  1148. #define DELETE        ULBIT(7)
  1149. #define OLD        ULBIT(8)
  1150. #define UNREAD        ULBIT(9)
  1151. #define UPDATE_STATUS    ULBIT(10) /* change status of msg when copyback */
  1152. #define NO_PAGE        ULBIT(11) /* don't page this message */
  1153. #define INDENT        ULBIT(12) /* indent included msg with string */
  1154. #define NO_IGNORE    ULBIT(13) /* don't ignore headers */
  1155. #define PRESERVE    ULBIT(14) /* preserve in mailbox unless deleted */
  1156. #define M_TOP        ULBIT(15) /* just print the top of msg (same as pre) */
  1157. #define FORWARD        ULBIT(16) /* Forward messages into the message buffer */
  1158. #define REPLIED        ULBIT(17) /* Messages that have been replied to */
  1159. #define NEW_SUBJECT    ULBIT(18) /* new subject regardless of $ask (mail -s) */
  1160. #define SAVED        ULBIT(19) /* when message has been saved */
  1161. #ifdef MSG_SEPARATOR
  1162. #define NO_SEPARATOR    ULBIT(20) /* don't include message separator lines */
  1163. #endif /* MSG_SEPARATOR */
  1164. X
  1165. #define M_PRIORITY(n)    ULBIT(21+(n))
  1166. /* It is possible to reset MAX_PRIORITY to as high as 10 */
  1167. #define MAX_PRIORITY    5
  1168. X
  1169. #define    MAXMSGS_BITS    MAXMSGS/sizeof(char)    /* number of bits for bitmap */
  1170. X
  1171. struct msg {
  1172. X    u_long m_flags;
  1173. X    long   m_offset;    /* offset in tempfile of msg */
  1174. X    long   m_size;    /* number of bytes in msg */
  1175. X    int    m_lines;    /* number of lines in msg */
  1176. X    char   *m_date_recv;/* Date user received msg (see dates.c for fmt) */
  1177. X    char   *m_date_sent;/* Date author sent msg (see dates.c for fmt) */
  1178. } msg[MAXMSGS];
  1179. X
  1180. struct options {
  1181. X    char *option;
  1182. X    char *value;
  1183. X    struct options *next;
  1184. } *set_options, *aliases, *ignore_hdr, *functions, *fkeys, *own_hdrs;
  1185. X
  1186. #define chk_option(v,f)    chk_two_lists(do_set(set_options,(v)), (f), "\t ,")
  1187. X
  1188. struct cmd {
  1189. X    char *command;
  1190. X    int (*func)();
  1191. };
  1192. extern struct cmd ucb_cmds[];
  1193. extern struct cmd cmds[], hidden_cmds[];
  1194. X
  1195. struct expand {
  1196. X    char *orig;        /* string beginning with substring to be expanded */
  1197. X    char *exp;        /* result of expansion of substring */
  1198. X    char *rest;        /* rest of the original string beyond substring */
  1199. };
  1200. X
  1201. FILE
  1202. X    *tmpf,        /* temporary holding place for all mail */
  1203. X    *mask_fopen(),    /* open a file with umask 077 (permissions 600) */
  1204. X    *open_file(),    /* open a file or program for write/append */
  1205. X    *lock_fopen(),    /* open and lock a file as an atomic operation */
  1206. X    *popen();        /* this should be in stdio.h */
  1207. X
  1208. extern char
  1209. X    *sys_errlist[],    /* system's list of global error messages */
  1210. X    **environ;        /* user's environment variables */
  1211. X
  1212. extern int errno;    /* global system error number */
  1213. jmp_buf jmpbuf;        /* longjmp to jmpbuf on sigs (not in tool) */
  1214. X
  1215. char
  1216. X    debug,        /* debug causes various print statements in code */
  1217. X    tempfile[MAXPATHLEN],    /* path to filename of temporary file */
  1218. X    msg_list[MAXMSGS_BITS],    /* MAXMSGS bits of boolean storage */
  1219. X    **alternates,    /* alternates list --see alts() */
  1220. X    *cmd_help,        /* filename of location for "command -?" commands. */
  1221. X    *login,        /* login name of user */
  1222. X    *mailfile,        /* path to filename of current mailfile */
  1223. X    **ourname,        /* the name and aliases of the current host */
  1224. X    **known_hosts,    /* the names of all hosts connected via uucp */
  1225. X    *prompt,        /* the prompt string -- may have %d */
  1226. X    *format_prompt(),    /* function to format prompts from the prompt string */
  1227. X    *escape,        /* the "tilde escape" when inputting text to letter */
  1228. X    *hdrs_only,        /* true if -H flag was given --set to args */
  1229. X    *hdr_format,    /* set to the header format string; referenced a lot */
  1230. X    *spoolfile,        /* MAILDIR/$USER in a string -- this is used a lot */
  1231. X    *msg_get(),        /* find start of message and return From_ line */
  1232. X    *do_range(),    /* parse a string converting to a "range" of numbers */
  1233. X    *getpath(),        /* static char returning path (expanding ~, +, %, #) */
  1234. X    *getdir(),        /* uses getpath() to expand and test directory names */
  1235. X    *do_set(),        /* set/unset an option, alias, ignored-hdr */
  1236. X    *reverse(),        /* reverse a string */
  1237. X    *trim_filename(),    /* remove or condense leading file name path */
  1238. X    *prog_name,
  1239. X
  1240. X    /* from loop.c */
  1241. X    **make_command(),    /* build a command vector (argv) */
  1242. X    **mk_argv(),    /* given a string, make a vector */
  1243. X    *variable_stuff(),    /* return information about variables */
  1244. X    *check_internal(),    /* test or evaluate internal variables */
  1245. X
  1246. X    /* from dates.c */
  1247. X    *Time(),        /* returns string expression of time (takes args) */
  1248. X    *date_to_ctime(),    /* convert a date into ctime() format */
  1249. X    *date_to_string(),    /* returns a string described by parse_date() */
  1250. X    *msg_date(),    /* return a string of the date of a message */
  1251. X    *parse_date(),    /* parse an ascii date, and return message-id str */
  1252. X    *rfc_date(),    /* create a date string compliant to RFC822 */
  1253. X
  1254. X    /* from hdrs.c */
  1255. X    *cc_to(),         /* when responding, return str which is the cc-list */
  1256. X    *compose_hdr(),    /* passes hdr_format to format_hdr() for displays */
  1257. X    *format_hdr(),    /* returns a formatted line describing passed msg # */
  1258. X    *header_field(),    /* the line in msg described by arg (message header) */
  1259. X    *reply_to(),    /* who do we reply to when responding */
  1260. X    *subject_to(),      /* when responding, return str which is the subject */
  1261. X
  1262. X    /* addrs.c */
  1263. X    *alias_to_address(),/* convert a name[list] to "real" names */
  1264. X    *bang_form(),    /* construct a !-style form of an address */
  1265. X    *get_name_n_addr(), /* get name and addr from a well-formed address */
  1266. X    *set_header(),     /* [interactive] proc to set/display to/subject/cc */
  1267. X    *wrap_addrs();    /* insert newlines in between headers */
  1268. X
  1269. int
  1270. X    last_msg_cnt,    /* when checking for new mail, save the last msg_cnt */
  1271. X    msg_cnt,        /* total number of messages */
  1272. X    crt,        /* min number of lines msg contains to invoke pager */
  1273. X    current_msg,    /* the current message we're dealing with */
  1274. X    exec_pid,        /* pid of a command that has been "exec"ed */
  1275. X    hist_no,        /* command's history number */
  1276. X    iscurses,        /* if we're running curses */
  1277. #if defined(SUNTOOL) || defined(lint)
  1278. X    istool,        /* argv[0] == "xxxxtool", ranges from 0 to 2 */
  1279. #else /* !SUNTOOL */
  1280. #define istool 0
  1281. #endif /* SUNTOOL */
  1282. X    n_array[128],    /* array of message numbers in the header window */
  1283. X    screen,        /* number of headers window can handle */
  1284. X    wrapcolumn,        /* compose mode line wrap, measured from left */
  1285. X
  1286. X    close_lock(),     /* unlock and close a file opened by lock_fopen() */
  1287. X
  1288. X    mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
  1289. X    folder(), folders(), merge_folders(), do_undigest(), mark_msg(),
  1290. X    save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
  1291. X    save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
  1292. X    do_pick(), print_help(), question_mark(), do_from(), my_stty(),
  1293. X    do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(),
  1294. X    await(), nopenfiles(), file_to_fp(),
  1295. X    check_new_mail(), get_new_mail(), show_new_mail(),
  1296. X    Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug();
  1297. X
  1298. #ifndef SIGRET
  1299. #define SIGRET int
  1300. #endif /* SIGRET */
  1301. SIGRET
  1302. X    rm_edfile(),    /* remove letter-compose file on interrupts */
  1303. X    stop_start(),    /* handle job control signals */
  1304. X    bus_n_seg(),    /* handle runtime segfaults -- exit gracefully */
  1305. X    sigchldcatcher(),    /* account for terminated child processes */
  1306. X    catch(),        /* catch user (keyboard) generated signals */
  1307. X    intrpt();        /* handle interrupts when we don't want to */
  1308. X
  1309. long
  1310. X    spool_size,        /* size of spool mail regardless of current folder */
  1311. X    last_size,        /* the last size of the mailfile since last check */
  1312. X    time();        /* satisfy lint */
  1313. X
  1314. void
  1315. X    error(), getmail(), mail_status(), sign_letter(),
  1316. X    init(), display_msg(), cleanup(), fs_error();
  1317. X    /* printf(), fclose(), fflush(), fputs(), fputc() */
  1318. #ifdef TIOCGLTC
  1319. struct ltchars ltchars;            /* tty character settings */
  1320. #endif /* TIOCGLTC */
  1321. #ifdef BSD /* (TIOCGETC) */
  1322. struct tchars  tchars;            /* more tty character settings */
  1323. #endif /* BSD (TIOCGETC) */
  1324. X
  1325. #ifdef CURSES
  1326. X
  1327. #define STANDOUT(y,x,s) standout(), mvaddstr(y,x,s), standend()
  1328. #define redraw()    clearok(curscr, TRUE), wrefresh(curscr)
  1329. X
  1330. int
  1331. X    curses_init();    /* interpret commands via the curses interface */
  1332. #endif /* CURSES */
  1333. X
  1334. int
  1335. X    mac_push(),        /* set up a string as a macro */
  1336. X    bind_it();        /* bind strings to functions or macros */
  1337. X
  1338. void
  1339. X    mac_flush();    /* Abandon macro processing (on error) */
  1340. X
  1341. #ifdef SUNTOOL
  1342. void
  1343. X    timeout_cursors(), do_file_dir(), toggle_mail_items(), ok_box(),
  1344. X    read_mail(), opts_panel_item(), view_options(), toolquit(), wprint(),
  1345. X    update_list_textsw(), check_icons();
  1346. X
  1347. char
  1348. X    *find_key(),    /* pass x,y coords to find which function key assoc. */
  1349. X    *panel_get(),          /* returns what has been typed in a panel item */
  1350. X    *tool_help,        /* help for tool-related things (sometimes, overlap) */
  1351. X    *more_prompt,    /* when NULL, we're paging a msg; else pager prompt */
  1352. X    blank[128];        /* use to clear to end of line */
  1353. X
  1354. int
  1355. X    time_out,        /* time out interval to wait for new mail */
  1356. X    is_iconic;        /* set if the mushview window is iconic. */
  1357. X
  1358. Notify_value
  1359. X    do_check(),        /* check for new mail on timeout */
  1360. X    destroy_proc(),    /* Destroy procedure. */
  1361. X    my_wait3(),        /* Handle wait for child exit */
  1362. X    scroll_textwin(),    /* Do fancy TEXTSW scrolling */
  1363. X    edit_msg_textwin();    /* Auto-positioning in compose TEXTSW */
  1364. X
  1365. Frame tool;        /* Main frame. */
  1366. Frame compose_frame;    /* Compose frame. */
  1367. Textsw pager_textsw;    /* for "paging" messages and other lists.. */
  1368. Textsw mfprint_sw;    /* Textsw in main mush frame for wprint() */
  1369. Canvas hdr_sw;         /* Canvas for message headers */
  1370. Tty tty_sw;         /* subwindow which forks a shell (usually editor) */
  1371. X
  1372. Pixwin
  1373. X    *hdr_win;        /* pixwin for message headers */
  1374. X
  1375. struct pixfont *mush_font;    /* array of fonts */
  1376. X
  1377. struct itimerval mail_timer;    /* frequency to check for new mail */
  1378. X
  1379. extern Cursor l_cursor, m_cursor, r_cursor;
  1380. extern Icon mail_icon;
  1381. X
  1382. /* When trapping events that represent scrolling actions */
  1383. typedef enum {
  1384. X    MUSH_SCROLL_TO,
  1385. X    MUSH_SCROLL_RELATIVE,
  1386. X    MUSH_SCROLL_IGNORE,
  1387. X    MUSH_SCROLL_PASS_EVENT
  1388. } Scroll_action;
  1389. #endif /* SUNTOOL */
  1390. SHAR_EOF
  1391. chmod 0644 mush.h ||
  1392. echo 'restore of mush.h failed'
  1393. Wc_c="`wc -c < 'mush.h'`"
  1394. test 23670 -eq "$Wc_c" ||
  1395.     echo 'mush.h: original size 23670, current size' "$Wc_c"
  1396. rm -f _shar_wnt_.tmp
  1397. fi
  1398. # ============= options.c ==============
  1399. if test -f 'options.c' -a X"$1" != X"-c"; then
  1400.     echo 'x - skipping options.c (File already exists)'
  1401.     rm -f _shar_wnt_.tmp
  1402. else
  1403. > _shar_wnt_.tmp
  1404. echo 'x - extracting options.c (Text)'
  1405. sed 's/^X//' << 'SHAR_EOF' > 'options.c' &&
  1406. /* @(#)options.c    (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */
  1407. X
  1408. #include "mush.h"
  1409. #include "options.h"
  1410. X
  1411. /*
  1412. X * NOTE:  Any word flag which is a prefix of another word flag must be
  1413. X *  listed AFTER the flag it prefixes in the list below
  1414. X */
  1415. X
  1416. char *word_flags[][2] = {
  1417. X    { "-bcc",        "-b" },
  1418. X    { "-blindcarbon",    "-b" },
  1419. X    { "-blind",        "-b" },
  1420. X    { "-carbon",    "-c" },
  1421. X    { "-cc",        "-c" },
  1422. X    { "-copy",        "-c" },
  1423. X    { "-curses",    "-C" },
  1424. X    { "-debug",        "-d" },
  1425. X    { "-draft",        "-h" },
  1426. X    { "-echo",        "-e" },
  1427. X    { "-folder",    "-f" },    /* Maybe -file should become -f too? */
  1428. X    { "-file",        "-F" },    /* Don't really like -file for -F */
  1429. X    { "-headerfile",    "-h" },
  1430. X    { "-headers",    "-H" },
  1431. X    { "-initialize",    "-I" },
  1432. X    { "-init",        "-I" },
  1433. X    { "-interactive",    "-i" },
  1434. X    { "-interact",    "-i" },
  1435. X    { "-mailbox",    "-m" },
  1436. X    { "-message",    "-h" },
  1437. X    { "-noheaders",    "-N" },
  1438. X    { "-noinit",    "-n" },
  1439. X    { "-readonly",    "-r" },
  1440. X    { "-send",        "-U" },
  1441. X    { "-shell",        "-S" },
  1442. X    { "-source",    "-F" },    /* This is better for -F */
  1443. X    { "-subject",    "-s" },
  1444. X    { "-timeout",    "-T" },
  1445. X    { "-toolhelp",    "-2" },
  1446. X    { "-tool",        "-t" },
  1447. X    { "-user",        "-u" },
  1448. X    { "-verbose",    "-v" },
  1449. X    { "-visual",    "-C" },
  1450. X    { NULL,        NULL }    /* This must be the last entry */
  1451. };
  1452. X
  1453. fix_word_flag(argp)
  1454. register char **argp;
  1455. SHAR_EOF
  1456. true || echo 'restore of options.c failed'
  1457. fi
  1458. echo 'End of  part 18'
  1459. echo 'File options.c is continued in part 19'
  1460. echo 19 > _shar_seq_.tmp
  1461. exit 0
  1462. exit 0 # Just in case...
  1463. -- 
  1464. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1465. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1466. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1467. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1468.