home *** CD-ROM | disk | FTP | other *** search
- From: argv@zipcode.com (Dan Heller)
- Newsgroups: comp.sources.misc
- Subject: v18i075: mush - Mail User's Shell, Part18/22
- Message-ID: <1991Apr22.153612.29725@sparky.IMD.Sterling.COM>
- Date: 22 Apr 91 15:36:12 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: dab05017 add96bdd 69b50751 c0cb38da
-
- Submitted-by: Dan Heller <argv@zipcode.com>
- Posting-number: Volume 18, Issue 75
- Archive-name: mush/part18
- Supersedes: mush: Volume 12, Issue 28-47
-
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file mush.1 continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 18; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping mush.1'
- else
- echo 'x - continuing file mush.1'
- sed 's/^X//' << 'SHAR_EOF' >> 'mush.1' &&
- or are strings that are automatically generated by pressing a special
- key on the terminal.
- On the other hand, the timeout can be used intentionally to prevent a
- macro from being expanded; simply type the first character of the macro,
- then wait for it to echo before typing the next.
- This does not work in curses mode, because curses macros
- never \*Qtime out.\*U
- .PP
- In any mode, macros are
- .IR recursive ;
- that is, if the
- .I "key sequence"
- of one macro appears in the
- .I expansion
- of another macro (or even of the same macro), the second key sequence
- is recognized when the first macro is expanded, and this new key
- sequence is also expanded.
- Great care should be taken when creating macros to be certain that
- recursive expansions do not happen unintentionally.
- Expansion can be prevented in line or composition modes by using a
- .I literal-next
- character.
- .PP
- Literal-next characters may be used from the keyboard or embedded
- in expansions.
- In either case, they prevent the next character
- from being interpreted as part of a key sequence.
- .I Mush
- recognizes the literal-next character from the tty settings of the
- terminal, if the \*Qnew\*U BSD-style device driver is available;
- otherwise, `^V' (control-V) is recognized as a literal-next.
- Note that, if you have a tty literal-next character,
- then when typing you need to type
- .I two
- of them in order to send one to \fIMush\fR; this is because the tty
- driver consumes the first one.
- It is not necessary to use two literal-nexts in macro expansions
- unless you wish to cause the second literal-next to be literal.
- .PP
- Backslash can be used as a literal-next when typing, and can
- sometimes be used as a literal-next in expansions; but use it
- with caution, because it also introduces escape sequences
- (see \*QMacro syntax,\*U below).
- There is no literal-next mechanism for curses mode.
- .PP
- A macro always aborts whenever
- .I any
- command called by the macro returns an error.
- This includes recursive expansions, so no matter how often a macro has
- recurred, it is terminated completely.
- Errors in curses mode include illegal cursor movements, such as up from
- the top of the screen or down from the last message.
- .PP
- .BR "Macro syntax" .
- .PP
- A special syntax is provided for specifying control characters and other
- non-printing characters in macro key sequences and expansions.
- This syntax is the same as that for bindings, discussed in the
- CURSES INTERFACE section; it can be summarized as:
- .ta 1.25i
- .in +2
- .nf
- \\CX control-X (where X is any capital letter)
- \\E the escape character
- \\n a newline (other C-style escapes also work)
- .fi
- .in -2
- .sp
- Thus, to create a line mode macro for control-X control-W, as in the
- example above, the command is
- .sp
- .ti +4
- map '\\CX\\CW' save
- .PP
- Also provided is a syntax for executing functions from within macros.
- There are two special functions that are effective in all modes;
- these are
- .I getstr
- and
- .IR getline .
- Both of these functions interrupt expansion of the current macro,
- and wait for a newline-terminated string to be entered from the
- standard input.
- This input string is inserted into the macro expansion.
- The functions differ in that
- .B getline
- retains the newline character (carriage-return) at the end of the
- input string, whereas
- .B getstr
- strips off the newline (one must still be typed to terminate input).
- These functions can be executed by surrounding their name with
- square brackets
- .RB ( [ ,
- .BR ] );
- for example,
- .sp
- .ti +4
- map '\\CX\\CW' save [getline]
- .sp
- creates a line mode macro, which is expanded when control-X control-W is
- typed, and which displays \*Qsave\*U followed by a space and then waits
- for the user to type a line of input; the input line is used as the
- arguments to the save command.
- .PP
- Additional functions are currently available only in the curses mode.
- However, the syntax of enclosing the function name in square brackets
- applies to all functions, regardless of mode.
- Note that
- .I ONLY
- the function name can appear in the brackets; no whitespace is allowed.
- .PP
- .BR "Curses mode macros" .
- .PP
- Macros in curses mode are the most versatile, because they can access the
- full range of curses commands quickly and easily.
- Every character that appears in the expansion part of a curses mode macro
- can reference a curses command or another macro.
- Like other curses functions, curses mode macros are created with the
- .B bind
- command.
- For example, to sort your messages by date and then send the most recent
- one to the printer, you could use
- .sp
- .ti +4
- bind @ macro 'od$|'
- .sp
- When the `@' key is typed, this macro first invokes sort
- (`o' from the default bindings) and instructs it to use date (d)
- for sorting; it then moves the current-message pointer to the last
- message ($) and prints that message (|).
- .PP
- Admittedly, the above macro is somewhat cryptic, and is dependent upon
- the bindings for sort, last-msg, and lpr being set to the defaults.
- It is better, and possibly more understandable, to refer to the
- desired curses functions without using their key bindings.
- To allow this, the \*Q[function]\*U syntax described above may be used
- in curses mode macros to reference curses functions.
- The only function that is prohibited from appearing in the \*Q[\|]\*U
- is the special
- .I macro
- function, which cannot be called when it has no binding.
- The example macro can therefore be rewritten as
- .sp
- .ti +4
- bind @ macro [sort]d[last-msg][lpr]
- .sp
- Such references to curses functions may be made only in curses mode
- macros, and are effective only when \fIMush\fR is actually in curses mode.
- That may sound strange, but the most common use of curses macros is
- to quickly perform functions that require an escape to the line mode.
- For example, although there is a variation of the curses mode
- .I mail
- function that prompts for additional flags, there is no function
- to prompt for flags to be passed to
- .IR reply .
- A macro can easily be created to provide this:
- .sp
- .ti +4
- bind R macro '[line-mode]reply '
- .sp
- This macro binds `R' to perform an escape to line mode and type
- the string \*Qreply\*U followed by a space.
- Macro expansion then ends, leaving it up to the user to supply
- flags to the command or to backspace over it if a different command
- (or none) is desired.
- Of course, the macro could also have provided some default arguments:
- .sp
- .ti +4
- bind R macro '[line-mode]reply \-ei '
- .PP
- Note that, if the
- .B getline
- or
- .B getstr
- function is used in a line-mode escape, it is not possible to
- erase the text that is typed before the
- .IR get ;
- that is, if the macro is
- .sp
- .ti +4
- bind R macro '[line-mode]reply \-ei [getline]'
- .sp
- then the user is forced to use the \-ei flags.
- .PP
- .BR "Line mode macros" .
- .PP
- Line mode macros combine some of the convenience of single-keystroke
- commands with the versatility of the line-oriented text interface.
- As has been noted, the choice of characters for line mode key sequences
- should be made carefully, so as not to interfere with normal typing.
- Line mode macros are created with the
- .B map
- command; for example, suppose you frequently forward messages to a
- friend named \*Qfred.\*U You could create a macro to do this:
- .sp
- .ti +4
- map '\\CF' 'mail \-f . fred\\n'
- .sp
- This macro causes the single keystroke `^F' (control-F) to forward
- the current message to \*Qfred.\*U Note the newline
- character \*Q\\n\*U at the end of the expansion;
- this causes the command to be executed immediately,
- without you having to type a carriage-return.
- .PP
- The expansion part of a line mode macro echoes to the screen when
- it is expanded, so you can see what the macro is doing.
- You can therefore use parts of the expansion as a \*Qprompt.\*U In
- the above example, suppose you wished to enter a message list rather
- than always forwarding the current message.
- Change the macro to:
- .sp
- .ti +4
- map '\\CF' 'mail \-f [getstr] fred\\n'
- .sp
- This version of the macro prints \*Qmail \-f\*U and a space, then waits
- for a newline-terminated string from the standard input.
- The newline is stripped, and the string is used as the message list
- passed to the \*Qmail \-f\*U command.
- The address \*Qfred\*U is also passed to
- .BR mail ,
- so the messages in the list are forwarded to fred.
- .PP
- If you want to be able to \*Qchange your mind\*U after starting a
- line mode macro, you must leave the \*Q\\n\*U out of the expansion.
- Without the newline, the macro is not executed immediately, so
- you have a chance erase the line (or part of it) and type
- something different.
- Remember that the
- .B getline
- function keeps the newline in the string it gets, so if you don't
- want a newline to appear, you must use
- .BR getstr .
- When using the
- .I get
- functions, you should also remember that you can
- .I never
- backspace past the \*Qbeginning\*U of a
- .BR getline ,
- and you can backspace past the beginning of a
- .B getstr
- only after the get has been completed.
- .PP
- When the
- .B getstr
- function is used in line mode macros,
- .I Mush
- reprints the current input line so you can see what the whole
- thing looks like, but does not redisplay the line mode prompt
- (see the entry for
- .B prompt
- in the VARIABLES section for information on what the
- prompt looks like).
- Don't let this worry you.
- The input line is also reprinted when
- .B getline
- is used, but the newline in the input string usually results in a
- new prompt being displayed.
- .PP
- .IR NOTE :
- Line mode macros are not available when using the line-mode escape
- function in curses mode.
- It is necessary to escape all the way to line mode (that is, leave
- curses mode by typing carriage-return at the `:' prompt) in order
- to access line mode macros.
- This is to prevent possible confusion when similar macros exist
- in both line and curses modes.
- .PP
- .BR "Composition mode macros" .
- .PP
- Composition mode macros are very similar to line mode macros, and
- provide a \*Qpower typing\*U function when composing messages.
- For example, you might want to have the word \*Qpercent\*U inserted
- into your message whenever you hit the `%' key:
- .sp
- .ti +4
- map! % percent
- .sp
- Another use is to simulate the indentation features of editors.
- For example, you might
- .sp
- .ti +4
- map! '\\CT' '\ \ \ \ '
- .sp
- (where the expansion is four spaces, enclosed in single quotes).
- This macro causes four spaces to be inserted into the message whenever
- control-T is typed.
- .PP
- Composition mode macros can also be used to execute
- .I tilde-escapes
- (see the GENERAL USAGE section for a list of these).
- For example, you could create a macro to invoke the editor:
- .sp
- .ti +4
- map! '\\CE' '\\n~v\\n'
- .sp
- When control-E is typed, this macro prints a newline (to be sure that
- the tilde-escape is the first thing on a line), then types \*Q~v\*U
- followed by another newline, to start the editor.
- Similar macros can be created for other tilde-escapes.
- .PP
- .BR "Mixed mode macros" .
- .PP
- It is not normally possible to mix macros among the different modes.
- However, once expansion has begun, it is interrupted only by an error
- or by the appearance of one of the special
- .I get
- functions.
- It is therefore possible to have a macro expansion which causes
- the mode to change before the expansion has completed.
- In this case, recursive expansions apply to the new mode.
- Suppose we are using a variation of the editor-starting macro shown
- above for composition mode:
- .sp
- .ti +4
- map! '\\CE' '\\n~v emacs\\n'
- .sp
- This macro causes the \*Qemacs\*U editor to be started when control-E
- is typed in composition mode.
- We can now create a line mode macro that makes use of this
- composition mode macro:
- .sp
- .ti +4
- map '#' 'reply \-i [getline]~t[getline]\\CE'
- .sp
- When the `#' key is pressed in line mode, this macro
- prints \*Qreply \-i\*U and waits for a message list, then enters
- composition mode (by executing the
- .B reply
- command).
- In composition mode, it displays the To: line
- (the \*Q~t\*U escape) and waits for other addresses to be added.
- Finally, it recursively expands the control-E macro, to
- start editing the message with emacs.
- .PP
- As can be seen from this example, the
- .I Mush
- macro facility is very powerful.
- Be very careful not to accidentally expand recursive macros,
- especially when using macros that change modes.
- When testing new macros, it is a good idea to start
- .I Mush
- in
- .I read-only
- mode (the \-r command line flag) to be sure that messages are
- not lost or altered.
- .PP
- .BR "Getting rid of macros" .
- .PP
- It is not necessary to delete a macro in order to redefine it.
- New expansions for existing key sequences automatically replace
- the old expansions.
- If it is necessary to remove a macro completely, the commands
- .BR unbind ,
- .B unmap
- and
- .B unmap!
- can be used to remove curses mode, line mode, and composition mode
- macros, respectively.
- Remember to use a backslash or other literal-next character to prevent
- the expansion of line mode macros when using these commands, especially
- .BR unmap .
- .SH "MAIL ADDRESSES"
- Whenever a command that requires a user address or set of addresses
- is specified
- .RB ( mail ,
- .BR reply ,
- .BR alias ,
- .BR etc )
- the addresses given must be separated by commas.
- Most casual users specify addresses that contain no comments or whitespace.
- The simplest addresses are just the login names of the users you wish to send
- your message to:
- .sp
- .ti +2
- \fBmail\fR fred barney wilma betty
- .sp
- In these cases,
- .I Mush
- can figure out that they are separate addresses and
- insert commas between addresses automatically.
- .sp
- .ti +2
- To: fred, barney, wilma, betty
- .sp
- Addresses may also contain `!', `@' and `%' characters which are used
- to separate hostnames and the final user name from each other.
- This is primarily used to mail to users on other machines.
- UUCP addresses are specified as
- .sp
- .ti +2
- host1!host2!user
- .sp
- where there may be as many hosts as necessary to route the message
- to the recipient user.
- Here, the user's account is on \*Qhost2\*U
- and that machine is connected to \*Qhost1\*U.
- .I Domain
- addresses (also called Arpanet, Internet, RFC822, and \*Qfully qualified\*U
- addresses) are specified as
- .sp
- .ti +2
- user@host.domain
- .ti +2
- user%host2.domain@host1
- .sp
- where \*Qdomain\*U is a domain name such as \*Q.berkeley.edu\*U or \*Q.com\*U.
- As in the first example, the user is on \*Qhost2\*U, but that machine talks
- to \*Qhost1\*U.
- It is beyond the scope of this document to discuss in detail the ramifications
- of inter-network mailing.
- More information can be obtained through your system manager.
- .PP
- .I Mush
- understands addresses containing a comment field.
- Comment fields do not affect the destination address of mail being sent.
- These fields are purely for
- human legibility and may be specified according to the following constraints:
- .sp
- Anything within angle brackets is an address; whatever is outside of the
- address is considered a comment:
- .sp
- .ti +2
- Dan Heller <zipcode!argv@cad.berkeley.edu>
- .ti +2
- Dan Heller <argv@zipcode.com>
- .sp
- Anything that has parentheses is a comment; whatever is outside of the
- parentheses is considered the address:
- .sp
- .ti +2
- zipcode!argv (Dan Heller)
- .ti +2
- argv@zipcode.com (Dan Heller)
- .sp
- Double quotes (") are treated just like parentheses:
- .sp
- .ti +2
- "Dan Heller" zipcode!argv
- .ti +2
- "Dan Heller" argv@zipcode.com
- .sp
- If the comment is to contain a comma, the first case above may not be used;
- you must use either the parenthesis or double-quote cases.
- .sp
- .ti +2
- fred@flintstone.bed.rock (Fred Flintstone, Cave Man)
- .sp
- If the comment contains unbalanced quotes, unpredictable results may occur
- .RI ( Mush
- won't deliver the mail).
- .sp
- Since the angle brackets have the highest precedence, quotes or parentheses
- may be used in conjunction with one another.
- .sp
- .ti +2
- Yabba Dabba Doo (Fred Flintstone) <fred>
- .ti +2
- Scoobie "Doobie" Doo <scooby@shaggys.mystery.machine>
- .PP
- Multiple addresses may appear on a line:
- .sp
- .in +2
- argv@zipcode.com argv@garp.mit.edu dheller
- .in -2
- .sp
- Because there is no indication of comments (parenthesis, angle bracket,
- or quotes), it is assumed that these are separate addresses and
- .I Mush
- inserts commas between these addresses accordingly.
- It is for this reason that the user is encouraged to explicitly insert
- commas between all mail addresses and not depend on the automation of comma
- insertion to correctly separate addresses from one another.
- .PP
- Mail aliases may contain addresses of the form described above.
- .sp
- .nf
- .in +2
- .ta 1.5i
- alias george George Jetson <george@spacely.space.sprockets>
- alias jane Jane Jetson <jane@sky-high.appts>
- alias group george, jane
- .in -2
- .fi
- .sp
- You can mail using the alias as an address and it is expanded
- accordingly.
- You cannot, however, reference an alias and specify a
- comment or another address at the same time.
- .sp
- .ti +2
- To: The Jetsons <group>
- .sp
- The comment \*QThe Jetsons\*U is not retained when the alias \*Qgroup\*U
- is expanded, because the entire address and comment are replaced by the
- expansion.
- .SH FILES
- .nf
- .ta 2.0i
- /usr/spool/mail/* Directory for incoming mail
- ~/Mail Default \fBfolder\fR directory
- ~/mbox File where old mail is saved
- ~/.mushrc File giving initial \fIMush\fR commands
- ~/.mailrc Alternate initialization file
- ~/.edXXXXXXX Temporary for file for outgoing messages
- ~/.mushXXXXXX Temporary mail file (copy of current folder)
- .fi
- .PP
- Temporary files that are created by the program are always
- created with read/write access to the owner only; group and other
- permissions are never set.
- This is also true for the /usr/spool/mail/* files.
- All other files created by the user via commands internal or external
- to the program have permissions set by the user's default umask.
- If the umask is reset within the program, the mask remains
- intact even after exiting.
- Remember to set the variable
- .B unix
- before attempting to set the umask value.
- .PP
- If your system is using Sun Microsystem's NFS, take special note to
- read the manual page for mount(1).
- Filesystems mounted for read/write
- access should be mounted as \*Qhard\*U NFS mounts or you may lose
- mailboxes during a timeout during a write or update.
- .PP
- Filesystems that use RFS still have bugs to be ironed out in the way
- of owners and permissions concerning utime(2).
- .SH "SEE ALSO"
- .IR Mail (1),
- .IR binmail (1),
- .IR csh (1),
- .IR aliases (5),
- .IR mount (1),
- .IR mailaddr (7),
- .IR sendmail (8),
- .IR printf (3),
- .IR execl (3),
- .IR umask (1),
- .IR utime (2).
- .SH AUTHOR
- The original
- .I Mush
- was written entirely by Dan Heller.
- Code to support macros, line wrapping, and a whole lot of other miscellaneous
- details, was written by Bart Schaefer, who gets his name in print
- because he updated and proofread this manual.
- Numerous others have supplied valuable suggestions
- and assorted bits and pieces.
- .PP
- argv@sun.com zipcode!argv
- .SH DISCLAIMERS
- .I Mush
- contains no
- .IR UNIX (TM)
- sources and never has.
- It is also not a modified version of any other mail user agent.
- Similarities
- with any other mailer may have been designed for compatibility reasons.
- .PP
- .I UNIX
- is a trademark of AT&T.
- .PP
- The Flintstones and The Jetsons are trademarks of Hannah-Barbara Inc.
- .SH BUGS
- The curses interface uses the curses library.
- The routines from the library that are used are the most basic and simple
- so as to avoid possible bugginess that
- different versions of UNIX might have.
- However, one unavoidable problem is the reverse video mode.
- Depending on your terminal,
- the termcap entry for it, and the version of curses you are running,
- the reverse video may make things worse than desired.
- In such situations, the user should set the variable
- .B no_reverse
- to not get reverse video.
- \&`^R' may still be entered at runtime in the curses
- interface to toggle reverse video.
- .PP
- Toggling from the curses mode to the line mode to get the full
- functionality of the shell/line mode is unfortunately necessary
- in order to maintain the display in a sensible manner and to keep the
- keystroke-command interface simple and \*Quser friendly\*U.
- Mostly, such escapes are only necessary
- for piping of commands and using the pick command.
- Macros are a big help with this.
- .PP
- If the program is already running and the system [later] has to swap
- and there is no swap space left, there may be problems.
- One such problem is sending mail.
- If this happens, then sending mail
- fails and a segmentation fault from the spawned/forked child may occur
- (unless the -v flag was given to mail).
- The unsent letter is not removed from the editing file ($home/.edXXXXXX)
- and may be recovered.
- .PP
- Many functions available to the line oriented mode (shell mode)
- are not available to the tool mode.
- For example,
- .B pick
- may not be directly accessed although experienced users may find that
- typing pick commands within single backquotes in the \*QRange:\*U panel item
- above the header window and then selecting a command that uses the range
- does indeed pick messages.
- This is mostly for selecting the \*Qdelete range\*U item
- or the middle mouse button icon in the header panel.
- .PP
- Version 6.5.6 was the last version designed to run under SunWindows, and is
- therefore the most recent version that functioned under SunOS 2.x.
- Starting with versions 7.x, the interface used is SunView, and may have
- a completely new set of problems in addition to those described below.
- Also, some of those described below may have been eliminated, and remain
- in this discussion only for completeness.
- .PP
- Shell escapes (of any kind) may be called only from the \*Qpipe\*U command
- in the tool mode, should not be interactive, and should produce
- output only to a file.
- The reason for this is that there is no tty
- .I window
- in which to do input/output.
- Since the interactive function-key binding interface has gone away, it is
- unfortunately only possible to execute commands that have been pre-defined
- in the initialization file.
- Future revisions may correct these deficiencies.
- .PP
- The function keys and their ability to
- .I work
- has been variable depending on the version of SunWindows/SunView
- your Sun Workstation has. From time to time, it works, but when it
- doesn't, it seems to be related to other user or system definable
- dot-files or whatever.
- .PP
- Changing the value of the
- .BR screen_win ,
- .BR crt_win ,
- or
- .B msg_win
- variables after the tool is running simply has no effect.
- .PP
- When using
- .B vi
- in the tool mode, the window is periodically one or more
- lines \*Qshort.\*U
- That is, scrolling is off by one line and you have to redraw the
- window (using \*Qz.\*U in vi) to get it in sync again. The problem
- is caused by the window having less than 24 lines in the window.
- Having the tty subwindow be
- .I exactly
- 24 lines usually eliminates the problem. This is a bug with SunView
- and will not be fixed since Sun no longer supports it.
- .PP
- When running on full filesystems,
- .I Mush
- may complain or not even run since it needs temporary space with which
- to work.
- Instead of finding new filesystems on its own,
- .I Mush
- leaves this task up to the user.
- The workaround is to set the variable
- .B tmpdir
- in the initialization file to be a writable place in a filesystem that
- has enough disk space.
- Note: some systems' setcwd() system call writes temporary information in
- /tmp and this cannot be overridden. You may get error messages such as
- "file system full" even if your
- .B tmpdir
- variable is set to a directory in a partition other than that of /tmp.
- There is nothing to be concerned about; chance are that you changed
- directories and the setcwd() system call can't write to its temp file.
- .PP
- Repeated sequences of creating and destroying compose frames
- uses up file descriptors in Sun OS 3.5, due to a bug where a destroyed
- ttysw does not free up its fd's.
- .PP
- Most of the other known and documented bugs
- are in the supplied README files accompanying the source.
- The source is also an excellent place to look as many known bugs are
- documented in comments.
- A good way to track suspicious bugs is to use the
- .B debug
- command, but note that
- this command is very difficult to use in curses mode.
- SHAR_EOF
- echo 'File mush.1 is complete' &&
- chmod 0644 mush.1 ||
- echo 'restore of mush.1 failed'
- Wc_c="`wc -c < 'mush.1'`"
- test 191116 -eq "$Wc_c" ||
- echo 'mush.1: original size 191116, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= mush.h ==============
- if test -f 'mush.h' -a X"$1" != X"-c"; then
- echo 'x - skipping mush.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting mush.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'mush.h' &&
- /* @(#)mush.h (c) copyright 1986 (Dan Heller) */
- X
- #include "config.h"
- X
- #ifdef CURSES
- X
- #ifdef USG
- # define _USG
- # undef USG
- #endif /* USG */
- #ifdef SYSV
- # define _SYSV
- # undef SYSV
- #endif /* SYSV */
- #include <curses.h>
- #if !defined(USG) && defined(_USG)
- # define USG
- #endif /* USG */
- #if !defined(SYSV) && defined(_SYSV)
- # define SYSV
- #endif /* SYSV */
- X
- #else /* CURSES */
- #include <stdio.h>
- #if defined(SYSV) && defined(USG)
- #include <termio.h>
- #endif /* SYSV && USG */
- #endif /* CURSES */
- X
- #include <ctype.h>
- #include <errno.h>
- #include <setjmp.h>
- #include "strings.h"
- X
- extern char
- X *malloc(), /* allocate memory */
- X *calloc(), /* allocate and clear memory */
- X *realloc(); /* re-allocate memory */
- X
- extern void
- X free_vec(), /* free a malloc'ed argv */
- X xfree(); /* free malloc'ed pointers */
- X
- #if defined(SUNTOOL) || defined(SUN_3_5) || defined(SUN_4_0) || defined(SUN_4_1)
- #if !defined(BSD) && !defined(SYSV)
- # define BSD /* default to BSD */
- #endif /* !BSD && !SYSV */
- #if !defined(SUN_3_5) && !defined(SUN_4_0)
- # ifndef SUN_4_1
- # define SUN_4_1 /* default to sun 4.1 */
- # endif /* SUN_4_1 */
- # define SUN_4_0 /* 4.0 stuff needed too */
- #endif /* !SUN_3_5 && !SUN_4_0 */
- #ifdef SUN_4_0
- # undef SUN_3_5
- # undef SIGRET
- # define SIGRET void
- #endif /* SUN_4_0 */
- #endif /* SUNTOOL || SUN_3_5 || SUN_4_0 || SUN_4_1 */
- X
- #ifdef BSD
- #define fputs Fputs /* See comments in print.c */
- #endif /* BSD */
- X
- #if defined(BSD) || defined(GETWD)
- extern char *getwd();
- #define GetCwd(buf,len) getwd(buf)
- #else
- extern char *getcwd();
- #define GetCwd(buf,len) getcwd(buf,len)
- #endif /* BSD || GETWD */
- X
- #ifdef SUNTOOL
- # include <suntool/sunview.h>
- #ifdef SUN_4_0
- # include <suntool/alert.h>
- #endif /* SUN_4_0 */
- # include <suntool/textsw.h>
- # include <sys/ioctl.h> /* for ltchars */
- #else
- # include <sys/types.h>
- # include <signal.h>
- # ifndef SYSV
- # include <sys/time.h>
- # include <sys/ioctl.h> /* for ltchars */
- # else
- # include <time.h>
- # include <fcntl.h>
- # endif /* SYSV */
- #endif /* SUNTOOL */
- X
- #include <sys/stat.h>
- #include <sys/file.h>
- X
- #ifdef SUNTOOL
- # include <suntool/panel.h>
- # include <suntool/canvas.h>
- # include <suntool/tty.h>
- # include <suntool/menu.h>
- # include <suntool/icon.h>
- # include <suntool/scrollbar.h>
- # include <suntool/icon_load.h>
- #endif /* SUNTOOL */
- X
- /* if no maximum number of files can be found, we'll use getdtablesize() */
- #ifdef _NFILE
- # define MAXFILES _NFILE
- #else
- #ifdef NOFILE
- # define MAXFILES NOFILE
- #endif /* NOFILE */
- #endif /* _NFILE */
- X
- #ifndef MAXPATHLEN
- #define MAXPATHLEN BUFSIZ
- #endif /* MAXPATHLEN */
- X
- #ifdef CTRL
- #undef CTRL
- #endif /* CTRL */
- #define CTRL(c) ((c) & 037)
- X
- #define ESC '\033'
- X
- #define NO_STRING ""
- #ifdef NULL
- #undef NULL
- #endif /* NULL */
- #define NULL (char *)0
- #define NULL_FILE (FILE *)0
- #define DUBL_NULL (char **)0
- #define TRPL_NULL (char ***)0
- #ifdef putchar
- #undef putchar
- #endif /* putchar */
- #define putchar(c) (void) (fputc(c, stdout), fflush(stdout))
- #ifdef SUNTOOL
- extern int bell();
- #else /* SUNTOOL */
- #define bell() (void) (fputc('\007', stderr), fflush(stderr))
- #endif /* SUNTOOL */
- X
- /* For error recovery purposes, send keyboard generated signals to a special
- X * routine (interrupt) to set a global flag (WAS_INTR) and return to the
- X * calling routine which is responsible for checking the flag. For both
- X * on_intr() and off_intr() macros, initialize WAS_INTR to false.
- X */
- #define on_intr() \
- X turnoff(glob_flags, WAS_INTR), oldint = signal(SIGINT, intrpt), \
- X oldquit = signal(SIGQUIT, intrpt)
- X
- #define off_intr() \
- X (void) (turnoff(glob_flags, WAS_INTR), signal(SIGINT, oldint), \
- X signal(SIGQUIT, oldquit))
- X
- /* Don't flush input when setting echo or cbreak modes (allow typeahead) */
- #ifdef TIOCSETN
- #ifdef stty
- #undef stty
- #endif /* stty */
- #define stty(fd, sgttybuf) ioctl(fd, TIOCSETN, sgttybuf)
- #endif /* TIOCSETN */
- X
- /* for system-V machines that run termio */
- #if defined(SYSV) && defined(USG)
- #ifdef crmode
- #undef crmode
- #undef nocrmode
- #endif /* nocrmode */
- X
- unsigned char vmin, vtime;
- #define sg_erase c_cc[2]
- #define sg_flags c_lflag
- #define sg_kill c_cc[3]
- #define sg_ospeed c_cflag
- #define gtty(fd, SGTTYbuf) ioctl(fd, TCGETA, SGTTYbuf)
- #undef stty
- #define stty(fd, SGTTYbuf) ioctl(fd, TCSETAW, SGTTYbuf)
- #define echon() (_tty.sg_flags |= (ECHO|ECHOE), stty(0, &_tty))
- #define echoff() (_tty.sg_flags &= ~ECHO, stty(0, &_tty))
- #define cbrkon() \
- X (_tty.sg_flags &= ~ICANON, _tty.c_cc[VMIN] = 1, stty(0, &_tty))
- #define cbrkoff() \
- X (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \
- X _tty.c_cc[VTIME] = vtime, stty(0, &_tty))
- #define savetty() \
- X (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN]
- #define cbreak() cbrkon()
- #define nocbreak() cbrkoff()
- X
- /* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */
- #ifndef CURSES
- typedef struct termio SGTTY;
- #define echom() echon()
- #define noechom() echoff()
- #define crmode() cbrkon()
- #define nocrmode() cbrkoff()
- X
- #else /* CURSES */
- /* If curses is defined, use the echo/cbreak commands in library only
- X * if curses is running. If curses isn't running, use macros above.
- X */
- #define echom() ((iscurses) ? echo(): echon())
- #define noechom() ((iscurses) ? noecho(): echoff())
- #define crmode() ((iscurses) ? cbreak() : cbrkon())
- #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
- #endif /* CURSES */
- #endif /* SYSV && USG */
- X
- #if !defined(USG)
- #ifndef CURSES
- /* if curses is not defined, simulate the same tty based macros */
- typedef struct sgttyb SGTTY;
- /* Do real ioctl calls to set the tty modes */
- #define crmode() (_tty.sg_flags |= CBREAK, stty(0, &_tty))
- #define nocrmode() (_tty.sg_flags &= ~CBREAK, stty(0, &_tty))
- #define echom() (_tty.sg_flags |= ECHO, stty(0, &_tty))
- #define noechom() (_tty.sg_flags &= ~ECHO, stty(0, &_tty))
- #define savetty() (void) gtty(0, &_tty)
- #else /* CURSES */
- #define echom() echo()
- #define noechom() noecho()
- #endif /* ~CURSES */
- #endif /* ~USG */
- X
- /* With all that out of the way, we can now declare our tty type */
- SGTTY _tty;
- X
- extern char
- X del_line, /* tty delete line character */
- X del_word, /* tty delete word character */
- X del_char, /* backspace */
- X reprint_line, /* usually ^R */
- X eofc, /* usually ^D */
- X lit_next, /* usually ^V */
- X complete, /* word completion, usually ESC */
- X complist; /* completion listing, usually tab */
- X
- /* These macros now turn on/off echo/cbreak independent of the UNIX running */
- #define echo_on() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) nocrmode(), echom()
- #define echo_off() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) crmode(), noechom()
- X
- #define strdup(dst, src) (xfree (dst), dst = savestr(src))
- #define Debug if (debug == 0) {;} else (void) wprint
- X
- #ifdef SYSV
- #ifndef L_SET
- #define L_SET 0
- #endif /* L_SET */
- #ifndef F_OK
- #define F_OK 000
- #define R_OK 004
- #define W_OK 002
- #define E_OK 001
- #endif /* F_OK */
- #ifdef u_long
- #undef u_long
- #endif /* u_long */
- #define u_long unsigned long
- #ifndef HPUX
- #define vfork fork
- #endif /* HPUX */
- #ifndef SIGCHLD
- #define SIGCHLD SIGCLD
- #endif /* SIGCHLD */
- #endif /* SYSV */
- X
- #if !defined(SUNTOOL) && !defined(CURSES)
- X
- #define TRUE 1
- #define FALSE 0
- #define print (void) printf
- #define wprint (void) printf
- #define print_more (void) printf
- X
- #endif /* !SUNTOOL && !CURSES */
- X
- #ifndef max
- #define max(a,b) (((a) > (b)) ? (a) : (b))
- #define min(a,b) (((a) < (b)) ? (a) : (b))
- #endif /* max */
- X
- #if defined(CURSES) && (!defined(SUNTOOL))
- #define wprint (void) printf
- #endif /* CURSES && (!SUNTOOL) */
- X
- #ifdef SUNTOOL
- /* stdout may be closed */
- #define printf wprint
- #else /* !SUNTOOL */
- #define ok_box print
- #endif /* SUNTOOL */
- X
- #if defined(CURSES) || defined(SUNTOOL)
- #define print_more turnon(glob_flags, CONT_PRNT), print
- void print(); /* printf to window or curses or tty accordingly */
- #endif /* CURSES || SUNTOOL */
- X
- #define ArraySize(o) (sizeof(o) / sizeof(*o))
- X
- #ifdef SUNTOOL
- X
- #define NO_ITEM (Panel_item)0
- #define NO_EVENT (struct inputevent *)0
- #define TIME_OUT 60 /* sleep 60 secs between mailchecks */
- #define PIX_XOR PIX_SRC ^ PIX_DST
- #define ID event_id(event)
- #define l_width() mush_font->pf_defaultsize.x /* width of letter */
- #define l_height() mush_font->pf_defaultsize.y /* height of letter */
- #define Clrtoeol(w,x,y) ((void) pw_text(w, x, y, PIX_SRC, mush_font, blank))
- X
- /* Miscellaneous old-SunView cleanup */
- #ifndef TTY_ARGV_DO_NOT_FORK
- #define TTY_ARGV_DO_NOT_FORK (-1)
- #endif
- X
- #endif /* SUNTOOL */
- X
- /* bits and pieces */
- #define turnon(flg,val) ((flg) |= (u_long)(val))
- #define turnoff(flg,val) ((flg) &= ~(u_long)(val))
- #define ison(flg,val) ((u_long)(flg) & (u_long)(val))
- #define isoff(flg,val) (!ison((flg), (val)))
- #define set_replied(n) \
- X if (isoff(msg[n].m_flags, REPLIED)) \
- X turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
- #define set_isread(n) \
- X if (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)) \
- X turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
- X
- #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
- #define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO))
- #define line_macro(s) (void) (turnon(glob_flags, LINE_MACRO), mac_push(s))
- #define curs_macro(s) (void) (turnon(glob_flags, IN_MACRO), mac_push(s))
- #define Ungetstr(s) (void) (turnon(glob_flags, QUOTE_MACRO), mac_push(s))
- X
- /* global conditions */
- #define is_shell (mailfile && *mailfile)
- X
- /* msg lists represented by bits (8 should be replaced by sizeof(char) */
- #define clear_msg_list(list) ((void) bzero(list, (msg_cnt+7)/8))
- #define msg_bit(list, n) ((list[(n) / 8] >> ((n) % 8)) & 1)
- #define set_msg_bit(list, n) (list[(n) / 8] |= (1 << ((n) % 8)))
- #define unset_msg_bit(list, n) (list[(n) / 8] &= ~(1 << ((n) % 8)))
- #define bput(S1, S2, Len, op) \
- X do { \
- X register char *s1 = S1, *s2 = S2; \
- X register int len = Len; \
- X while(len--) \
- X *s2++ op *s1++; \
- X } while (0)
- #define bitput(m1,m2,len,op) bput(m1, m2, (((len)+7)/8), op)
- X
- /* convenience and/or readability */
- #define when break;case
- #define otherwise break;default
- #define lower(c) (isupper(c)? tolower(c): c)
- #define Lower(c) (c = lower(c))
- #define upper(c) (islower(c)? toupper(c): c)
- #define Upper(c) (c = upper(c))
- #define skipspaces(n) for(p += (n); *p == ' ' || *p == '\t'; ++p)
- #define skipdigits(n) for(p += (n); isdigit(*p); ++p)
- #define ismsgnum(c) (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
- #define skipmsglist(n)\
- X for(p += (n); ismsgnum(*p) || index(" \t,-{`}", *p); ++p)\
- X if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
- X
- /* define a macro to declare unsigned-long bits */
- #define ULBIT(bit) ((u_long)1 << (u_long)(bit))
- X
- /* various flags */
- u_long glob_flags; /* global boolean flags thruout the whole program */
- #define DO_UPDATE ULBIT(0) /* folder has been modified -- update it */
- #define REV_VIDEO ULBIT(1) /* reverse video for curses or toolmode */
- #define CONT_PRNT ULBIT(2) /* continue to print without a '\n' */
- #define DO_SHELL ULBIT(3) /* run a shell even if no mail? (true if tool) */
- #define DO_PIPE ULBIT(4) /* if commands are piping to other commands */
- #define IS_PIPE ULBIT(5) /* true if commands' "input" comes from a pipe */
- #define IGN_SIGS ULBIT(6) /* true if catch() should not longjmp */
- #define IGN_BANG ULBIT(7) /* ignore ! as a history reference */
- #define ECHO_FLAG ULBIT(8) /* if true, echo|cbreak is ON, echo typing (-e) */
- #define IS_GETTING ULBIT(9) /* true if we're getting input for a letter */
- #define PRE_CURSES ULBIT(10) /* true if curses will run, but hasn't started */
- #define READ_ONLY ULBIT(11) /* -r passed to folder() for read only */
- #define REDIRECT ULBIT(12) /* true if stdin is being redirected */
- #define WAS_INTR ULBIT(13) /* catch interrupts, set this flag (signals.c) */
- #define WARNING ULBIT(14) /* if set, various warning messages are printed */
- #define NEW_MAIL ULBIT(15) /* new mail has arrived; mush is busy or closed */
- #define CNTD_CMD ULBIT(16) /* curses.c -- promotes "...continue..." prompt */
- #define IS_SENDING ULBIT(17) /* was run to send mail, not run as a shell */
- #define MIL_TIME ULBIT(19) /* if $mil_time is set, use 24hr time fmt */
- #define DATE_RECV ULBIT(20) /* $date_received: show date received on msgs */
- #define IN_MACRO ULBIT(21) /* input is currently being read from a macro */
- #define LINE_MACRO ULBIT(22) /* escape to line mode from curses in progress */
- #define QUOTE_MACRO ULBIT(23) /* protect current macro from recursive expan.. */
- #define NEW_FRAME ULBIT(24) /* toolmode should build a new frame for pager */
- #define HELP_TEXT ULBIT(25) /* create textsw frame for paging help messages */
- #define CORRUPTED ULBIT(26) /* error loading new mail has occurred */
- X
- /* flags to control composition */
- #define VERBOSE ULBIT(0) /* verbose flag for sendmail */
- #define INCLUDE ULBIT(1) /* include msg in response */
- #define INCLUDE_H ULBIT(2) /* include msg with header */
- #define EDIT ULBIT(3) /* enter editor by default on mailing */
- #define SIGN ULBIT(4) /* auto-include ~/.signature in mail */
- #define DO_FORTUNE ULBIT(5) /* add a fortune at end of msgs */
- #define EDIT_HDRS ULBIT(6) /* user edits headers using editor */
- #define SEND_NOW ULBIT(7) /* send without further changes */
- #define NO_SIGN ULBIT(8) /* override SIGN and DO_FORTUNE */
- X
- /* msg flags */
- #define PRINTED ULBIT(4) /* sent through lpr command */
- #define NO_HEADER ULBIT(6) /* don't print header of message */
- #define DELETE ULBIT(7)
- #define OLD ULBIT(8)
- #define UNREAD ULBIT(9)
- #define UPDATE_STATUS ULBIT(10) /* change status of msg when copyback */
- #define NO_PAGE ULBIT(11) /* don't page this message */
- #define INDENT ULBIT(12) /* indent included msg with string */
- #define NO_IGNORE ULBIT(13) /* don't ignore headers */
- #define PRESERVE ULBIT(14) /* preserve in mailbox unless deleted */
- #define M_TOP ULBIT(15) /* just print the top of msg (same as pre) */
- #define FORWARD ULBIT(16) /* Forward messages into the message buffer */
- #define REPLIED ULBIT(17) /* Messages that have been replied to */
- #define NEW_SUBJECT ULBIT(18) /* new subject regardless of $ask (mail -s) */
- #define SAVED ULBIT(19) /* when message has been saved */
- #ifdef MSG_SEPARATOR
- #define NO_SEPARATOR ULBIT(20) /* don't include message separator lines */
- #endif /* MSG_SEPARATOR */
- X
- #define M_PRIORITY(n) ULBIT(21+(n))
- /* It is possible to reset MAX_PRIORITY to as high as 10 */
- #define MAX_PRIORITY 5
- X
- #define MAXMSGS_BITS MAXMSGS/sizeof(char) /* number of bits for bitmap */
- X
- struct msg {
- X u_long m_flags;
- X long m_offset; /* offset in tempfile of msg */
- X long m_size; /* number of bytes in msg */
- X int m_lines; /* number of lines in msg */
- X char *m_date_recv;/* Date user received msg (see dates.c for fmt) */
- X char *m_date_sent;/* Date author sent msg (see dates.c for fmt) */
- } msg[MAXMSGS];
- X
- struct options {
- X char *option;
- X char *value;
- X struct options *next;
- } *set_options, *aliases, *ignore_hdr, *functions, *fkeys, *own_hdrs;
- X
- #define chk_option(v,f) chk_two_lists(do_set(set_options,(v)), (f), "\t ,")
- X
- struct cmd {
- X char *command;
- X int (*func)();
- };
- extern struct cmd ucb_cmds[];
- extern struct cmd cmds[], hidden_cmds[];
- X
- struct expand {
- X char *orig; /* string beginning with substring to be expanded */
- X char *exp; /* result of expansion of substring */
- X char *rest; /* rest of the original string beyond substring */
- };
- X
- FILE
- X *tmpf, /* temporary holding place for all mail */
- X *mask_fopen(), /* open a file with umask 077 (permissions 600) */
- X *open_file(), /* open a file or program for write/append */
- X *lock_fopen(), /* open and lock a file as an atomic operation */
- X *popen(); /* this should be in stdio.h */
- X
- extern char
- X *sys_errlist[], /* system's list of global error messages */
- X **environ; /* user's environment variables */
- X
- extern int errno; /* global system error number */
- jmp_buf jmpbuf; /* longjmp to jmpbuf on sigs (not in tool) */
- X
- char
- X debug, /* debug causes various print statements in code */
- X tempfile[MAXPATHLEN], /* path to filename of temporary file */
- X msg_list[MAXMSGS_BITS], /* MAXMSGS bits of boolean storage */
- X **alternates, /* alternates list --see alts() */
- X *cmd_help, /* filename of location for "command -?" commands. */
- X *login, /* login name of user */
- X *mailfile, /* path to filename of current mailfile */
- X **ourname, /* the name and aliases of the current host */
- X **known_hosts, /* the names of all hosts connected via uucp */
- X *prompt, /* the prompt string -- may have %d */
- X *format_prompt(), /* function to format prompts from the prompt string */
- X *escape, /* the "tilde escape" when inputting text to letter */
- X *hdrs_only, /* true if -H flag was given --set to args */
- X *hdr_format, /* set to the header format string; referenced a lot */
- X *spoolfile, /* MAILDIR/$USER in a string -- this is used a lot */
- X *msg_get(), /* find start of message and return From_ line */
- X *do_range(), /* parse a string converting to a "range" of numbers */
- X *getpath(), /* static char returning path (expanding ~, +, %, #) */
- X *getdir(), /* uses getpath() to expand and test directory names */
- X *do_set(), /* set/unset an option, alias, ignored-hdr */
- X *reverse(), /* reverse a string */
- X *trim_filename(), /* remove or condense leading file name path */
- X *prog_name,
- X
- X /* from loop.c */
- X **make_command(), /* build a command vector (argv) */
- X **mk_argv(), /* given a string, make a vector */
- X *variable_stuff(), /* return information about variables */
- X *check_internal(), /* test or evaluate internal variables */
- X
- X /* from dates.c */
- X *Time(), /* returns string expression of time (takes args) */
- X *date_to_ctime(), /* convert a date into ctime() format */
- X *date_to_string(), /* returns a string described by parse_date() */
- X *msg_date(), /* return a string of the date of a message */
- X *parse_date(), /* parse an ascii date, and return message-id str */
- X *rfc_date(), /* create a date string compliant to RFC822 */
- X
- X /* from hdrs.c */
- X *cc_to(), /* when responding, return str which is the cc-list */
- X *compose_hdr(), /* passes hdr_format to format_hdr() for displays */
- X *format_hdr(), /* returns a formatted line describing passed msg # */
- X *header_field(), /* the line in msg described by arg (message header) */
- X *reply_to(), /* who do we reply to when responding */
- X *subject_to(), /* when responding, return str which is the subject */
- X
- X /* addrs.c */
- X *alias_to_address(),/* convert a name[list] to "real" names */
- X *bang_form(), /* construct a !-style form of an address */
- X *get_name_n_addr(), /* get name and addr from a well-formed address */
- X *set_header(), /* [interactive] proc to set/display to/subject/cc */
- X *wrap_addrs(); /* insert newlines in between headers */
- X
- int
- X last_msg_cnt, /* when checking for new mail, save the last msg_cnt */
- X msg_cnt, /* total number of messages */
- X crt, /* min number of lines msg contains to invoke pager */
- X current_msg, /* the current message we're dealing with */
- X exec_pid, /* pid of a command that has been "exec"ed */
- X hist_no, /* command's history number */
- X iscurses, /* if we're running curses */
- #if defined(SUNTOOL) || defined(lint)
- X istool, /* argv[0] == "xxxxtool", ranges from 0 to 2 */
- #else /* !SUNTOOL */
- #define istool 0
- #endif /* SUNTOOL */
- X n_array[128], /* array of message numbers in the header window */
- X screen, /* number of headers window can handle */
- X wrapcolumn, /* compose mode line wrap, measured from left */
- X
- X close_lock(), /* unlock and close a file opened by lock_fopen() */
- X
- X mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
- X folder(), folders(), merge_folders(), do_undigest(), mark_msg(),
- X save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
- X save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
- X do_pick(), print_help(), question_mark(), do_from(), my_stty(),
- X do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(),
- X await(), nopenfiles(), file_to_fp(),
- X check_new_mail(), get_new_mail(), show_new_mail(),
- X Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug();
- X
- #ifndef SIGRET
- #define SIGRET int
- #endif /* SIGRET */
- SIGRET
- X rm_edfile(), /* remove letter-compose file on interrupts */
- X stop_start(), /* handle job control signals */
- X bus_n_seg(), /* handle runtime segfaults -- exit gracefully */
- X sigchldcatcher(), /* account for terminated child processes */
- X catch(), /* catch user (keyboard) generated signals */
- X intrpt(); /* handle interrupts when we don't want to */
- X
- long
- X spool_size, /* size of spool mail regardless of current folder */
- X last_size, /* the last size of the mailfile since last check */
- X time(); /* satisfy lint */
- X
- void
- X error(), getmail(), mail_status(), sign_letter(),
- X init(), display_msg(), cleanup(), fs_error();
- X /* printf(), fclose(), fflush(), fputs(), fputc() */
- #ifdef TIOCGLTC
- struct ltchars ltchars; /* tty character settings */
- #endif /* TIOCGLTC */
- #ifdef BSD /* (TIOCGETC) */
- struct tchars tchars; /* more tty character settings */
- #endif /* BSD (TIOCGETC) */
- X
- #ifdef CURSES
- X
- #define STANDOUT(y,x,s) standout(), mvaddstr(y,x,s), standend()
- #define redraw() clearok(curscr, TRUE), wrefresh(curscr)
- X
- int
- X curses_init(); /* interpret commands via the curses interface */
- #endif /* CURSES */
- X
- int
- X mac_push(), /* set up a string as a macro */
- X bind_it(); /* bind strings to functions or macros */
- X
- void
- X mac_flush(); /* Abandon macro processing (on error) */
- X
- #ifdef SUNTOOL
- void
- X timeout_cursors(), do_file_dir(), toggle_mail_items(), ok_box(),
- X read_mail(), opts_panel_item(), view_options(), toolquit(), wprint(),
- X update_list_textsw(), check_icons();
- X
- char
- X *find_key(), /* pass x,y coords to find which function key assoc. */
- X *panel_get(), /* returns what has been typed in a panel item */
- X *tool_help, /* help for tool-related things (sometimes, overlap) */
- X *more_prompt, /* when NULL, we're paging a msg; else pager prompt */
- X blank[128]; /* use to clear to end of line */
- X
- int
- X time_out, /* time out interval to wait for new mail */
- X is_iconic; /* set if the mushview window is iconic. */
- X
- Notify_value
- X do_check(), /* check for new mail on timeout */
- X destroy_proc(), /* Destroy procedure. */
- X my_wait3(), /* Handle wait for child exit */
- X scroll_textwin(), /* Do fancy TEXTSW scrolling */
- X edit_msg_textwin(); /* Auto-positioning in compose TEXTSW */
- X
- Frame tool; /* Main frame. */
- Frame compose_frame; /* Compose frame. */
- Textsw pager_textsw; /* for "paging" messages and other lists.. */
- Textsw mfprint_sw; /* Textsw in main mush frame for wprint() */
- Canvas hdr_sw; /* Canvas for message headers */
- Tty tty_sw; /* subwindow which forks a shell (usually editor) */
- X
- Pixwin
- X *hdr_win; /* pixwin for message headers */
- X
- struct pixfont *mush_font; /* array of fonts */
- X
- struct itimerval mail_timer; /* frequency to check for new mail */
- X
- extern Cursor l_cursor, m_cursor, r_cursor;
- extern Icon mail_icon;
- X
- /* When trapping events that represent scrolling actions */
- typedef enum {
- X MUSH_SCROLL_TO,
- X MUSH_SCROLL_RELATIVE,
- X MUSH_SCROLL_IGNORE,
- X MUSH_SCROLL_PASS_EVENT
- } Scroll_action;
- #endif /* SUNTOOL */
- SHAR_EOF
- chmod 0644 mush.h ||
- echo 'restore of mush.h failed'
- Wc_c="`wc -c < 'mush.h'`"
- test 23670 -eq "$Wc_c" ||
- echo 'mush.h: original size 23670, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= options.c ==============
- if test -f 'options.c' -a X"$1" != X"-c"; then
- echo 'x - skipping options.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting options.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'options.c' &&
- /* @(#)options.c (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */
- X
- #include "mush.h"
- #include "options.h"
- X
- /*
- X * NOTE: Any word flag which is a prefix of another word flag must be
- X * listed AFTER the flag it prefixes in the list below
- X */
- X
- char *word_flags[][2] = {
- X { "-bcc", "-b" },
- X { "-blindcarbon", "-b" },
- X { "-blind", "-b" },
- X { "-carbon", "-c" },
- X { "-cc", "-c" },
- X { "-copy", "-c" },
- X { "-curses", "-C" },
- X { "-debug", "-d" },
- X { "-draft", "-h" },
- X { "-echo", "-e" },
- X { "-folder", "-f" }, /* Maybe -file should become -f too? */
- X { "-file", "-F" }, /* Don't really like -file for -F */
- X { "-headerfile", "-h" },
- X { "-headers", "-H" },
- X { "-initialize", "-I" },
- X { "-init", "-I" },
- X { "-interactive", "-i" },
- X { "-interact", "-i" },
- X { "-mailbox", "-m" },
- X { "-message", "-h" },
- X { "-noheaders", "-N" },
- X { "-noinit", "-n" },
- X { "-readonly", "-r" },
- X { "-send", "-U" },
- X { "-shell", "-S" },
- X { "-source", "-F" }, /* This is better for -F */
- X { "-subject", "-s" },
- X { "-timeout", "-T" },
- X { "-toolhelp", "-2" },
- X { "-tool", "-t" },
- X { "-user", "-u" },
- X { "-verbose", "-v" },
- X { "-visual", "-C" },
- X { NULL, NULL } /* This must be the last entry */
- };
- X
- fix_word_flag(argp)
- register char **argp;
- SHAR_EOF
- true || echo 'restore of options.c failed'
- fi
- echo 'End of part 18'
- echo 'File options.c is continued in part 19'
- echo 19 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-