s-nail (1) - Linux Manuals
s-nail: send and receive Internet mail
NAME
S-nail [v14.9.23] - send and receive Internet mail
SYNOPSIS
s-nail [-DdEFinv~# ] [-: spec ] [-A account ] [: -a attachment : ] [: -b bcc-addr : ] [: -C field: body : ] [: -c cc-addr : ] [-M type | -m file | -q file | -t ] [-r from-addr ] [: -S var [= value : ] ] [-s subject ] [: -T field: addr : ] [: -X cmd : ] [: -Y cmd : ] [-. ] : to-addr : [--~ : mta-option : ]
s-nail
[-DdEeHiNnRv~#
]
[-: spec
]
[-A account
]
[: -C field: body :
]
[-L spec
]
[-r from-addr
]
[: -S var [= value : ]
]
[-u user
]
[: -X cmd :
]
[: -Y cmd :
]
[--~ : mta-option :
]
s-nail
[-DdEeHiNnRv~#
]
[-: spec
]
[-A account
]
[: -C field: body :
]
-f
[-L spec
]
[-r from-addr
]
[: -S var [= value : ]
]
[: -X cmd :
]
[: -Y cmd :
]
[file
]
[--~ : mta-option :
]
s-nail
-h | --help
s-nail
-V | --version
DESCRIPTION
Note: S-nail (S-nail) will see major changes in v15.0 (circa 2022). Some backward incompatibilities cannot be avoided. Sx COMMANDS change to Sx Shell-style argument quoting , and shell metacharacters will become (more) meaningful. Some commands accept new syntax today via wysh ( Sx Command modifiers ) Behaviour is flagged [v15-compat] and [no v15-compat], set ting v15-compat ( Sx INTERNAL VARIABLES will choose new behaviour when applicable; giving it a value makes wysh an implied default. [Obsolete] flags what will vanish.Warning! v15-compat (with value) will be a default in v14.10.0!
S-nail provides a simple and friendly environment for sending and receiving mail. It is intended to provide the functionality of the POSIX mailx(1) command, but is MIME capable and optionally offers extensions for line editing, S/MIME, SMTP and POP3, among others. S-nail divides incoming mail into its constituent messages and allows the user to deal with them in any order. It offers many Sx COMMANDS and Sx INTERNAL VARIABLES for manipulating messages and sending mail. It provides the user simple editing capabilities to ease the composition of outgoing messages, and increasingly powerful and reliable non-interactive scripting capabilities.
Options
- -: spec , --resource-files =..
- Controls loading of (as via source Sx Resource files : spec is parsed case-insensitively, the letter `s' corresponds to the system wide s-nail.rc `u' the user's personal file ~/.mailrc The (original) system wide resource is also compiled-in, accessible via `x' The letters `-' and `/' disable usage of resource files. Order matters, default is `su' This option overrides -n
- -A name , --account =..
- Activate user account name after program startup is complete (resource files loaded, only -X commands are to be executed), and switch to its Sx primary system mailbox (most likely the inbox ) If activation fails the program e xit s if used non-interactively, or if any of errexit or posix are set.
- -a file [=input-charset [#output-charset ] ]
-
Fl Fl attach Ns =.. (Send mode) Attach file For (Compose mode) opportunities refer to ~@ and ~^ file is subject to tilde expansion (see Sx Filename transformations and folder ) if it is not accessible but contains a `=' character, anything before the last `=' will be used as the filename, anything thereafter as a character set specification, as shown. If only an input character set is specified, the input side is fixed, and no character set conversion will be applied; an empty or the special string hyphen-minus `-' is taken for ttycharset (the default). If an output character set has also been specified the desired conversion is performed immediately, not considering file type and content, except for an empty string or hyphen-minus `-' , which select the default conversion algorithm (see Sx Character sets ) : no immediate conversion is performed, file and its contents will be MIME-classified ( Sx HTML mail and MIME attachments , The mime.types files) first --- only the latter mode is available unless features includes `,+iconv,'
- -B
- ([Obsolete]: S-nail will always use line-buffered output, to gain line-buffered input even in batch mode enable batch mode via -# .
- -b addr , --bcc =..
- (Send mode) Send a blind carbon copy to recipient addr The option may be used multiple times. Also see the section Sx On sending mail, and non-interactive mode .
- -C field: body , --custom-header =..
- Create a custom header which persists for an entire session. A custom header consists of the field name followed by a colon `:' and the field content body, for example `-C' Blah: Neminem laede; imo omnes, quantum potes, juva . Standard header field names cannot be overwritten by custom headers. Runtime adjustable custom headers are available via the variable customhdr and in (Compose mode) ~^ one of the Sx COMMAND ESCAPES , as well as digmsg are the most flexible and powerful options to manage message headers. This option may be used multiple times.
- -c addr , --cc =..
- (Send mode) Just like -b except it places the argument in the list of carbon copies.
- -D , --disconnected
- [Option] Startup with disconnected set
- -d , --debug
- Enter a debug-only sandbox mode by setting the internal variable debug the same can be achieved via `-S ' Va debug or `set ' Va debug . Also see -v
- -E , --discard-empty-messages
- (Send mode) set skipemptybody and thus discard messages with an empty message part body, successfully.
- -e , --check-and-exit
- Just check if mail is present (in the system inbox or the one specified via -f ) if yes, return an exit status of zero, a non-zero value otherwise. To restrict the set of mails to consider in this evaluation a message specification can be added with the option -L Quickrun: does not open an interactive session.
- -F
- (Send mode) Save the message to send in a file named after the local part of the first recipient's address (instead of in record ).
- -f , --file
- Read in the contents of the user's Sx secondary mailbox MBOX (or the specified file) for processing; when S-nail is quit, it writes undeleted messages back to this file (but be aware of the hold option). The optional file argument will undergo some special Sx Filename transformations (as via folder ) Note that file is not an argument to the flag -f but is instead taken from the command line after option processing has been completed. In order to use a file that starts with a hyphen-minus, prefix with a relative path, as in `./-hyphenbox.mbox'
- -H , --header-summary
- Display a summary of headers for the given folder (depending on -u inbox or MAIL or as specified via -f ) then exit. A configurable summary view is available via the option -L This mode does not honour showlast Quickrun: does not open an interactive session.
- -h , --help
- Show a brief usage summary; use --long-help for a list long options.
- -i
- set ignore to ignore tty interrupt signals.
- -L spec , --search =..
- Display a summary of headers of all messages that match the given spec in the folder found by the same algorithm used by -H then exit. See the section Sx Specifying messages for the format of spec This mode does not honour showlast
If the -e option has been given in addition no header summary is produced, but S-nail will instead indicate via its exit status whether spec matched any messages ( `0' or not ( `1' ); note that any verbose output is suppressed in this mode and must instead be enabled explicitly (see -v ) Quickrun: does not open an interactive session.
- -M type
- (Send mode) Will flag standard input with the MIME `Content-Type:' set to the given known type ( Sx HTML mail and MIME attachments , The mime.types files and use it as the main message body. [v15 behaviour may differ] Using this option will bypass processing of message-inject-head and message-inject-tail Also see -q , m , t
- -m file
- (Send mode) MIME classify the specified file and use it as the main message body. [v15 behaviour may differ] Using this option will bypass processing of message-inject-head and message-inject-tail Also see -q , M , t
- -N , --no-header-summary
- inhibit the initial display of message headers when reading mail or editing a mailbox folder by calling unset for the internal variable header
- -n
- Standard flag that inhibits reading the system wide s-nail.rc upon startup. The option -: allows more control over the startup sequence; also see Sx Resource files .
- -q file , --quote-file =..
- (Send mode) Initialize the message body with the contents of file which may be standard input `-' only in non-interactive context. Also see -M , m , t
- -R , --read-only
- Any mailbox folder aka folder opened will be in read-only mode.
- -r from-addr , --from-address =..
- The RFC 5321 reverse-path used for relaying and delegating messages to its destination(s), for example to report delivery errors, is normally derived from the address which appears in the from header (or, if that contains multiple addresses, in sender ) A file-based aka local executable mta (Mail-Transfer-Agent), however, instead uses the local identity of the initiating user.
When this command line option is used the given single addressee from-addr will be assigned to the internal variable from but in addition the command line option -f from-addr will be passed to a file-based mta whenever a message is sent. Shall from-addr include a user name the address components will be separated and the name part will be passed to a file-based mta individually via -F name Even though not a recipient the `shquote' expandaddr flag is supported.
If an empty string is passed as from-addr then the content of the variable from (or, if that contains multiple addresses, sender will be evaluated and used for this purpose whenever the file-based mta is contacted. By default, without -r that is, neither -f nor -F command line options are used when contacting a file-based MTA, unless this automatic deduction is enforced by set ting the internal variable r-option-implicit
Remarks: many default installations and sites disallow overriding the local user identity like this unless either the MTA has been configured accordingly or the user is member of a group with special privileges. Passing an invalid address will cause an error.
- -S var [= value , --set =.. ]
- set (or, with a prefix string `no' , as documented in Sx INTERNAL VARIABLES , unset var iable and optionally assign value if supported; [v15 behaviour may differ] the entire expression is evaluated as if specified within dollar-single-quotes (see Sx Shell-style argument quoting ) if the internal variable v15-compat is set. If the operation fails the program will exit if any of errexit or posix are set. Settings established via -S cannot be changed from within Sx Resource files or an account switch initiated by -A They will become mutable again before commands registered via -X are executed.
- -s subject , --subject =..
- (Send mode) Specify the subject of the message to be sent. Newline (NL) and carriage-return (CR) bytes are invalid and will be normalized to space (SP) characters.
- -T field: addr , --target =..
- (Send mode) Add addr to the list of receivers targeted by field for now supported are only `bcc' , `cc' , `fcc' , and `to' Field and body (address) are separated by a colon `:' and optionally blank (space, tabulator) characters. The `shquote' expandaddr flag is supported. addr is parsed like a message header address line, as if it would be part of a template message fed in via -t and the same modifier suffix is supported. This option may be used multiple times.
- -t , --template
- (Send mode) The text message given (on standard input) is expected to contain, separated from the message body by an empty line, one or multiple plain text message headers. [v15 behaviour may differ] Readily prepared MIME mail messages cannot be passed. Headers can span multiple consecutive lines if follow lines start with any amount of whitespace. A line starting with the number sign `#' in the first column is ignored. Message recipients can be given via the message headers `To:' , `Cc:' , `Bcc:' (the `?single' modifier enforces treatment as a single addressee, for example `To?single:' exa, <m@ple> ) or `Fcc:' , they will be added to any recipients specified on the command line, and are likewise subject to expandaddr validity checks. If a message subject is specified via `Subject:' then it will be used in favour of one given on the command line.
More optional headers are `Reply-To:' (possibly overriding reply-to ) `Sender:' ( sender `From:' ( from and / or option -r ) `Message-ID:' , `In-Reply-To:' , `References:' and `Mail-Followup-To:' , by default created automatically dependent on message context, will be used if specified (a special address massage will however still occur for the latter). Any other custom header field (also see -C customhdr and ~^ is passed through entirely unchanged, and in conjunction with the options -~ or -# it is possible to embed Sx COMMAND ESCAPES . Also see -M , m , q
- -u user , --inbox-of =..
- Initially read the Sx primary system mailbox of user appropriate privileges presumed; effectively identical to `-f ' Ns %user .
- -V , --version
- Show S-nails version and exit. The command version will also show the list of features `$' s-nail -:/ -Xversion -Xx .
- -v , --verbose
- set s the internal variable verbose to enable logging of informational context messages. (Increases level of verbosity when used multiple times.) Also see -d
- -X cmd , --startup-cmd =..
- Add the given (or multiple for a multiline argument) cmd to a list of commands to be executed before normal operation starts. The commands will be evaluated as a unit, just as via source Correlates with -# and errexit
- -Y cmd , --cmd =..
- Add the given (or multiple for a multiline argument) cmd to a list of commands to be executed after normal operation has started. The commands will be evaluated successively in the given order, and as if given on the program's standard input --- before interactive prompting begins in interactive mode, after standard input has been consumed otherwise.
- -~ , --enable-cmd-escapes
- Enable Sx COMMAND ESCAPES in (Compose mode) even in non-interactive use cases. This can for example be used to automatically format the composed message text before sending the message:
$ ( echo 'line one. Word. Word2.';\ echo '~| /usr/bin/fmt -tuw66' ) |\ LC_ALL=C s-nail -d~:/ -Sttycharset=utf-8 bob [at] exam.ple
- -# , --batch-mode
- Enables batch mode: standard input is made line buffered, the complete set of (interactive) commands is available, processing of Sx COMMAND ESCAPES is enabled in Sx Compose mode , and diverse Sx INTERNAL VARIABLES are adjusted for batch necessities, exactly as if done via -S emptystart no errexit no header no posix quiet sendwait typescript-mode as well as MAIL MBOX and inbox (the latter three to /dev/null ) Also, the values of COLUMNS and LINES are looked up, and acted upon. The following prepares an email message in a batched dry run:
$ for name in bob alice [at] exam.ple lisa [at] exam.ple; do printf 'mail %s\n~s ubject\nText\n~.\n' "${name}" done | LC_ALL=C s-nail -#:x -Smta=test \ -X'alias bob bob [at] exam.ple'
- -. , --end-options
- This flag forces termination of option processing in order to prevent ``option injection'' (attacks). It also forcefully puts S-nail into send mode, see Sx On sending mail, and non-interactive mode .
If the setting of expandargv allows their recognition all mta-option arguments given at the end of the command line after a `--' separator will be passed through to a file-based mta (Mail-Transfer-Agent) and persist for the entire session. expandargv constraints do not apply to the content of mta-arguments Command line receiver address handling supports the `shquote' constraint of expandaddr for more please see Sx On sending mail, and non-interactive mode .
$ s-nail -#:/ -X 'addrcodec enc Hey, ho <silver@go>' -Xx
A starter
S-nail is a direct descendant of BSD Mail, itself a successor to the Research UNIX mail which ``was there from the start'' according to Sx HISTORY . It thus represents the user side of the UNIX mail system, whereas the system side (Mail-Transfer-Agent, MTA) was traditionally taken by sendmail(8) (and most MTAs provide a binary of this name for compatibility reasons). If the [Option]al SMTP mta is included in the features of S-nail then the system side is not a mandatory precondition for mail delivery.S-nail strives for compliance with the POSIX mailx(1) standard, but posix one of the Sx INTERNAL VARIABLES , or its Sx ENVIRONMENT Ns al equivalent POSIXLY_CORRECT needs to be set to adjust behaviour to be almost on par. Almost, because there is one important difference: POSIX Sx Shell-style argument quoting is ([v15 behaviour may differ] increasingly) used instead of the Sx Old-style argument quoting that the standard documents, which is believed to be a feature. The builtin as well as the (default) global s-nail.rc Sx Resource files already bend the standard imposed settings a bit.
For example, hold and keepsave are set in order to suppress the automatic moving of messages to the Sx secondary mailbox MBOX that would otherwise occur (see Sx Message states ) , and keep to not remove empty system MBOX mailbox files (or all empty such files in posix mode) to avoid mangling of file permissions when files eventually get recreated.
To enter interactive mode even if the initial mailbox is empty emptystart is set, editheaders to allow editing of headers as well as fullnames to not strip down addresses in Sx Compose mode , and quote to include the message that is being responded to when reply ing, which is indented by an indentprefix that also deviates from standard imposed settings. mime-counter-evidence is fully enabled, too. It sets followup-to-honour and reply-to-honour to comply with reply address desires.
Credentials and other settings are easily addressable by grouping them via account The file mode creation mask can be managed with umask Files and shell pipe output can be source d for eval uation, also during startup from within the Sx Resource files . Informational context can be available by set ting verbose or debug (as via -v , d )
On sending mail, and non-interactive mode
To send a message to one or more people, using a local or built-in mta (Mail-Transfer-Agent) transport to actually deliver the generated mail message, S-nail can be invoked with arguments which are the names of people to whom the mail will be sent, and the command line options -b and -c can be used to add (blind) carbon copy receivers:# Via test MTA $ echo Hello, world | s-nail -:/ -Smta=test -s test $LOGNAME # Via sendmail(1) MTA $ </dev/null s-nail -:x -s test $LOGNAME # Debug dry-run mode: $ </dev/null LC_ALL=C s-nail -d -:/ \ -Sttycharset=utf8 -Sfullnames \ -b bcc [at] exam.ple -c cc [at] exam.ple -. \ '(Lovely) Bob <bob [at] exam.ple>' eric [at] exam.ple # With SMTP (no real sending due to -d debug dry-run) $ LC_ALL=C s-nail -d -:/ -Sv15-compat -Sttycharset=utf8 \ -S mta=smtps://mylogin@exam.ple:465 -Ssmtp-auth=none \ -S from=scriptreply [at] exam.ple \ -a /etc/mail.rc --end-options \ eric [at] exam.ple < /tmp/letter.txt
Email addresses and plain user names are subject to alternates filtering, names only are first expanded through alias and mta-aliases An address in angle brackets consisting only of a valid local user `<name>' will be converted to a fully qualified address if either hostname is not set, or set to a non-empty value; if set to the empty value the conversion is left up to the mta By setting expandaddr fine-grained control of recipient address types other than user names and network addresses is possible. Recipients are classified as follows: any name that starts with a vertical bar `|' character specifies a command pipe - the command string following the `|' is executed and the message is sent to its standard input; likewise, any name that consists only of hyphen-minus `-' or starts with the character solidus `/' or the character sequence dot solidus `./' is treated as a file, regardless of the remaining content. Any other name which contains a commercial at `@' character is a network address; Any other name which starts with a plus sign `+' character is a mailbox name; Any other name which contains a solidus `/' character but no exclamation mark `!' or percent sign `%' character before is also a mailbox name; What remains is treated as a network address. This classification can be avoided by using a `Fcc:' header, see Sx Compose mode .
$ echo bla | s-nail -Sexpandaddr -s test ./mbox.mbox $ echo bla | s-nail -Sexpandaddr -s test '|cat >> ./mbox.mbox' $ echo safe | LC_ALL=C \ s-nail -:/ -Smta=test -Sv15-compat -Sttycharset=utf8 \ --set mime-force-sendout --set fullnames \ -S expandaddr=fail,-all,+addr,failinvaddr -s test \ --end-options 'Imagine John <cold [at] turk.ey>'
Before messages are sent they undergo editing in Sx Compose mode . But many settings are static and can be set more generally. The envelope sender address for example is defined by from explicitly defining an originating hostname may be desirable, especially with the built-in SMTP Mail-Transfer-Agent mta Sx Character sets for outgoing message and MIME part content are configurable via sendcharsets whereas input data is assumed to be in ttycharset Message data will be passed over the wire in a mime-encoding and MIME parts aka attachments need a mimetype usually taken out of Sx The mime.types files . Saving copies of sent messages in a record mailbox may be desirable - as for most mailbox folder targets Sx Filename transformations will be performed.
For the purpose of arranging a complete environment of settings that can be switched to with a single command or command line option there are account s Alternatively a flat configuration could be possible, making use of so-called variable chains which automatically pick `USER [at] HOST' or `HOST' context-dependent variants some variables support: for example addressing `Folder ' Ns pop3://yaa [at] exam.ple would find pop3-no-apop-yaa [at] exam.ple pop3-no-apop-exam.ple and pop3-no-apop in order. For more please see Sx On URL syntax and credential lookup and Sx INTERNAL VARIABLES .
To avoid environmental noise scripts should create a script-local environment, ideally with the command line options -: to disable configuration files in conjunction with repetitions of -S to specify variables:
$ env LC_ALL=C s-nail -:/ \ -Sv15-compat \ -Sttycharset=utf-8 -Smime-force-sendout \ -Sexpandaddr=fail,-all,failinvaddr \ -S mta=smtps://mylogin@exam.ple:465 -Ssmtp-auth=login \ -S from=scriptreply [at] exam.ple \ -s 'Subject to go' -a attachment_file \ -Sfullnames -. \ 'Recipient 1 <rec1 [at] exam.ple>' rec2 [at] exam.ple \ < content_file
As shown, scripts producing messages can ``fake'' a locale environment, the above specifies the all-compatible 7-bit clean LC_ALL ``C'' but will nonetheless take and send UTF-8 in the message text by using ttycharset If character set conversion is compiled in ( features includes the term `,+iconv,' ) invalid (according to ttycharset character input data would normally cause errors; setting mime-force-sendout will instead, as a last resort, classify the input as binary data, and therefore allow message creation to be successful. (Such content can then be inspected either by installing a pipe-TYPE/SUBTYPE handler for `application/octet-stream' , or possibly automatically through mime-counter-evidence )
In interactive mode, introduced soon, messages can be sent by calling the mail command with a list of recipient addresses:
$ s-nail -:/ -Squiet -Semptystart -Sfullnames -Smta=test "/var/spool/mail/user": 0 messages ? mail "Recipient 1 <rec1 [at] exam.ple>", rec2 [at] exam.ple ... ? # Will do the right thing (tm) ? m rec1 [at] exam.ple rec2 [at] exam.ple
Compose mode
If standard input is a terminal rather than the message to be sent, the user is expected to type in the message contents. In compose mode lines beginning with the character `~' (in fact the value of escape are special - these are so-called Sx COMMAND ESCAPES which can be used to read in files, process shell commands, add and edit attachments and more. For example ~v or ~e will start the VISUAL text EDITOR respectively, to revise the message in its current state, ~h allows editing of the most important message headers, with the potent ~^ custom headers can be created, for example (more specifically than with -C and customhdr ) [Option]ally ~? gives an overview of most other available command escapes.To create file-carbon-copies the special recipient header `Fcc:' may be used as often as desired, for example via ~^ Its entire value (or body in standard terms) is interpreted as a folder target, after having been subject to Sx Filename transformations : this is the only way to create a file-carbon-copy without introducing an ambiguity regarding the interpretation of the address, file names with leading vertical bars or commercial ats can be used. Like all other recipients `Fcc:' is subject to the checks of expandaddr Any local file and pipe command addressee honours the setting of mbox-fcc-and-pcc
Once finished with editing the command escape ~. (see there) will call hooks, insert automatic injections and receivers, leave compose mode and send the message once it is completed. Aborting letter composition is possible with either of ~x or ~q the latter of which will save the message in the file denoted by DEAD unless no save is set. And unless ignoreeof is set the effect of ~. can also be achieved by typing end-of-transmission (EOT) via `control-D' ( `^D' at the beginning of an empty line, and ~q is always reachable by typing end-of-text (ETX) twice via `control-C' ( `^C' ).
The compose mode hooks on-compose-enter , on-compose-splice , on-compose-leave and on-compose-cleanup may be set to define d macros and provide reliable and increasingly powerful mechanisms to perform automated message adjustments dependent on message context, for example addition of message signatures ( message-inject-head , message-inject-tail or creation of additional receiver lists (also by setting autocc , autobcc ) To achieve that the command digmsg may be used in order to query and adjust status of message(s). The splice hook can also make use of Sx COMMAND ESCAPES . ([v15 behaviour may differ] The compose mode hooks work for forward , mail , reply and variants; resend and Resend only provide the hooks on-resend-enter and on-resend-cleanup which are pretty restricted due to the nature of the operation.)
On reading mail, and more on interactive mode
When invoked without addressees S-nail enters interactive mode in which mails may be read. When used like that the user's system inbox (for more on mailbox types please see the command folder is read in and a one line header of each message therein is displayed if the variable header is set. The visual style of this summary of headers can be adjusted through the variable headline and the possible sorting criterion via autosort Scrolling through screen fuls of headers can be performed with the command z If the initially opened mailbox is empty S-nail will instead exit immediately (after displaying a message) unless the variable emptystart is set.At the prompt the command list will give a listing of all available commands and help will [Option]ally give a summary of some common ones. If the [Option]al documentation strings are available (see features one can type `help' X (or `?X' and see the actual expansion of `X' and what its purpose is, i.e., commands can be abbreviated (note that POSIX defines some abbreviations, so that the alphabetical order of commands does not necessarily relate to the abbreviations; it is however possible to define overwrites with commandalias ) These commands can also produce a more verbose output.
Messages are given numbers (starting at 1) which uniquely identify messages; the current message - the ``dot'' - will either be the first new message, or the first unread message, or the first message of the mailbox; the internal variable showlast will instead cause usage of the last message for this purpose. The command headers will display a screen ful of header summaries containing the ``dot'' whereas from will display only the summaries of the given messages, defaulting to the ``dot''
Message content can be displayed with the command type ( `t' alias print ) Here the variable crt controls whether and when S-nail will use the configured PAGER for display instead of directly writing to the user terminal screen the sole difference to the command more which will always use the PAGER The command top will instead only show the first toplines of a message (maybe even compressed if topsqueeze is set). Message display experience may improve by setting and adjusting mime-counter-evidence and also see Sx HTML mail and MIME attachments .
By default the current message ( ``dot'' is displayed, but like with many other commands it is possible to give a fancy message specification (see Sx Specifying messages ) , for example `t:u' will display all unread messages, `t.' will display the ``dot'' `t' 1 5 will type the messages 1 and 5, `t' 1-5 will type the messages 1 through 5, and `t-' and `t+' will display the previous and the next message, respectively. The command search (a more substantial alias for from will display a header summary of the given message specification list instead of their content; the following will search for subjects:
? from "'@Some subject to search for'"
In the default setup all header fields of a message will be type d, but fields can be white- or blacklisted for a variety of applications by using the command headerpick e.g., to restrict their display to a very restricted set for type `headerpick ' Cd type retain Ar from to cc subject . In order to display all header fields of a message regardless of currently active ignore or retain lists, use the commands Type and Top Show will show the raw message content. Note that historically the global s-nail.rc not only adjusts the list of displayed headers, but also sets crt ([v15 behaviour may differ] A yet somewhat restricted) Reliable scriptable message inspection is available via digmsg
Dependent upon the configuration a line editor (see the section Sx On terminal control and line editor ) aims at making the user experience with the many Sx COMMANDS a bit nicer. When reading the system inbox or when -f (or folder specified a mailbox explicitly prefixed with the special `%:' modifier (to propagate it to a Sx primary system mailbox ) , then messages which have been read (see Sx Message states will be automatically moved to a Sx secondary mailbox , the user's MBOX file, when the mailbox is left, either by changing the active mailbox or by quitting S-nail - this automatic moving from a system- or primary- to the secondary mailbox is not performed when the variable hold is set. Messages can also be explicitly move d to other mailboxes, whereas copy keeps the original message. write can be used to write out data content of specific parts of messages.
After examining a message the user can reply `r' to the sender and all recipients (which will also be placed in `To:' unless recipients-in-cc is set), or Reply `R' exclusively to the sender(s). To comply with with the receivers desired reply address the Sx quadoption Ns s followup-to-honour and reply-to-honour should usually be set. The commands Lreply and Lfollowup know how to apply a special addressee massage, see Sx Mailing lists . Dependent on the presence and value of quote the message being replied to will be included in a quoted form. forward ing a message will allow editing the new message: the original message will be contained in the message body, adjusted according to headerpick It is possible to resend or Resend messages: the former will add a series of `Resent-' headers, whereas the latter will not; different to newly created messages editing is not possible and no copy will be saved even with record unless the additional variable record-resent is set. When sending, replying or forwarding messages comments and full names will be stripped from recipient addresses unless the internal variable fullnames is set.
Of course messages can be delete `d' and they can spring into existence again via undelete or when the S-nail session is ended via the exit or xit commands to perform a quick program termation. To end a mail processing session regularly and perform a full program exit one may issue the command quit It will, among others, move read messages to the Sx secondary mailbox MBOX as necessary, discard deleted messages in the current mailbox, and update the [Option]al (see features line editor history-file By the way, whenever the main event loop is about to look out for the next input line it will trigger the hook on-main-loop-tick
HTML mail and MIME attachments
HTML-only messages become more and more common, and many messages come bundled with a bouquet of MIME (Multipurpose Internet Mail Extensions) parts and attachments. To get a notion of MIME types there is a built-in default set, onto which the content of Sx The mime.types files will be added (as configured and allowed by mimetypes-load-control ) Types can also become registered and listed with the command mimetype To improve interaction with the faulty MIME part declarations of real life mime-counter-evidence will allow verification of the given assertion, and the possible provision of an alternative, better MIME type. Note plain text parts will always be preferred in `multipart/alternative' MIME messages unless mime-alternative-favour-rich is set.Whereas a simple HTML-to-text filter for displaying HTML messages is [Option]ally supported (indicated by `,+filter-html-tagsoup,' in features ) MIME types other than plain text cannot be handled directly. To deal with specific non-text MIME types or file extensions programs need to be registered which either prepare (re-)integrable plain text versions of their input (a mode which is called copiousoutput ) or display the content externally, for example in a graphical window: the latter type is only considered by and for the command mimeview
To install a handler program for a MIME type an according pipe-TYPE/SUBTYPE variable needs to be set; to define a handler for a file extension pipe-EXTENSION can be used - these handlers take precedence. [Option]ally mail user agent configuration is supported (see Sx The Mailcap files ) , and will be queried for display or quote handlers after the former ones. Type-markers registered via mimetype are the last possible source for information how to handle a MIME type.
For example, to display HTML messages integrated via the text browsers lynx(1) or elinks(1), register a MathML MIME type and enable its plain text display, and to open PDF attachments in an external PDF viewer, asynchronously and with some other magic attached:
? if "$features" !% ,+filter-html-tagsoup, ? #set pipe-text/html='?* elinks -force-html -dump 1' ? set pipe-text/html='?* lynx -stdin -dump -force_html' ? # Display HTML as plain text instead ? #set pipe-text/html=?t ? endif ? mimetype ?t application/mathml+xml mathml ? wysh set pipe-application/pdf='?&=? \ trap "rm -f \"${MAILX_FILENAME_TEMPORARY}\"" EXIT;\ trap "trap \"\" INT QUIT TERM; exit 1" INT QUIT TERM;\ mupdf "${MAILX_FILENAME_TEMPORARY}"' ? define showhtml { ? \localopts yes ? \set mime-alternative-favour-rich pipe-text/html=?h? ? \type "$@" ? } ? \commandalias html \\call showhtml
Mailing lists
Known or subscribed-to mailing lists may be flagged in the summary of headers ( headline format character `%L' ) , and will gain special treatment when sending mails: the variable followup-to-honour will ensure that a `Mail-Followup-To:' header is honoured when a message is being replied to ( reply followup Lreply Lfollowup ) and followup-to controls creation of this header when creating mail s, if the necessary user setup ( from , sender ) is available; then, it may also be created automatically, for example when list-replying via Lreply or Lfollowup when followup or reply is used and the messages `Mail-Followup-To:' is honoured etc.The commands mlist and mlsubscribe manage S-nails notion of which addresses are mailing lists. With the [Option]al regular expression support any address which contains any of the magic regular expression characters `(' ^[*+?|$ ; see re_format7 or regex(7), dependent on the host system) will be compiled and used as one, possibly matching many addresses. It is not possible to escape the ``magic'' in order to match special characters as-is, bracket expressions must be used, for example `search ' Li @subject@'[[]open bracket' .
? set followup-to followup-to-honour=ask-yes \ reply-to-honour=ask-yes ? mlist a1 [at] b1.c1 a2 [at] b2.c2 '.*@lists\.c3$' ? mlsubscribe a4 [at] b4.c4 exact [at] lists.c3
Known and subscribed lists differ in that for the latter the user s address is not part of a generated `Mail-Followup-To:' There are exceptions, for example if multiple lists are addressed and not all have the subscription attribute. When replying to a message its list address ( `List-Post:' header) is automatically and temporarily treated like a known mlist dependent on the variable reply-to-honour an existing `Reply-To:' is used instead (if it is a single address on the same domain as `List-Post:' ) in order to accept a list administrator's wish that is supposed to have been manifested like that.
For convenience and compatibility with mail programs that do not honour the non-standard M-F-T, an automatic user entry in the carbon-copy `Cc:' address list of generated message can be created by setting followup-to-add-cc This entry will be added whenever the user will be placed in the `Mail-Followup-To:' list, and is not a regular addressee already. reply-to-swap-in tries to deal with the address rewriting that many mailing-lists nowadays perform to work around DKIM / DMARC etc. standard imposed problems.
Signed and encrypted messages with S/MIME
[Option] S/MIME provides two central mechanisms: message signing and message encryption. A signed message contains some data in addition to the regular text. The data can be used to verify that the message has been sent using a valid certificate, that the sender address matches that in the certificate, and that the message text has not been altered. Signing a message does not change its regular text; it can be read regardless of whether the recipients software is able to handle S/MIME. It is thus usually possible to sign all outgoing messages if so desired.Encryption, in contrast, makes the message text invisible for all people except those who have access to the secret decryption key. To encrypt a message, the specific recipients public encryption key must be known. It is therefore not possible to send encrypted mail to people unless their key has been retrieved from either previous communication or public key directories. Because signing is performed with private keys, and encryption with public keys, messages should always be signed before being encrypted.
A central concept to S/MIME is that of the certification authority (CA). A CA is a trusted institution that issues certificates. For each of these certificates it can be verified that it really originates from the CA, provided that the CA's own certificate is previously known. A set of CA certificates is usually delivered and installed together with the cryptographical library that is used on the local system. Therefore reasonable security for S/MIME on the Internet is provided if the source that provides that library installation is trusted. It is also possible to use a specific pool of trusted certificates. If this is desired, smime-ca-no-defaults should be set to avoid using the default certificate pool, and smime-ca-file and/or smime-ca-dir should be pointed to a trusted pool of certificates. A certificate cannot be more secure than the method its CA certificate has been retrieved with.
This trusted pool of certificates is used by the command verify to ensure that the given S/MIME messages can be trusted. If so, verified sender certificates that were embedded in signed messages can be saved locally with the command certsave and used by S-nail to encrypt further communication with these senders:
? certsave FILENAME ? set smime-encrypt-USER [at] HOST=FILENAME \ smime-cipher-USER [at] HOST=AES256
To sign outgoing messages, in order to allow receivers to verify the origin of these messages, a personal S/MIME certificate is required. S-nail supports password-protected personal certificates (and keys), see smime-sign-cert The section Sx On URL syntax and credential lookup gives an overview of the possible sources of user credentials, and Sx S/MIME step by step shows examplarily how a private S/MIME certificate can be obtained. In general, if such a private key plus certificate ``pair'' is available, all that needs to be done is to set some variables:
? set smime-sign-cert=ME [at] exam.ple.paired \ smime-sign-digest=SHA512 \ smime-sign from=myname [at] my.host
Variables of interest for S/MIME in general are smime-ca-dir smime-ca-file smime-ca-flags smime-ca-no-defaults smime-crl-dir smime-crl-file For S/MIME signing of interest are smime-sign smime-sign-cert smime-sign-include-certs and smime-sign-digest Additional variables of interest for S/MIME en- and decryption: smime-cipher and smime-encrypt-USER [at] HOST Variables of secondary interest may be content-description-smime-message and content-description-smime-signature S/MIME is available if `,+smime,' is included in features
[v15 behaviour may differ] Note that neither S/MIME signing nor encryption applies to message subjects or other header fields yet. Thus they may not contain sensitive information for encrypted messages, and cannot be trusted even if the message content has been verified. When sending signed messages, it is recommended to repeat any important header information in the message text.
On URL syntax and credential lookup
For accessing protocol-specific resources Uniform Resource Locators (URL, RFC 3986) have become omnipresent. Here they are expected in a ``normalized'' variant, not used in data exchange, but only meant as a compact, easy-to-use way of defining and representing information in a well-known notation; as such they do not conform to any real standard. Optional parts are placed in brackets `[]' , optional either because there also exist other ways to define the information, or because the part is protocol specific. `/path' for example is used by the [Option]al Maildir folder type and the IMAP protocol, but not by POP3. If `USER' and `PASSWORD' are included in an URL server specification, URL percent encoded (RFC 3986) forms are needed, generable with urlcodec
PROTOCOL://[USER[:PASSWORD]@]server[:port][/path]
Often Sx INTERNAL VARIABLES exist in multiple versions, called ``variable chains'' in this document: the plain `variable' as well as `variable-HOST' and `variable-USER [at] HOST' If a port was specified `HOST' really means `server:port' , not `server' And this `USER' is never in URL percent encoded form. For example, whether the hypothetical `smtp://wings%3Aof@a.dove' including user and password was used, or whether it was `smtp://a.dove' and it came from a different source, to lookup the chain tls-config-pairs first `tls-config-pairs-wings:of [at] a.dove' is looked up, then `tls-config-pairs-a.dove' , before finally looking up the plain variable.
The logic to collect (an account s) credential information is as follows:
-
A user is always required.
If no
`USER'
has been given in the URL the variables
user-HOST
and
user
are looked up.
Afterwards, when enforced by the [Option]al variables
netrc-lookup-HOST
or
netrc-lookup
Sx The .netrc file
of the user will be searched for a
`HOST'
specific entry which provides a
`login'
name: only unambiguous entries are used (one possible matching entry for
`HOST'
) .
If there is still no `USER' then the verified LOGNAME known to be a valid user on the current host, is used.
- Authentication: unless otherwise noted the chain PROTOCOL-auth-USER [at] HOST , PROTOCOL-auth-HOST , PROTOCOL-auth is checked, falling back to a protocol-specific default as necessary.
-
If no
`PASSWORD'
has been given in the URL, then if the
`USER'
has been found through the [Option]al
netrc-lookup
that may have also provided the password.
Otherwise the chain
password-USER [at] HOST , password-HOST , password
is looked up.
Thereafter the (now complete) [Option]al chain netrc-lookup-USER [at] HOST , netrc-lookup-HOST , netrc-lookup is checked, if set the netrc cache is searched for a password only (multiple user accounts for a single machine may exist as well as a fallback entry without user but with a password).
If at that point there is still no password available, but the (protocols') chosen authentication type requires a password, then in interactive mode the user will be prompted on the terminal.
Note: S/MIME verification works relative to the values found in the `From:' (or `Sender:' ) header field(s), which means the values of smime-sign , smime-sign-cert , smime-sign-include-certs and smime-sign-digest will not be looked up using the `USER' and `HOST' chains from above, but instead use the corresponding values from the message that is being worked on. If no address matches we assume and use the setting of from In unusual cases multiple and different `USER' and `HOST' combinations may therefore be involved - on the other hand those unusual cases become possible. The usual case is as short as:
set mta=smtp://USER:PASS@HOST smtp-use-starttls \ smime-sign smime-sign-cert=+smime.pair \ from=myname [at] my.host
The section Sx EXAMPLES contains complete example configurations.
Encrypted network communication
[Option] SSL (Secure Sockets Layer) aka its successor TLS (Transport Layer Security) are protocols which aid in securing communication by providing a safely initiated and encrypted network connection. A central concept of TLS are certificates: as part of each network connection setup a (set of) certificates will be exchanged through which the identity of the network peer can be cryptographically verified; if possible the TLS/SNI (ServerNameIndication) extension will be enabled to allow servers fine-grained control over the certificates being used. A locally installed pool of trusted certificates will then be inspected, and verification will succeed if it contains a(n in)direct signer of the presented certificate(s).The local pool of trusted so-called CA (Certification Authority) certificates is usually delivered with and used along the TLS library. A custom pool of trusted certificates can be selected by pointing tls-ca-file and/or (with special preparation) tls-ca-dir to the desired location; setting tls-ca-no-defaults in addition will avoid additional inspection of the default pool. A certificate cannot be more secure than the method its CA certificate has been retrieved with. For inspection or other purposes, the certificate of a server (as seen when connecting to it) can be fetched with the command tls (port can usually be the protocol name, too, and tls-verify is taken into account here):
$ s-nail -vX 'tls certchain SERVER-URL[:PORT]; x'
A local pool of CA certificates is not strictly necessary, however, server certificates can also be verified via their fingerprint. For this a message digest will be calculated and compared against the variable chain tls-fingerprint and verification will succeed if the fingerprint matches. The message digest (algorithm) can be configured via the variable chain tls-fingerprint-digest tls can again be used:
$ s-nail -X 'wysh set verbose; tls fingerprint SERVER-URL[:PORT]; x'
It depends on the used protocol whether encrypted communication is possible, and which configuration steps have to be taken to enable it. Some protocols, like POP3S, are implicitly encrypted, others, like POP3, can upgrade a plain text connection if so requested. For example, to use the `STLS' that POP3 offers (a member of) the variable (chain) pop3-use-starttls needs to be set, with convenience via shortcut
shortcut encpop1 pop3s://pop1.exam.ple shortcut encpop2 pop3://pop2.exam.ple set pop3-use-starttls-pop2.exam.ple set mta=smtps://smtp.exam.ple:465 set mta=smtp://smtp.exam.ple smtp-use-starttls
Normally that is all there is to do, given that TLS libraries try to provide safe defaults, plenty of knobs however exist to adjust settings. For example certificate verification settings can be fine-tuned via tls-ca-flags and the TLS configuration basics are accessible via tls-config-pairs for example to control protocol versions or cipher lists. In the past hints on how to restrict the set of protocols to highly secure ones were indicated, but as of the time of this writing the list of protocols or ciphers may need to become relaxed in order to be able to connect to some servers; the following example allows connecting to a ``Lion'' that uses OpenSSL 0.9.8za from June 2014 (refer to Sx INTERNAL VARIABLES for more on variable chains):
wysh set tls-config-pairs-lion [at] exam.ple='MinProtocol=TLSv1.1,\ CipherString=TLSv1.2:!aNULL:!eNULL:\ ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:\ DHE-RSA-AES256-SHA:@STRENGTH'
The OpenSSL program ciphers(1) should be referred to when creating a custom cipher list. Variables of interest for TLS in general are tls-ca-dir tls-ca-file tls-ca-flags tls-ca-no-defaults tls-config-file tls-config-module tls-config-pairs tls-crl-dir tls-crl-file tls-rand-file as well as tls-verify Also see tls-features TLS is available if `+tls' is included in features
Character sets
[Option] The user's locale environment is detected by looking at the LC_ALL environment variable. The internal variable ttycharset will be set to the detected terminal character set accordingly, and will thus show up in the output of commands like set and varshow This character set will be targeted when trying to display data, and user input data is expected to be in this character set, too.When creating messages their character input data is classified. 7-bit clean text data and attachments will be classified as charset-7bit 8-bit data will [Option]ally be converted into members of sendcharsets until a character set conversion succeeds. charset-8bit is the implied default last member of this list. If no 8-bit character set is capable to represent input data, no message will be sent, and its text will optionally be save d in DEAD If that is not acceptable, for example in script environments, mime-force-sendout can be set to force sending of non-convertible data as `application/octet-stream' classified binary content instead: like this receivers still have the option to inspect message content (for example via mime-counter-evidence ) If the [Option]al character set conversion is not available ( features misses `,+iconv,' ) , ttycharset is the only supported character set for non 7-bit clean data, and it is simply assumed it can be used to exchange 8-bit messages.
ttycharset may also be given an explicit value to send mail in a completely ``faked'' locale environment, which can be used to generate and send for example 8-bit UTF-8 input data in a pure 7-bit US-ASCII `LC_ALL=C' environment (an example of this can be found in the section Sx On sending mail, and non-interactive mode ) . Due to lack of programming interfaces reading mail will not really work as expected in a faked environment: whereas ttycharset might be addressable, any output will be made safely printable, as via vexpr makeprint according to the actual locale environment, which is not affected by ttycharset.
Classifying 7-bit clean data as charset-7bit is a problem if the input character set ( ttycharset is a multibyte character set that is itself 7-bit clean. For example, the Japanese character set ISO-2022-JP is, but is capable to encode the rich set of Japanese Kanji, Hiragana and Katakana characters: in order to notify receivers of this character set the mail message must be MIME encoded so that the character set ISO-2022-JP can be advertised, otherwise an invalid email message would result! To achieve this, the variable charset-7bit can be set to ISO-2022-JP. (Today a better approach regarding email is the usage of UTF-8, which uses 8-bit bytes for non-US-ASCII data.)
When replying to a message and the variable reply-in-same-charset is set, the character set of the message being replied to is tried first as a target character set (still being a subject of charsetalias filtering, however). Another opportunity is sendcharsets-else-ttycharset to reflect the user's locale environment automatically, it will treat ttycharset as an implied member of (an unset) sendcharsets
[Option] When reading messages, their text data is converted into ttycharset as necessary in order to display them on the user's terminal. Unprintable characters and invalid byte sequences are detected and replaced by substitution characters. Character set mappings for source character sets can be established with charsetalias which may be handy to work around faulty or incomplete character set catalogues (one could for example add a missing LATIN1 to ISO-8859-1 mapping), or to enforce treatment of one character set as another one ( ``interpret LATIN1 as CP1252'' Also see charset-unknown-8bit to deal with another hairy aspect of message interpretation.
In general, if a message saying ``cannot convert from a to b'' appears, either some characters are not appropriate for the currently selected (terminal) character set, or the needed conversion is not supported by the system. In the first case, it is necessary to set an appropriate LC_CTYPE locale and/or the variable ttycharset The best results are usually achieved when running in a UTF-8 locale on a UTF-8 capable terminal, in which case the full Unicode spectrum of characters is available. In this setup characters from various countries can be displayed, while it is still possible to use more simple character sets for sending to retain maximum compatibility with older mail clients.
On the other hand the POSIX standard defines a locale-independent 7-bit ``portable character set'' that should be used when overall portability is an issue, the even more restricted subset named ``portable filename character set'' consists of A-Z, a-z, 0-9, period `.' , underscore `_' and hyphen-minus `-'
Message states
S-nail differentiates in between several message states; the current state will be reflected in the summary of headers if the attrlist of the configured headline allows, and Sx Specifying messages dependent on their state is possible. When operating on the system inbox or in any other Sx primary system mailbox , special actions, like the automatic moving of messages to the Sx secondary mailbox MBOX may be applied when the mailbox is left (also implicitly by program termination, unless the command exit was used) - however, because this may be irritating to users which are used to ``more modern'' mail-user-agents, the provided global s-nail.rc template sets the internal hold and keepsave variables in order to suppress this behaviour.- `new'
- Message has neither been viewed nor moved to any other state. Such messages are retained even in the Sx primary system mailbox .
- `unread'
- Message has neither been viewed nor moved to any other state, but the message was present already when the mailbox has been opened last: Such messages are retained even in the Sx primary system mailbox .
- `read'
-
The message has been processed by one of the following commands:
~f
~m
~F
~M
copy
mbox
next
pipe
Print
print
top
Type
type
undelete
The commands
dp
and
dt
will always try to automatically
``step''
and
type
the
``next''
logical message, and may thus mark multiple messages as read, the
delete
command will do so if the internal variable
autoprint
is set.
Except when the exit command is used, messages that are in a Sx primary system mailbox and are in `read' state when the mailbox is left will be saved in the Sx secondary mailbox MBOX unless the internal variable hold it set.
- `deleted'
- The message has been processed by one of the following commands: delete dp dt Only undelete can be used to access such messages.
- `preserved'
- The message has been processed by a preserve command and it will be retained in its current location.
- `saved'
- The message has been processed by one of the following commands: save or write Unless when the exit command is used, messages that are in a Sx primary system mailbox and are in `saved' state when the mailbox is left will be deleted; they will be saved in the Sx secondary mailbox MBOX when the internal variable keepsave is set.
In addition to these message states, flags which otherwise have no technical meaning in the mail system except allowing special ways of addressing them when Sx Specifying messages can be set on messages. These flags are saved with messages and are thus persistent, and are portable between a set of widely used MUAs.
- answered
- Mark messages as having been answered.
- draft
- Mark messages as being a draft.
- flag
- Mark messages which need special attention.
Specifying messages
[Only new quoting rules] COMMANDS which take Sx Message list arguments , such as search type copy and delete can perform actions on a number of messages at once. Specifying invalid messages, or using illegal syntax, will cause errors to be reported through the Sx INTERNAL VARIABLES ! ^ERR and companions, as well as the command exit status ?For example, `delete' 1 2 deletes the messages 1 and 2, whereas `delete' 1-5 will delete the messages 1 through 5. In sorted or threaded mode (see the sort command), `delete' 1-5 will delete the messages that are located between (and including) messages 1 through 5 in the sorted/threaded order, as shown in the headers summary.
Errors can for example be ^ERR -BADMSG when requesting an invalid message, ^ERR -NOMSG if no applicable message can be found, ^ERR -CANCELED for missing informational data (mostly thread-related). ^ERR -INVAL for invalid syntax as well as ^ERR -IO for input/output errors can happen. The following special message names exist:
- .
- The current message, the so-called ``dot''
- ;
- The message that was previously the current message; needs to be quoted.
- ,
- The parent message of the current message, that is the message with the Message-ID given in the `In-Reply-To:' field or the last entry of the `References:' field of the current message.
- file ...
- The previous undeleted message, or the previous deleted message for the undelete command; In sort ed or `thread' Ns ed mode, the previous such message in the according order.
- file ...
- The next undeleted message, or the next deleted message for the undelete command; In sort ed or `thread' Ns ed mode, the next such message in the according order.
- file ...
- The first undeleted message, or the first deleted message for the undelete command; In sort ed or `thread' Ns ed mode, the first such message in the according order.
- file ...
- The last message; In sort ed or `thread' Ns ed mode, the last such message in the according order. Needs to be quoted.
- & x
- In `thread' Ns ed sort mode, selects the message addressed with x where x is any other message specification, and all messages from the thread that begins at it. Otherwise it is identical to x If x is omitted, the thread beginning with the current message is selected.
- file ...
- All messages.
- file ...
- All messages that were included in the Sx Message list arguments of the previous command; needs to be quoted. (A convenient way to read all new messages is to select them via `from' :n , as below, and then to read them in order with the default command --- next --- simply by successively typing ``' ; for this to work showlast must be set.)
- x-y
- An inclusive range of message numbers. Selectors that may also be used as endpoints include any of .;-+^$
- address
- A case-insensitive ``any substring matches'' search against the `From:' header, which will match addresses (too) even if showname is set (and POSIX says ``any address as shown in a header summary shall be matchable in this form )'' However, if the allnet variable is set, only the local part of the address is evaluated for the comparison, not ignoring case, and the setting of showname is completely ignored. For finer control and match boundaries use the `@' search expression.
- / string
- All messages that contain string in the subject field (case ignored according to locale). See also the searchheaders variable. If string is empty, the string from the previous specification of that type is used again.
- [@ name-list @ expr ]
-
- All messages that contain the given case-insensitive search expr ession; If the [Option]al regular expression support is available expr will be interpreted as (an extended) one if any of the Sx magic regular expression characters is seen. If the optional @ name-list part is missing the search is restricted to the subject field body, but otherwise name-list specifies a comma-separated list of header fields to search, for example
'@to,from,cc [at] Someone i ought to know'
In order to search for a string that includes a `@' (commercial at) character the name-list is effectively non-optional, but may be given as the empty string. Also, specifying an empty search expr ession will effectively test for existence of the given header fields. Some special header fields may be abbreviated: `f' , `t' , `c' , `b' and `s' will match `From' , `To , ' `Cc , ' `Bcc' and `Subject' , respectively and case-insensitively. [Option]ally, and just like expr name-list will be interpreted as (an extended) regular expression if any of the Sx magic regular expression characters is seen.
The special names `header' or `<' can be used to search in (all of) the header(s) of the message, and the special names `body' or `>' and `text' or `=' will perform full text searches - whereas the former searches only the body, the latter also searches the message header ([v15 behaviour may differ] this mode yet brute force searches over the entire decoded content of messages, including administrativa strings).
This specification performs full text comparison, but even with regular expression support it is almost impossible to write a search expression that safely matches only a specific address domain. To request that the body content of the header is treated as a list of addresses, and to strip those down to the plain email address which the search expression is to be matched against, prefix the effective name-list with a tilde `~' :
'@~f,c@@a\.safe\.domain\.match$'
- All messages that contain the given case-insensitive search expr ession; If the [Option]al regular expression support is available expr will be interpreted as (an extended) one if any of the Sx magic regular expression characters is seen. If the optional @ name-list part is missing the search is restricted to the subject field body, but otherwise name-list specifies a comma-separated list of header fields to search, for example
- :c
-
All messages of state or with matching condition
`c'
,
where
`c'
is one or multiple of the following colon modifiers:
- a
- answered messages (cf. the variable markanswered )
- d
- `deleted' messages (for the undelete and from commands only).
- f
- flag ged messages.
- L
- Messages with receivers that match mlsubscribe d addresses.
- l
- Messages with receivers that match mlist ed addresses.
- n
- `new' messages.
- o
- Old messages (any not in state `read' or `new' ) .
- r
- `read' messages.
- S
- [Option] Messages with unsure spam classification (see Sx Handling spam ) .
- s
- [Option] Messages classified as spam.
- t
- Messages marked as draft
- u
- `unread' messages.
[Option] IMAP-style SEARCH expressions may also be used. These consist of keywords and criterions, and because Sx Message list arguments are split into tokens according to Sx Shell-style argument quoting it is necessary to quote the entire IMAP search expression in order to ensure that it remains a single token. This addressing mode is available with all types of mailbox folder s; S-nail will perform the search locally as necessary. Strings must be enclosed by double quotation marks `' in their entirety if they contain whitespace or parentheses; within the quotes, only reverse solidus `\' is recognized as an escape character. All string searches are case-insensitive. When the description indicates that the ``envelope'' representation of an address field is used, this means that the search string is checked against both a list constructed as
'("name" "source" "local-part" "domain-part")'
for each address, and the addresses without real names from the respective header field. These search expressions can be nested using parentheses, see below for examples.
- ( criterion
- All messages that satisfy the given criterion
- ( criterion1 criterion2 ... criterionN
- All messages that satisfy all of the given criteria.
- ( or criterion1 criterion2
- All messages that satisfy either criterion1 or criterion2 or both. To connect more than two criteria using `or' specifications have to be nested using additional parentheses, as with `(or' a (or b c)) , since `(or' a b c) really means `((a' or b) and c) . For a simple `or' operation of independent criteria on the lowest nesting level, it is possible to achieve similar effects by using three separate criteria, as with `(a)' (b) (c) .
- ( not criterion
- All messages that do not satisfy criterion
- ( bcc " string "
- All messages that contain string in the envelope representation of the `Bcc:' field.
- ( cc " string "
- All messages that contain string in the envelope representation of the `Cc:' field.
- ( from " string "
- All messages that contain string in the envelope representation of the `From:' field.
- ( subject " string "
- All messages that contain string in the `Subject:' field.
- ( to " string "
- All messages that contain string in the envelope representation of the `To:' field.
- ( header name " string "
- All messages that contain string in the specified `Name:' field.
- ( body " string "
- All messages that contain string in their body.
- ( text " string "
- All messages that contain string in their header or body.
- ( larger size
- All messages that are larger than size (in bytes).
- ( smaller size
- All messages that are smaller than size (in bytes).
- ( before date
- All messages that were received before date which must be in the form `d[d]-mon-yyyy' , where `d' denotes the day of the month as one or two digits, `mon' is the name of the month - one of `Jan' Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec , and `yyyy' is the year as four digits, for example `28-Dec-2012'
- ( on date
- All messages that were received on the specified date.
- ( since date
- All messages that were received since the specified date.
- ( sentbefore date
- All messages that were sent on the specified date.
- ( senton date
- All messages that were sent on the specified date.
- ( sentsince date
- All messages that were sent since the specified date.
- ()
- The same criterion as for the previous search. This specification cannot be used as part of another criterion. If the previous command line contained more than one independent criterion then the last of those criteria is used.
On terminal control and line editor
[Option] Terminal control through one of the standard UNIX libraries, Lb libtermcap or Lb libterminfo , may be available. For the TERM inal defined in the environment interactive usage aspects, for example Sx Coloured display , and insight of cursor and function keys for the Mailx-Line-Editor (MLE), will be enhanced or enabled. Library interaction can be disabled on a per-invocation basis via termcap-disable whereas the internal variable termcap is always used as a preferred source of terminal capabilities. (For a usage example see the Sx FAQ entry Sx Not "defunctional", but the editor key does not work . )[Option] The built-in Mailx-Line-Editor (MLE) should work in all environments which comply to the ISO C standard St -isoC-amd1 , and will support wide glyphs if possible (the necessary functionality had been removed from ISO C, but was included in St -xpg4 ) . Usage of a line editor in interactive mode can be prevented by setting line-editor-disable Especially if the [Option]al terminal control support is missing setting entries in termcap will help shall the MLE misbehave, see there for more. The MLE can support a little bit of colour
[Option] If the history feature is available then input from line editor prompts will be saved in a history list that can be searched in and be expanded from. Such saving can be prevented by prefixing input with any amount of whitespace. Aspects of history, like allowed content and maximum size, as well as whether history shall be saved persistently, can be configured with the internal variables history-file history-gabby history-gabby-persist and history-size There also exists the macro hook on-history-addition which can be used to apply finer control on what enters history.
The MLE supports a set of editing and control commands. By default (as) many (as possible) of these will be assigned to a set of single-letter control codes, which should work on any terminal (and can be generated by holding the ``control'' key while pressing the key of desire, for example `control-D' ) . If the [Option]al bind command is available then the MLE commands can also be accessed freely by assigning the command name, which is shown in parenthesis in the list below, to any desired key-sequence, and the MLE will instead and also use bind to establish its built-in key bindings (more of them if the [Option]al terminal control is available), an action which can then be suppressed completely by setting line-editor-no-defaults Sx Shell-style argument quoting notation is used in the following:
- `\cA'
- Go to the start of the line ( mle-go-home
- `\cB'
- Move the cursor backward one character ( mle-go-bwd
- `\cC'
- raise(3) `SIGINT' ( mle-raise-int
- `\cD'
- Forward delete the character under the cursor; quits S-nail if used on the empty line unless the internal variable ignoreeof is set ( mle-del-fwd
- `\cE'
- Go to the end of the line ( mle-go-end
- `\cF'
- Move the cursor forward one character ( mle-go-fwd
- `\cG'
- Cancel current operation, full reset. If there is an active history search or tabulator expansion then this command will first reset that, reverting to the former line content; thus a second reset is needed for a full reset in this case ( mle-reset
- `\cH'
- Backspace: backward delete one character ( mle-del-bwd
- `\cI'
- [Only new quoting rules] Horizontal tabulator: try to expand the word before the cursor, supporting the usual Sx Filename transformations ( mle-complete this is affected by mle-quote-rndtrip and line-editor-cpl-word-breaks )
- `\cJ'
- Newline: commit the current line ( mle-commit
- `\cK'
- Cut all characters from the cursor to the end of the line ( mle-snarf-end
- `\cL'
- Repaint the line ( mle-repaint
- `\cN'
- [Option] Go to the next history entry ( mle-hist-fwd
- `\cO'
- ([Option]ally context-dependent) Invokes the command dt
- `\cP'
- [Option] Go to the previous history entry ( mle-hist-bwd
- `\cQ'
- Toggle roundtrip mode shell quotes, where produced, on and off ( mle-quote-rndtrip This setting is temporary, and will be forgotten once the command line is committed; also see shcodec
- `\cR'
- [Option] Complete the current line from (the remaining) older history entries ( mle-hist-srch-bwd
- `\cS'
- [Option] Complete the current line from (the remaining) newer history entries ( mle-hist-srch-fwd
- `\cT'
- Paste the snarf buffer ( mle-paste
- `\cU'
- The same as `\cA' followed by `\cK' ( mle-snarf-line
- `\cV'
- Prompts for a Unicode character (hexadecimal number without prefix, see vexpr to be inserted ( mle-prompt-char Note this command needs to be assigned to a single-letter control code in order to become recognized and executed during input of a key-sequence (only three single-letter control codes can be used for that shortcut purpose); this control code is then special-treated and thus cannot be part of any other sequence (because it will trigger the mle-prompt-char function immediately).
- `\cW'
- Cut the characters from the one preceding the cursor to the preceding word boundary ( mle-snarf-word-bwd
- `\cX'
- Move the cursor forward one word boundary ( mle-go-word-fwd
- `\cY'
- Move the cursor backward one word boundary ( mle-go-word-bwd
- `\cZ'
- raise(3) `SIGTSTP' ( mle-raise-tstp
- `\c['
- Escape: reset a possibly used multibyte character input state machine and [Option]ally a lingering, incomplete key binding ( mle-cancel This command needs to be assigned to a single-letter control code in order to become recognized and executed during input of a key-sequence (only three single-letter control codes can be used for that shortcut purpose). This control code may also be part of a multi-byte sequence, but if a sequence is active and the very control code is currently also an expected input, then the active sequence takes precedence and will consume the control code.
- `\c\'
- ([Option]ally context-dependent) Invokes the command `z ' Ns + .
- `\c]'
- ([Option]ally context-dependent) Invokes the command `z ' Ns $ .
- `\c^'
- ([Option]ally context-dependent) Invokes the command `z ' Ns 0 .
- `\c_'
- Cut the characters from the one after the cursor to the succeeding word boundary ( mle-snarf-word-fwd
- `\c?'
- Backspace: mle-del-bwd
- -
- mle-bell ring the audible bell.
- -
- [Option] mle-clear-screen move the cursor home and clear the screen.
- -
- mle-fullreset different to mle-reset this will immediately reset a possibly active search etc.
- -
- mle-go-screen-bwd move the cursor backward one screen width.
- -
- mle-go-screen-fwd move the cursor forward one screen width.
- -
- mle-raise-quit: raise(3) `SIGQUIT'
Coloured display
[Option] Colours and font attributes through ANSI a.k.a. ISO 6429 SGR (select graphic rendition) escape sequences are optionally supported. Usage of colours and font attributes solely depends upon the capability of the detected terminal type ( TERM and as fine-tuned through termcap Colours and font attributes can be managed with the multiplexer command colour and uncolour removes the given mappings. Setting colour-disable suppresses usage of colour and font attribute sequences, while leaving established mappings unchanged.Whether actually applicable colour and font attribute sequences should also be generated when output is going to be paged through the external PAGER (also see crt ) depends upon the setting of colour-pager because pagers usually need to be configured in order to support ISO escape sequences. Knowledge of some widely used pagers is however built-in, and in a clean environment it is often enough to simply set colour-pager please refer to that variable for more on this topic.
It might make sense to conditionalize colour setup on interactive mode via if ( `terminal' indeed means ``interactive )''
if terminal && "$features" =% ,+colour, colour iso view-msginfo ft=bold,fg=green colour iso view-header ft=bold,fg=red (from|subject) # regex colour iso view-header fg=red uncolour iso view-header from,subject colour iso view-header ft=bold,fg=magenta,bg=cyan colour 256 view-header ft=bold,fg=208,bg=230 "subject,from" colour mono view-header ft=bold colour mono view-header ft=bold,ft=reverse subject,from endif
Handling spam
[Option] S-nail can make use of several spam interfaces for the purpose of identification of, and, in general, dealing with spam messages. A precondition of most commands in order to function is that the spam-interface variable is set to one of the supported interfaces. Sx Specifying messages that have been identified as spam is possible via their (volatile) `is-spam' state by using the `:s ' and `:S ' specifications, and their attrlist entries will be used when displaying the headline in the summary of headers- spamrate rates the given messages and sets their `is-spam' flag accordingly. If the spam interface offers spam scores these can be shown in headline by using the format `%$'
- spamham spamspam and spamforget will interact with the Bayesian filter of the chosen interface and learn the given messages as ``ham'' or ``spam'' respectively; the last command can be used to cause ``unlearning'' of messages; it adheres to their current `is-spam' state and thus reverts previous teachings.
- spamclear and spamset will simply set and clear, respectively, the mentioned volatile `is-spam' message flag, without any interface interaction.
The spamassassin(1) based spam-interface `spamc' requires a running instance of the spamd(1) server in order to function, started with the option --allow-tell shall Bayesian filter learning be possible.
$ spamd -i localhost:2142 -i /tmp/.spamsock -d [-L] [-l] $ spamd --listen=localhost:2142 --listen=/tmp/.spamsock \ --daemonize [--local] [--allow-tell]
Thereafter S-nail can make use of these interfaces:
$ s-nail -Sspam-interface=spamc -Sspam-maxsize=500000 \ -Sspamc-command=/usr/local/bin/spamc \ -Sspamc-arguments="-U /tmp/.spamsock" -Sspamc-user= or $ s-nail -Sspam-interface=spamc -Sspam-maxsize=500000 \ -Sspamc-command=/usr/local/bin/spamc \ -Sspamc-arguments="-d localhost -p 2142" -Sspamc-user=
Using the generic filter approach allows usage of programs like bogofilter(1). Here is an example, requiring it to be accessible via PATH
$ s-nail -Sspam-interface=filter -Sspam-maxsize=500000 \ -Sspamfilter-ham="bogofilter -n" \ -Sspamfilter-noham="bogofilter -N" \ -Sspamfilter-nospam="bogofilter -S" \ -Sspamfilter-rate="bogofilter -TTu 2>/dev/null" \ -Sspamfilter-spam="bogofilter -s" \ -Sspamfilter-rate-scanscore="1;^(.+)$"
Because messages must exist on local storage in order to be scored (or used for Bayesian filter training), it is possibly a good idea to perform the local spam check last. Spam can be checked automatically when opening specific folders by setting a specialized form of the internal variable folder-hook
define spamdelhook { # Server side DCC spamset (header x-dcc-brand-metrics "bulk") # Server-side spamassassin(1) spamset (header x-spam-flag "YES") del :s # TODO we HAVE to be able to do `spamrate :u ! :sS' move :S +maybe-spam spamrate :u del :s move :S +maybe-spam } set folder-hook-SOMEFOLDER=spamdelhook
See also the documentation for the variables
spam-interface , spam-maxsize
spamc-command , spamc-arguments , spamc-user
spamfilter-ham , spamfilter-noham , spamfilter-nospam ,
The beginning of such input lines is then scanned for the name of
a known command: command names may be abbreviated, in which case the
first command that matches the given prefix will be used.
Sx Command modifiers
may prefix a command in order to modify its behaviour.
A name may also be a
commandalias
which will become expanded until no more expansion is possible.
Once the command that shall be executed is known, the remains of the
input line will be interpreted according to command-specific rules,
documented in the following.
This behaviour is different to the
sh(1)
ell, which is a programming language with syntactic elements of clearly
defined semantics, and therefore capable to sequentially expand and
evaluate individual elements of a line.
`?'
set one=value two=$one
for example will never possibly assign value to one, because the
variable assignment is performed no sooner but by the command
( set
long after the expansion happened.
A list of all commands in lookup order is dumped by the command
list
[Option]ally the command
help
(or
? )
when given an argument, will show a documentation string for the
command matching the expanded argument, as in
`?t'
,
which should be a shorthand of
`?type'
;
with these documentation strings both commands support a more
verbose
listing mode which includes the argument type of the command and other
information which applies; a handy suggestion might thus be:
The given name will be tested for being a valid
sh(1)
variable name, and may therefore only consist of upper- and lowercase
characters, digits, and the underscore; the hyphen-minus may be used as
a non-portable extension; digits may not be used as first, hyphen-minus
may not be used as last characters.
In addition the name may either not be one of the known
Sx INTERNAL VARIABLES ,
or must otherwise refer to a writable (non-boolean) value variable.
The actual put operation may fail nonetheless, for example if the
variable expects a number argument only a number will be accepted.
Any error during these operations causes the command as such to fail,
and the error number
!
will be set to
^ERR -NOTSUP
the exit status
?
should be set to
`-1'
,
but some commands deviate from the latter, which is documented.
A command line is parsed from left to right and an input token is
completed whenever an unquoted, otherwise ignored, metacharacter is seen.
Metacharacters are vertical bar
|
ampersand
&
semicolon
;
as well as all characters from the variable
ifs
and / or
space , tabulator , newline
The additional metacharacters left and right parenthesis
( , )
and less-than and greater-than signs
< ,
that the
sh(1)
supports are not used, and are treated as ordinary characters: for one
these characters are a vivid part of email addresses, and it seems
highly unlikely that their function will become meaningful to S-nail.
It also often depends on an actual subcommand of a multiplexer command
how the rest of the line should be treated, and until v15 we are not
capable to perform this deep inspection of arguments.
Nonetheless, at least the following commands which work with positional
parameters fully support
ifs
for an almost shell-compatible field splitting:
call , call_if , read , vpospar , xcall
Any unquoted number sign
`#'
at the beginning of a new token starts a comment that extends to the end
of the line, and therefore ends argument processing.
An unquoted dollar sign
`$'
will cause variable expansion of the given name, which must be a valid
sh(1)
ell-style variable name (see
vput )
Sx INTERNAL VARIABLES
as well as
Sx ENVIRONMENT
(shell) variables can be accessed through this mechanism, brace
enclosing the name is supported (i.e., to subdivide a token).
Whereas the metacharacters
space , tabulator , newline
only complete an input token, vertical bar
|
ampersand
&
and semicolon
;
also act as control operators and perform control functions.
For now supported is semicolon
;
which terminates a single command, therefore sequencing the command line
and making the remainder of the line a subject to reevaluation.
With sequencing, multiple command argument types and quoting rules may
therefore apply to a single line, which can become problematic before
v15: e.g., the first of the following will cause surprising results.
Quoting is a mechanism that will remove the special meaning of
metacharacters and reserved words, and will prevent expansion.
There are four quoting mechanisms: the escape character, single-quotes,
double-quotes and dollar-single-quotes:
Whereas historically circumflex notation has often been used for
visualization purposes of control codes, as in
`^G'
,
the reverse solidus notation has been standardized:
`\cG'
Some control codes also have standardized (ISO-10646, ISO C) aliases,
as shown above
( `\a'
`\n'
,
`\t'
etc) :
whenever such an alias exists it will be used for display purposes.
The control code NUL
( `\c@'
a non-standard extension) will suppress further output for the remains
of the token (which may extend beyond the current quote), or, depending
on the context, the remains of all arguments for the current command.
Caveats:
A shell expansion as if specified in double-quotes (see
Sx Shell-style argument quoting )
may be applied, so that any occurrence of
`$VARIABLE'
(or
`${VARIABLE}'
)
will be replaced by the expansion of the variable, if possible;
Sx INTERNAL VARIABLES
as well as
Sx ENVIRONMENT
(shell) variables can be accessed through this mechanism.
Shell pathname wildcard pattern expansions
( glob(7)
may be applied as documented.
If the fully expanded filename results in multiple pathnames and the
command is expecting only one file, an error results.
In interactive context, in order to allow simple value acceptance (via
``ENTER )''
arguments will usually be displayed in a properly quoted form, so a file
`diet\'
is \curd.txt
may be displayed as
`'diet\'
is \curd.txt' .
In conjunction with the
vput
modifier the following special cases exist:
a negative exit status occurs if the collected data could not be stored
in the given variable, which is a
^ERR -NOTSUP
error that should otherwise not occur.
^ERR -CANCELED
indicates that no temporary file could be created to collect the command
output at first glance.
In case of catchable out-of-memory situations
^ERR -NOMEM
will occur and S-nail will try to store the empty string, just like with
all other detected error conditions.
Without arguments a listing of all defined accounts is shown.
With one argument the given account is activated: the system
inbox
of that account will be activated (as via
folder )
a possibly installed
folder-hook
will be run, and the internal variable
account
will be updated.
The two argument form behaves identical to defining a macro as via
define
Important settings for accounts include
folder , from , hostname , inbox , mta , password
and
user
( Sx On URL syntax and credential lookup )
as well as things like
tls-config-pairs
( Sx Encrypted network communication )
and protocol specifics like
imap-auth , pop3-auth , smtp-auth
Decoding will show how a standard-compliant MUA will display the given
argument, which should be an email address.
Please be aware that most MUAs have difficulties with the address
standards, and vary wildly when (comments) in parenthesis,
``double-quoted''
strings, or quoted-pairs, as below, become involved.
[v15 behaviour may differ] S-nail currently does not perform decoding when displaying addresses.
Skinning is identical to decoding but only outputs the plain address,
without any string, comment etc. components.
Another difference is that it may fail with the error number
!
set to
^ERR -INVAL
if decoding fails to find a(n) (valid) email address, in which case the
unmodified input will be output again.
skinlist
first performs a skin operation, and thereafter checks a valid
address for whether it is a registered mailing list (see
mlist
and
mlsubscribe )
eventually reporting that state in the error number
!
as
^ERR -EXIST
(This state could later become overwritten by an I/O error, though.)
Encoding supports four different modes, lesser automated versions can be
chosen by prefixing one, two or three plus signs: the standard imposes
a special meaning on some characters, which thus have to be transformed
to so-called quoted-pairs by pairing them with a reverse solidus
`\'
in order to remove the special meaning; this might change interpretation
of the entire argument from what has been desired, however!
Specify one plus sign to remark that parenthesis shall be left alone,
two for not turning double quotation marks into quoted-pairs, and three
for also leaving any user-specified reverse solidus alone.
The result will always be valid, if a successful exit status is reported
([v15 behaviour may differ] the current parser fails this assertion for some constructs).
[v15 behaviour may differ] Addresses need to be specified in between angle brackets
`<'
,
`>'
if the construct becomes more difficult, otherwise the current parser
will fail; it is not smart enough to guess right.
In all other cases the given alias is newly defined, or will be appended
to: arguments must either be themselves valid alias names, or any
other address type (see
Sx On sending mail, and non-interactive mode ) .
Recursive expansion of aliases can be prevented by prefixing the desired
argument with the modifier reverse solidus
\
A valid alias name conforms to
mta-aliases
syntax, but follow-up characters can also be the number sign
`#'
,
colon
`:'
,
commercial at
`@,'
exclamation mark
`!'
,
period
`.'
as well as
``any character that has the high bit set''
The dollar sign
`$'
may be the last character.
The number sign
`#'
may need
Sx Shell-style argument quoting .
[v15 behaviour may differ] Unfortunately the colon is currently not supported, as it
interferes with normal address parsing rules.
[v15 behaviour may differ] Such high bit characters will likely cause warnings at the moment
for the same reasons why colon is unsupported; also, in the future
locale dependent character set validity checks will be performed.
The former command manages the error number
!
It shows the current set of alternates when used without arguments; in
this mode only it also supports
vput
(see
Sx Command modifiers ) .
Otherwise the given arguments (after being checked for validity) are
appended to the list of alternate names; in
posix
mode they replace that list instead.
With zero arguments, or with a context name the former command shows
all key bindings (of the given context; an asterisk
`*'
will iterate over all contexts); a more verbose listing will be
produced if either of
debug
or
verbose
are set.
With two or more arguments a specific binding is shown, or
(re)established: the first argument is the context to which the binding
shall apply, the second argument is a comma-separated list of the
``keys''
which form the binding.
Further arguments will be joined to form the expansion, and cause the
binding to be created or updated.
To indicate that a binding shall not be auto-committed, but that the
expansion shall instead be furtherly editable by the user, a commercial at
`@'
(that will be removed) can be placed last in the expansion, from which
leading and trailing whitespace will finally be removed.
Reverse solidus cannot be used as the last character of expansion.
An empty expansion will be rejected.
Contexts define when a binding applies, i.e., a binding will not be seen
unless the context for which it is defined for is currently active.
This is not true for the shared binding
`base'
,
which is the foundation for all other bindings and as such always
applies, its bindings, however, only apply secondarily.
The available contexts are the shared
`base'
,
the
`default'
context which is used in all not otherwise documented situations, and
`compose'
,
which applies only to
Sx Compose mode .
Bindings are specified as a comma-separated list of byte-sequences,
where each list entry corresponds to one
``key''
(press).
Byte sequence boundaries will be forcefully terminated after
bind-inter-byte-timeout
milliseconds, whereas key sequences can be timed out via
bind-inter-key-timeout
A list entry may, indicated by a leading colon character
`:'
,
also refer to the name of a terminal capability; several dozen names
are compiled in and may be specified either by their
terminfo(5),
or, if existing, by their
termcap(5)
name, regardless of the actually used [Option]al terminal control library.
But any capability may be used, as long as the name is resolvable by the
[Option]al control library, or was defined via the internal variable
termcap
Input sequences are not case-normalized, an exact match is required to
update or remove a binding.
It is advisable to use an initial escape or other control character (like
`\cA'
)
for user (as opposed to purely terminal capability based) bindings in
order to avoid ambiguities; it also reduces search time.
Examples:
Note that the entire comma-separated list is first parsed (over) as a
shell-token with whitespace as the field separator, then parsed and
expanded for real with comma as the field separator, therefore
whitespace needs to be properly quoted, see
Sx Shell-style argument quoting .
Using Unicode reverse solidus escape sequences renders a binding
defunctional if the locale does not support Unicode (see
Sx Character sets ) ,
and using terminal capabilities does so if no (corresponding) terminal
control support is (currently) available.
Adding, deleting or modifying a key binding invalidates the internal
prebuilt lookup tree, it will be recreated as necessary: this process
will be visualized in most
verbose
as well as in
debug
mode.
The following terminal capability names are built-in and can be used in
terminfo(5)
or (if available) the two-letter
termcap(5)
notation.
See the respective manual for a list of capabilities.
The program
infocmp(1)
can be used to show all the capabilities of
TERM
or the given terminal type;
using the
-x
flag will also show supported (non-standard) extensions.
Some terminals support key-modifier combination extensions, e.g.,
`Alt+Shift+xy'
For example, the delete key,
kdch1
in its shifted variant, the name is mutated to
kDC
then a number is appended for the states
`Alt'
( kDC3
`Shift+Alt'
( kDC4
`Control'
( kDC5
`Shift+Control'
( kDC6
`Alt+Control'
( kDC7
finally
`Shift+Alt+Control'
( kDC8
The same for the left cursor key,
kcub1
KLFT , KLFT3 , KLFT4 , KLFT5 , KLFT6 , KLFT7 , KLFT8
The latter command deletes all aliases given as arguments,
or all at once when given the asterisk
`*'
The former shows the list of all currently defined aliases if used
without arguments, or the target of the given single argument;
when given two arguments, hyphen-minus
`-'
being the first, the second is instead expanded recursively.
In all other cases the given arguments are treated as pairs of character
sets and their desired target alias name, creating new or updating
already existing aliases.
Otherwise the second argument defines the mappable slot, the third
argument a (comma-separated list of) colour and font attribute
specification(s), and the optionally supported fourth argument can be
used to specify a precondition: if conditioned mappings exist they are
tested in (creation) order unless a (case-insensitive) match has been
found, and the default mapping (if any has been established) will only
be chosen as a last resort.
The types of available preconditions depend on the mappable slot,
the following of which exist:
Mappings prefixed with
`mle-'
are used for the [Option]al built-in Mailx-Line-Editor (MLE, see
Sx On terminal control and line editor )
and do not support preconditions.
Mappings prefixed with
`sum-'
are used in header summaries, and they all understand the preconditions
`dot'
(the current message) and
`older'
for elder messages (only honoured in conjunction with
datefield-markout-older )
Mappings prefixed with
`view-'
are used when displaying messages.
The following (case-insensitive) colour definitions and font attributes
are understood, multiple of which can be specified in a comma-separated
list:
The command
uncolour
will remove for the given colour type (the special type
`*'
selects all) the given mapping; if the optional precondition argument is
given only the exact tuple of mapping and precondition is removed.
The special name
`*'
will remove all mappings (no precondition allowed), thus
`uncolour'
* *
will remove all established mappings.
With two or more arguments a command alias is defined or updated: the
first argument is the name under which the remaining command line should
be accessible, the content of which can be just about anything.
An alias may itself expand to another alias, but to avoid expansion loops
further expansion will be prevented if an alias refers to itself or if
an expansion depth limit is reached.
Explicit expansion prevention is available via reverse solidus
\
one of the
Sx Command modifiers .
A defined macro can be invoked explicitly by using the
call
call_if
and
xcall
commands, or implicitly if a macro hook is triggered, for example a
folder-hook
Execution of a macro body can be stopped from within by calling
return
Temporary macro block-scope variables can be created or deleted with the
local
command modifier in conjunction with the commands
set
and
unset
respectively.
To enforce unrolling of changes made to (global)
Sx INTERNAL VARIABLES
the command
localopts
can be used instead; its covered scope depends on how (i.e.,
``as what''
normal macro, folder hook, hook,
account
switch) the macro is invoked.
Inside a
call ed macro, the given positional parameters are implicitly local
to the macro's scope, and may be accessed via the variables
*
@
#
and
1
and any other positive unsigned decimal number less than or equal to
#
Positional parameters can be
shift ed, or become completely replaced, removed etc. via
vpospar
A helpful command for numeric computation and string evaluations is
vexpr
csop
offers C-style byte string operations.
The objects may be
remove d again by giving the same identifier used for creation;
this step could be omitted: objects will be automatically closed
when the active
folder
(mailbox) or the compose mode is left, respectively.
In all other use cases the second argument is an object identifier,
and the third and all following arguments are interpreted as via
~^
(see
Sx COMMAND ESCAPES ) :
Remarks:
this command traditionally (in BSD Mail) also performed
Sx Filename transformations ,
which is standard incompatible and hard to handle because quoting
transformation patterns is not possible; the subcommand
file-expand
of
vexpr
can be used to expand filenames.
Afterwards changing such variables with
set
will cause automatic updates of the environment, too.
Sufficient system support provided (it was in BSD as early as 1987, and
is standardized since Y2K) removing such variables with
unset
will remove them also from the environment, but in any way the knowledge
they ever have been
link ed will be lost.
This implies that
localopts
may cause loss of such links.
The subcommand
unlink
removes an existing link without otherwise touching variables, the
set
and
unset
subcommands are identical to
set
and
unset
but additionally update the program environment accordingly; removing
a variable breaks any freely established
link
When used without arguments the former shows a list of all currently
defined file hooks, with one argument the expansion of the given alias.
Otherwise three arguments are expected, the first specifying the file
extension for which the hook is meant, and the second and third defining
the load- and save commands to deal with the file type, respectively,
both of which must read from standard input and write to standard
output.
Changing hooks will not affect already opened mailboxes ([v15 behaviour may differ] except below).
[v15 behaviour may differ] For now too much work is done, and files are oftened read in twice
where once would be sufficient: this can cause problems if a filetype is
changed while such a file is opened; this was already so with the
built-in support of .gz etc. in Heirloom, and will vanish in v15.
[v15 behaviour may differ] For now all handler strings are passed to the
SHELL for evaluation purposes; in the future a
`!'
prefix to load and save commands may mean to bypass this shell instance:
placing a leading space will avoid any possible misinterpretations.
Sx Filename transformations
will be applied to the
name
argument, and
`protocol://'
prefixes are, i.e., URL (see
Sx On URL syntax and credential lookup )
syntax is understood, as in
`mbox:///tmp/somefolder'
If a protocol prefix is used the mailbox type is fixated, otherwise
opening none-existing
folders
uses the protocol defined in
newfolders
For the protocols
mbox
and
file
(MBOX database), as well as
eml
(electronic mail message [v15 behaviour may differ] read-only) the list of all registered
filetype s is traversed to check whether hooks shall be used to load (and save)
data from (and to) the given
name
Changing hooks will not affect already opened mailboxes.
For example, the following creates hooks for the
gzip(1)
compression tool and a combined compressed and encrypted format:
For historic reasons
filetype s provide limited (case-sensitive) auto-completion capabilities.
For example
`mbox.gz'
will be found for
`?'
file mbox ,
provided that corresponding handlers are installed.
It will neither find
`mbox.GZ'
nor
`mbox.Gz however,
'
but an explicit
`?'
file mbox.GZ
will find and use the handler for
`gz'
[v15 behaviour may differ] The latter mode can only be used for MBOX files.
EML files consist of only one mail message,
[v15 behaviour may differ] and can only be opened read-only.
When reading MBOX files tolerant POSIX rules are used by default.
Invalid message boundaries that can be found quite often in historic
MBOX files will be complained about (even more with
debug )
in this case the method described for
mbox-rfc4155
can be used to create a valid MBOX database from the invalid input.
MBOX databases and EML files will always be protected via file-region locks
( fcntl(2)
during file operations to protect against concurrent modifications.
[Option] An MBOX
inbox
( MAIL
or
Sx primary system mailbox
will also be protected by so-called dotlock files,
the traditional way of mail spool file locking: for any file
`x'
a lock file
`x.lock'
will be created during the synchronization, in the same directory and
with the same user and group identities as the file of interest ---
as necessary created by an external privileged dotlock helper.
dotlock-disable
disables dotlock files.
Also see
Sx FAQ :
Sx Howto handle stale dotlock files .
[Option] If no protocol has been fixated, and
name
refers to a directory with the subdirectories
`tmp'
,
`new'
and
`cur'
,
then it is treated as a folder in
``Maildir''
format.
The maildir format stores each message in its own file, and has been
designed so that file locking is not necessary when reading or writing
files.
[Option]ally URLs can be used to access network resources, securely via
Sx Encrypted network communication ,
if so supported.
Network communication socket timeouts are configurable via
socket-connect-timeout
All network traffic may be proxied over a SOCKS server via
socks-proxy
[Option]ally supported network protocols are
pop3
(POP3) and
pop3s
(POP3 with TLS encrypted transport),
imap
and
imaps
The
[/path]
part is valid only for IMAP; there it defaults to
INBOX
Network URLs require a special encoding as documented in the section
Sx On URL syntax and credential lookup .
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified, or was rejected by
expandaddr
policy,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
It can also fail with errors of
Sx Specifying messages .
Any error stops processing of further messages.
The current settings of the given context are displayed if it is the
only argument.
A second argument denotes the type of restriction that is to be chosen,
it may be (a case-insensitive prefix of)
`retain'
or
`ignore'
for white- and blacklisting purposes, respectively.
Establishing a whitelist suppresses inspection of the corresponding
blacklist.
If no further argument is given the current settings of the given type
will be displayed, otherwise the remaining arguments specify header
fields, which [Option]ally may be given as regular expressions, to be added
to the given type.
The special wildcard field (asterisk,
`*'
)
will establish a (fast) shorthand setting which covers all fields.
The latter command always takes three or more arguments and can be used
to remove selections, i.e., from the given context, the given type of
list, all the given headers will be removed, the special argument
`*'
will remove all headers.
Further (case-insensitive) one-argument conditions are
`t'
Ns
erminal which evaluates to true in interactive terminal sessions
(running with standard input or standard output attached to a terminal,
and none of the
``quickrun''
command line options
-e
-H
and
-L
have been used), as well as any boolean value (see
Sx INTERNAL VARIABLES
for textual boolean representations) to mark an enwrapped block as
``never execute''
or
``always execute''
(Remarks: condition syntax errors skip all branches until
endif .
[no v15-compat] and without
wysh
It is possible to check
Sx INTERNAL VARIABLES
as well as
Sx ENVIRONMENT
variables for existence or compare their expansion against a user given
value or another variable by using the
`$'
( ``variable next''
conditional trigger character;
a variable on the right hand side may be signalled using the same
mechanism.
Variable names may be enclosed in a pair of matching braces.
When this mode has been triggered, several operators are available
([v15-compat] and
wysh
they are always available, and there is no trigger: variables will have
been expanded by the shell-compatible parser before the
if
etc. command sees them).
[v15-compat] Two argument conditions.
Variables can be tested for existence and expansion:
`-N'
will test whether the given variable exists, so that
`-N'
editalong
will evaluate to true when
editalong
is set, whereas
`-Z'
editalong
will if it is not.
`-n'
$editalong
will be true if the variable is set and expands to a non-empty string,
`-z'
$'\$editalong'
only if the expansion is empty, whether the variable exists or not.
The remaining conditions take three arguments.
Integer operators treat the arguments on the left and right hand side of
the operator as integral numbers and compare them arithmetically.
It is an error if any of the operands is not a valid integer, an empty
argument (which implies it had been quoted) is treated as if it were 0.
Via the question mark
`?'
modifier suffix a saturated operation mode is available where numbers
will linger at the minimum or maximum possible value, instead of
overflowing (or trapping), the keyword
`saturated'
is optional,
`==?'
,
`==?satu'
and
`==?saturated'
are therefore identical.
Available operators are
`-lt'
(less than),
`-le'
(less than or equal to),
`-eq'
(equal),
`-ne'
(not equal),
`-ge'
(greater than or equal to), and
`-gt'
(greater than).
String and regular expression data operators compare the left and right
hand side according to their textual content.
Unset variables are treated as the empty string.
Via the question mark
`?'
modifier suffix a case-insensitive operation mode is available, the keyword
`case'
is optional,
`==?'
and
`==?case'
are identical.
Available string operators are
`<'
(less than),
`<='
(less than or equal to),
`=='
(equal),
`!='
(not equal),
`>='
(greater than or equal to),
`>'
(greater than),
`=%'
(is substring of) and
`!%'
(is not substring of).
By default these operators work on bytes and (therefore) do not take
into account character set specifics.
If the case-insensitivity modifier has been used, case is ignored
according to the rules of the US-ASCII encoding, i.e., bytes are
still compared.
When the [Option]al regular expression support is available, the additional
string operators
`=~'
and
`!~'
can be used.
They treat the right hand side as an extended regular expression that is
matched according to the active locale (see
Sx Character sets ) ,
i.e., character sets should be honoured correctly.
Conditions can be joined via AND-OR lists (where the AND operator is
`&&'
and the OR operator is
`||'
) ,
which have equal precedence and will be evaluated with left
associativity, thus using the same syntax that is known for the
sh(1).
It is also possible to form groups of conditions and lists by enclosing
them in pairs of brackets
`[... ] ,'
which may be interlocked within each other, and also be joined via
AND-OR lists.
The results of individual conditions and entire groups may be modified
via unary operators: the unary operator
`!'
will reverse the result.
This setting stacks up: i.e., if
`macro1'
enables change localization and calls
`macro2'
,
which explicitly resets localization, then any value changes within
`macro2'
will still be reverted when the scope of
`macro1'
is left.
(Caveats: if in this example
`macro2'
changes to a different
account
which sets some variables that are already covered by localizations,
their scope will be extended, and in fact leaving the
account
will (thus) restore settings in (likely) global scope which actually
were defined in a local, macro private context!)
This command takes one or two arguments, the optional first one
specifies an attribute that may be one of
scope
which refers to the current scope and is thus the default,
call
which causes any macro that is being
call ed to be started with localization enabled by default, as well as
call-fixate
which (if enabled) disallows any called macro to turn off localization:
like this it can be ensured that once the current scope regains control,
any changes made in deeper levels have been reverted.
The latter two are mutually exclusive, and neither affects
xcall
The (second) argument is interpreted as a boolean (string, see
Sx INTERNAL VARIABLES )
and states whether the given attribute shall be turned on or off.
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified,
^ERR -PERM
if some addressees where rejected by
expandaddr
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
It can also fail with errors of
Sx Specifying messages .
Occurrence of some of the errors depend on the value of
expandaddr
Any error stops processing of further messages.
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified,
^ERR -PERM
if some addressees where rejected by
expandaddr
^ERR -NOTSUP
if multiple messages have been specified,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
It can also fail with errors of
Sx Specifying messages .
Occurrence of some of the errors depend on the value of
expandaddr
The latter command deletes all specifications of the given MIME type, thus
`?'
unmimetype text/plain
will remove all registered specifications for the MIME type
`text/plain'
The special name
`*'
will discard all existing MIME types, just as will
`reset'
,
but which also reenables cache initialization via
mimetypes-load-control
The channel name is expected to be a file descriptor number, or,
if parsing the numeric fails, an input file name that undergoes
Sx Filename transformations .
For example (this example requires a modern shell):
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified, or was rejected by
expandaddr
policy,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
It can also fail with errors of
Sx Specifying messages .
Any error stops processing of further messages.
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified, or was rejected by
expandaddr
policy,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
It can also fail with errors of
Sx Specifying messages .
Any error stops processing of further messages.
Otherwise the given variables (and arguments) are set or adjusted.
Arguments are of the form
`name=value'
(no space before or after
`='
) ,
or plain
`name'
if there is no value, i.e., a boolean variable.
If a name begins with
`no'
,
as in
`set'
nosave ,
the effect is the same as invoking the
unset
command with the remaining part of the variable
( `unset'
save ).
[v15 behaviour may differ] In conjunction with the
wysh
(or local
command prefix(es)
Sx Shell-style argument quoting
can be used to quote arguments as necessary.
[v15 behaviour may differ] Otherwise quotation marks may be placed around any part of the
assignment statement to quote blanks or tabs.
When operating in global scope any
`name'
that is known to map to an environment variable will automatically cause
updates in the program environment (unsetting a variable in the
environment requires corresponding system support) --- use the command
environ
for further environmental control.
If the command modifier
local
has been used to enforce local scoping then the given user variables
will be garbage collected when the local scope is left;
for
Sx INTERNAL VARIABLES ,
however,
local
behaves the same as if
localopts
would have been set (temporarily), which means that changes are
inherited by deeper scopes.
Also see
varshow
and the sections
Sx INTERNAL VARIABLES
and
Sx ENVIRONMENT .
Supports
vput
(see
Sx Command modifiers ) ,
and manages the error number
!
If the coding operation fails the error number
!
is set to
^ERR -CANCELED
and the unmodified input is used as the result; the error number may
change again due to output or result storage errors.
[v15 behaviour may differ] This command does not know about URLs beside what is documented.
( vexpr
offers a
makeprint
subcommand, shall the URL be displayed.)
Numeric operations work on one or two signed 64-bit integers.
Numbers prefixed with
`0x'
or
`0X'
are interpreted as hexadecimal (base 16) numbers, whereas
`0'
indicates octal (base 8), and
`0b'
as well as
`0B'
denote binary (base 2) numbers.
It is possible to use any base in between 2 and 36, inclusive, with the
`BASE#number'
notation, where the base is given as an unsigned decimal number, so
`16#AFFE'
is a different way of specifying a hexadecimal number.
Unsigned interpretation of a number can be enforced by prefixing an
`u'
(case-insensitively), as in
`u-110'
;
this is not necessary for power-of-two bases (2, 4, 8, 16 and 32),
which will be interpreted as unsigned by default, but it still makes
a difference regarding overflow detection and overflow constant.
It is possible to enforce signed interpretation by (instead) prefixing a
`s'
(case-insensitively).
The number sign notation uses a permissive parse mode and as such
supports complicated conditions out of the box:
One integer is expected by assignment (equals sign
`='
) ,
which does nothing but parsing the argument, thus detecting validity and
possible overflow conditions, unary not (tilde
`~'
) ,
which creates the bitwise complement, and unary plus and minus.
Two integers are used by addition (plus sign
`+'
) ,
subtraction (hyphen-minus
`-'
) ,
multiplication (asterisk
`*'
) ,
division (solidus
`/'
)
and modulo (percent sign
`%'
) ,
as well as for the bitwise operators logical or (vertical bar
`|'
,
to be quoted) ,
bitwise and (ampersand
`&'
,
to be quoted) ,
bitwise xor (circumflex
`^'
) ,
the bitwise signed left- and right shifts
( `<<'
`>>'
) ,
as well as for the unsigned right shift
`>>>'
Another numeric operation is
pbase
which takes a number base in between 2 and 36, inclusive, and will act
on the second number given just the same as what equals sign
`='
does, but the number result will be formatted in the base given, as
a signed 64-bit number unless unsigned interpretation of the input
number had been forced (with an u prefix).
Numeric operations support a saturated mode via the question mark
`?'
modifier suffix; the keyword
`saturated'
is optional,
`+?'
,
`+?satu'
,
and
`+?saturated'
are therefore identical.
In saturated mode overflow errors and division and modulo by zero are no
longer reported via the exit status, but the result will linger at the
minimum or maximum possible value, instead of overflowing (or trapping).
This is true also for the argument parse step.
For the bitwise shifts, the saturated maximum is 63.
Any caught overflow will be reported via the error number
!
as
^ERR -OVERFLOW
Character set agnostic string functions have no notion of locale
settings and character sets.
String operations work, sufficient support provided, according to the
active user's locale encoding and character set (see
Sx Character sets ) .
Where the question mark
`?'
modifier suffix is supported, a case-insensitive operation mode is
available; the keyword
`case'
is optional,
`regex?'
and
`regex?case'
are therefore identical.
If the first argument is
`quote'
,
a round-trip capable representation of the stack contents is created,
with each quoted parameter separated from each other with the first
character of
ifs
and followed by the first character of
if-ws
if that is not empty and not identical to the first.
If that results in no separation at all a
space
character is used.
This mode supports
vput
(see
Sx Command modifiers ) .
I.e., the subcommands
`set'
and
`quote'
can be used (in conjunction with
eval
to (re)create an argument stack from and to a single variable losslessly.
In interactive mode the user is consecutively asked for the filenames of
the processed parts.
For convenience saving of each part may be skipped by giving an empty
value, the same result as writing it to
/dev/null
Shell piping the part content by specifying a leading vertical bar
`|'
character for the filename is supported.
Other user input undergoes the usual
Sx Filename transformations ,
including shell pathname wildcard pattern expansions
( glob(7)
and shell variable expansion for the message as such, not the individual
parts, and contents of the destination file are overwritten if the file
previously existed.
Character set conversion to
ttycharset
is performed when saving text data.
[v15 behaviour may differ] In non-interactive mode any part which does not specify a filename
is ignored, and suspicious parts of filenames of the remaining parts are
URL percent encoded (as via
urlcodec
to prevent injection of malicious character sequences, resulting in
a filename that will be written into the current directory.
Existing files will not be overwritten, instead the part number or
a dot are appended after a number sign
`#'
to the name until file creation succeeds (or fails due to other
reasons).
Unless otherwise documented command escapes ensure proper updates of
the error number
!
and the exit status
?
The variable
errexit
controls whether a failed operation errors out message compose mode and
causes program exit.
Escapes may be prefixed by none to multiple single character command
modifiers, interspersed whitespace is ignored:
Addition of the command line to the [Option]al history can be prevented by
placing whitespace directly after
escape
The [Option]al key
bind ings support a compose mode specific context.
The following command escapes are supported:
Without
filename
arguments the attachment list is edited, entry by entry;
if a filename is left empty, that attachment is deleted from the list;
once the end of the list is reached either new attachments may be
entered or the session can be quit by committing an empty
``new''
attachment.
In non-interactive mode or in batch mode
( -#
the list of attachments is effectively not edited but instead recreated;
again, an empty input ends list creation.
For all modes, if a given filename solely consists of the number sign
`#'
followed by either a valid message number of the currently active
mailbox, or by a period
`.'
,
referring to the current message of the active mailbox, the so-called
``dot''
then the given message is attached as a
`message/rfc822'
MIME message part.
The number sign must be quoted to avoid misinterpretation as a shell
comment character.
If the first character of the command is a vertical bar, then the entire
message including header fields is subject to the filter command, so
`~||'
echo Fcc: /tmp/test; cat
will prepend a file-carbon-copy message header.
Also see
~e , ~v
The protocol consists of command lines followed by (a) response line(s).
The first field of the response line represents a status code
which specifies whether a command was successful or not, whether result
data is to be expected, and if, the format of the result data.
Response data will be shell quoted as necessary for consumption by
readsh
or
eval
and
vpospar
to name a few.
Error status code lines may optionally contain additional context:
If a command indicates failure then the message will have remained
unmodified.
Most commands can fail with
`500'
if required arguments are missing, or excessive arguments have been
given (false command usage).
([v15 behaviour may differ] The latter does not yet occur regularly, because as stated in
Sx Shell-style argument quoting
our argument parser is not yet smart enough to work on subcommand base;
for example one might get excess argument error for a three argument
subcommand that receives four arguments, but not for a four argument
subcommand which receives six arguments: here excess will be joined.)
The following (case-insensitive) commands are supported:
It returns via
`210'
upon success, with the index of the found attachment following,
`505'
for message attachments or if the given keyword is invalid, and
`501'
if no such attachment can be found.
The following keywords may be used (case-insensitively):
If no path component exists in the given argument, then all attachments
will be searched for
`filename='
parameter matches as well as for matches of the basename of the path
which has been used when the attachment has been created; multiple
matches result in a
`506'
`210'
is returned upon success, followed by the name of the header and the list
position of the newly inserted instance.
The list position is always 1 for single-instance header fields.
All free-form header fields are managed in a single list; also see
customhdr
In compose-mode read-only access to optional pseudo headers in the S-nail
private namespace is available:
Two different kinds of internal variables exist, and both of which can
also form chains.
There are boolean variables, which can only be in one of the two states
``set''
and
``unset''
and value variables with a(n optional) string value.
For the latter proper quoting is necessary upon assignment time, the
introduction of the section
Sx COMMANDS
documents the supported quoting rules.
Dependent upon the actual option string values may become interpreted as
colour names, command specifications, normal text, etc.
They may be treated as numbers, in which case decimal values are
expected if so documented, but otherwise any numeric format and
base that is valid and understood by the
vexpr
command may be used, too.
There also exists a special kind of string value, the
``boolean string''
which must either be a decimal integer (in which case
`0'
is false and
`1'
and any other value is true) or any of the (case-insensitive) strings
`off'
,
`no'
,
`n'
and
`false'
for a false boolean and
`on'
,
`yes'
,
`y'
and
`true'
for a true boolean;
a special kind of boolean string is the
``quadoption''
it can optionally be prefixed with the (case-insensitive) term
`ask-'
,
as in
`ask-yes'
;
in interactive mode the user will be prompted, otherwise the actual
boolean is used.
Variable chains extend a plain
`variable'
with
`variable-HOST'
and
`variable-USER [at] HOST'
variants.
Here
`HOST'
will be converted to all lowercase when looked up (but not when the
variable is set or unset!), [Option]ally IDNA converted, and indeed means
`server:port'
if a
`port'
had been specified in the contextual Uniform Resource Locator URL, see
Sx On URL syntax and credential lookup .
Even though this mechanism is based on URLs no URL percent encoding may
be applied to neither of
`USER'
nor
`HOST'
,
variable chains need to be specified using raw data;
the mentioned section contains examples.
Variables which support chains are explicitly documented as such, and
S-nail treats the base name of any such variable special, meaning that
users should not create custom names like
`variable-xyz'
in order to avoid false classifications and treatment of such variables.
However, S-nail has built-in some initial (and some default) settings
which (may) diverge, others may become adjusted by one of the
Sx Resource files .
Displaying the former is accomplished via
set
`$'
s-nail -:/ -v -Xset -Xx .
In general this implementation sets (and has extended the meaning of)
sendwait
and does not support the
no onehop
variable - use command line options or
mta-arguments
to pass options through to a
mta
The default global resource file sets, among others, the variables
hold
keep
and
keepsave
establishes a default
headerpick
selection etc., and should thus be taken into account.
This variable will also be taken into account if a MIME type (see
Sx The mime.types files )
of a MIME message part that uses the
`binary'
character set is forcefully treated as text.
Recipient types can be added and removed with a plus sign
`+'
or hyphen-minus
`-'
prefix, respectively.
By default invalid or disallowed types are filtered out and
cause a warning, hard send errors need to be enforced by including
`fail'
The value
`all'
covers all types,
`fcc'
whitelists
`Fcc:'
header targets regardless of other settings,
`file'
file targets (it includes
`fcc'
) ,
`pipe'
command pipeline targets,
`name'
user names still unexpanded after
alias
and
mta-aliases
processing and thus left for expansion by the
mta
(invalid for the built-in SMTP one), and
`addr'
network addresses.
Targets are interpreted in the given order, so that
`restrict,fail,+file,-all,+addr'
will cause hard errors for any non-network address recipient address
unless running interactively or having been started with the option
-~
or
-#
in the latter case(s) any type may be used.
User name receivers addressing valid local users can be expanded to
fully qualified network addresses (also see
hostname
by including
`nametoaddr'
in the list.
Historically invalid recipients were stripped off without causing
errors, this can be changed by making
`failinvaddr'
an entry of the list (it really acts like
`failinvaddr,+addr'
) .
Likewise,
`domaincheck'
(really `domaincheck,+addr'
compares address domain names against a whitelist and strips off
( `fail'
for hard errors) addressees which fail this test; the domain name
`localhost'
and the non-empty value of
hostname
(the real hostname otherwise) are always whitelisted,
expandaddr-domaincheck
can be set to extend this list.
Finally some address providers (for example
-b , c
and all other command line recipients) will be evaluated as
if specified within dollar-single-quotes (see
Sx Shell-style argument quoting )
if the value list contains the string
`shquote'
The specialized form will override the generic one if
`FOLDER'
matches the file that is opened.
Unlike other folder specifications, the fully expanded name of a folder,
without metacharacters, is used to avoid ambiguities.
However, if the mailbox resides under
folder
then the usual
`+'
specification is tried in addition, so that if
folder
is
``mail''
(and thus relative to the user's home directory) then
/home/usr1/mail/sent
will be tried as
`folder-hook-/home/usr1/mail/sent'
first, but then followed by
`folder-hook-+sent'
If a file-based MTA is used, then
from
(or, if that contains multiple addresses,
sender
can nonetheless be used as the envelope sender address at the MTA
protocol level (the RFC 5321 reverse-path), either via the
-r
command line option (without argument; see there for more), or by setting
r-option-implicit
If the machine's hostname is not valid at the Internet (for example at
a dialup machine), then either this variable or
hostname
([v15-compat] a SMTP-based
mta
adds even more fine-tuning capabilities with
smtp-hostname
have to be set: if so the message and MIME part related unique ID fields
`Message-ID:'
and
`Content-ID:'
will be created (except when disallowed by
message-id-disable
or
stealthmua )
The default is
`%>%a%m%-18f %16d %4l/%-5o %i%-s ,'
or
`%>%a%m%20-f
In general setting this variable will cause S-nail to encapsulate text
fields that may occur when displaying
headline
(and some other fields, like dynamic expansions in
prompt
with special Unicode control sequences;
it is possible to fine-tune the terminal support level by assigning
a value:
no value (or any value other than
`1'
,
`2'
and
`3'
)
will make S-nail assume that the terminal is capable to properly deal
with Unicode version 6.3, in which case text is embedded in a pair of
U+2068 (FIRST STRONG ISOLATE) and U+2069 (POP DIRECTIONAL ISOLATE)
characters.
In addition no space on the line is reserved for these characters.
Weaker support is chosen by using the value
`1'
(Unicode 6.3, but reserve the room of two spaces for writing the control
sequences onto the line).
The values
`2'
and
`3'
select Unicode 1.1 support (U+200E, LEFT-TO-RIGHT MARK); the latter
again reserves room for two spaces in addition.
Setting it to the empty string will cause the normal hostname to be
used, but nonetheless enables creation of said ID fields.
[v15-compat] in conjunction with the built-in SMTP
mta
smtp-hostname
also influences the results:
one should produce some test messages with the desired combination of
hostname
and/or
from
sender
etc. first.
This may temporarily be handy when S-nail complains about invalid
`From_'
lines when opening a MBOX: in this case setting this variable and
re-opening the mailbox in question may correct the result.
If so, copying the entire mailbox to some other file, as in
`copy'
* SOME-FILE ,
will perform proper, all-compatible
`From_'
quoting for all detected messages, resulting in a valid MBOX mailbox.
([v15 behaviour may differ] The better and non-destructive approach is to re-encode invalid
messages, as if it would be created anew, instead of mangling the
`From_'
lines; this requires the structural code changes of the v15 rewrite.)
Finally the variable can be unset again:
This classification however treats text files which are encoded in
UTF-16 (seen for HTML files) and similar character sets as binary
octet-streams, forcefully changing any
`text/plain'
or
`text/html'
specification to
`application/octet-stream'
:
If that actually happens a yet unset charset MIME parameter is set to
`binary'
,
effectively making it impossible for the receiving MUA to automatically
interpret the contents of the part.
If this variable is set, and the data was unambiguously identified as
text data at first glance (by a
`.txt'
or
`.html'
file extension), then the original
`Content-Type:'
will not be overwritten.
More sources can be specified by using a different syntax: if the
value string contains an equals sign
`='
then it is instead parsed as a comma-separated list of the described
letters plus
`f=FILENAME'
pairs; the given filenames will be expanded and loaded, and their
content may use the extended syntax that is described in the section
Sx The mime.types files .
Directives found in such files always take precedence (are prepended to
the MIME type cache).
([no v15-compat]:
`[smtp://]server[:port]'
The default has been chosen at compile time.
MTA data transfers are always performed in asynchronous child processes,
and without supervision unless either the
sendwait
or the
verbose
variable is set.
Also see
mta-bcc-ok
[Option]ally expansion of
aliases(5)
can be performed by setting
mta-aliases
For testing purposes there is the
`test'
pseudo-MTA, which dumps to standard output or optionally to a file,
and honours
mbox-fcc-and-pcc
For a file-based MTA it may be necessary to set
mta-argv0
in in order to choose the right target of a modern
mailwrapper(8)
environment.
It will be passed command line arguments from several possible sources:
from the variable
mta-arguments
if set, from the command line if given and the variable
expandargv
allows their use.
Argument processing of the MTA will be terminated with a
--
separator.
The otherwise occurring implicit usage of the following MTA command
line arguments can be disabled by setting the boolean variable
mta-no-default-arguments
(which will also disable passing
--
to the MTA):
-i
(for not treating a line with only a dot
`.'
character as the end of input),
-m
(shall the variable
metoo
be set) and
-v
(if the
verbose
variable is set); in conjunction with the
-r
command line option or
r-option-implicit
-f
as well as possibly
-F
will (not) be passed.
[Option]ally S-nail can send mail over SMTP aka SUBMISSION network
connections to a single defined smart host by setting this variable to
a SMTP or SUBMISSION URL (see
Sx On URL syntax and credential lookup ) .
An authentication scheme can be specified via the variable chain
smtp-auth
Encrypted network connections are [Option]ally available, the section
Sx Encrypted network communication
should give an overview and provide links to more information on this.
Note that with some mail providers it may be necessary to set the
smtp-hostname
variable in order to use a specific combination of
from
hostname
and
mta
Network communication socket timeouts are configurable via
socket-connect-timeout
All generated network traffic may be proxied over a SOCKS
socks-proxy
it can be logged by setting
verbose
twice.
The following SMTP variants may be used:
SMTPS is nonetheless a commonly offered protocol and thus can be
chosen by assigning a value like [v15-compat]
`smtps://[user[:password]@]server[:port]'
([no v15-compat]
`smtps://server[:port]'
) ;
due to the mentioned problems it is usually necessary to explicitly
specify the port as
`:465'
,
however.
For compose mode hooks that may affect the message content please see
on-compose-enter , on-compose-leave , on-compose-splice
[v15 behaviour may differ] This hook exists because
alias , alternates , commandalias , shortcut
to name a few, are neither covered by
localopts
nor by
local
changes applied in compose mode will continue to be in effect thereafter.
Here is an example that injects a signature via
message-inject-tail
instead using
on-compose-splice
to simply inject the file of desire via
~<
or
~<!
may be a better approach.
During execution of these hooks S-nail will temporarily forget whether it
has been started in interactive mode, (a restricted set of)
Sx COMMAND ESCAPES
will always be available, and for guaranteed reproducibilities sake
escape
and
ifs
will be set to their defaults.
The compose mode command
~^
has been especially designed for scriptability (via these hooks).
The first line the hook will read on its standard input is the protocol
version of said command escape, currently
``0 0 2''
backward incompatible protocol changes have to be expected.
Care must be taken to avoid deadlocks and other false control flow:
if both involved processes wait for more input to happen at the
same time, or one does not expect more input but the other is stuck
waiting for consumption of its output, etc.
There is no automatic synchronization of the hook: it will not be
stopped automatically just because it, e.g., emits
`~x'
The hooks will however receive a termination signal if the parent enters
an error condition.
[v15 behaviour may differ] Protection against and interaction with signals is not yet given;
it is likely that in the future these scripts will be placed in an
isolated session, which is signalled in its entirety as necessary.
The special value question mark
`?'
forces interpretation of the message part as plain text, for example
`set'
pipe-application/xml=? .
(This can also be achieved by adding a MIME type-marker via
mimetype .
[Option]ally MIME type handlers may be defined via
Sx The Mailcap files
to which should be referred to for documentation of flags like
copiousoutput
Question mark is indeed a trigger character to indicate flags that
adjust behaviour and usage of the rest of the value, the shell command,
for example:
Some information about the MIME part to be displayed is embedded into
the environment of the shell command:
In order to embed characters which should not be counted when
calculating the visual width of the resulting string, enclose the
characters of interest in a pair of reverse solidus escaped brackets:
`\[\E[0m\]'
;
a slot for coloured prompts is also available with the [Option]al command
colour
Prompting may be prevented by setting this to the null string
(aka
`set'
noprompt ) .
The 8-bit fallback
charset-8bit
never comes into play as
ttycharset
is implicitly assumed to be 8-bit and capable to represent all files the
user may specify (as is the case when no character set conversion
support is available in S-nail and the only supported character set is
ttycharset
see
Sx Character sets ) .
This might be a problem for scripts which use the suggested
`LC_ALL=C'
setting, since in this case the character set is US-ASCII by definition,
so that it is better to also override
ttycharset
then; and/or do something like the following in the resource file:
If this variable is set then child program exit is waited for, and its
exit status code is used to decide about success.
Remarks: in conflict with the POSIX standard this variable is built-in
to be initially set.
Another difference is that it can have a value, which is interpreted as
a comma-separated list of case-insensitive strings naming specific
subsystems for which synchronousness shall be ensured (only).
Possible values are
`mta'
for
mta
delivery, and
`pcc'
for command-pipe receivers.
The actually available cipher algorithms depend on the cryptographic
library that S-nail uses.
[Option] Support for more cipher algorithms may be available through
dynamic loading via
EVP_get_cipherbyname3
(OpenSSL) if S-nail has been compiled to support this.
If a message is sent to multiple recipients,
each of them for whom a corresponding variable is set will receive an
individually encrypted message;
other recipients will continue to receive the message in plain text
unless the
smime-force-encryption
variable is set.
It is recommended to sign encrypted messages, i.e., to also set the
smime-sign
variable.
content-description-smime-message
will be inspected for messages which become encrypted.
For message signing
`USER [at] HOST'
is always derived from the value of
from
(or, if that contains multiple addresses,
sender )
For the purpose of encryption the recipients public encryption key
(certificate) is expected; the command
certsave
can be used to save certificates of signed messages (the section
Sx Signed and encrypted messages with S/MIME
gives some details).
This mode of operation is usually driven by the specialized form.
When decrypting messages the account is derived from the recipient
fields
( `To:'
and
`Cc:'
)
of the message, which are searched for addresses for which such
a variable is set.
S-nail always uses the first address that matches,
so if the same message is sent to more than one of the user addresses
using different encryption keys, decryption might fail.
Password-encrypted keys may be used for signing and decryption.
Automated password lookup is possible via the
``pseudo-hosts''
`USER [at] HOST.smime-cert-key'
for the private key, and
`USER [at] HOST.smime-cert-cert'
for the certificate stored in the same file.
For example, the hypothetical address
`bob [at] exam.ple'
could be driven with a private key / certificate pair path defined in
smime-sign-cert-bob [at] exam.ple
and the needed passwords would then be looked up as
`bob [at] exam.ple.smime-cert-key'
and
`bob [at] exam.ple.smime-cert-cert'
When decrypting the value of
from
will be tried as a fallback to provide the necessary
`USER [at] HOST'
To include intermediate certificates, use
smime-sign-include-certs
The possible password sources are documented in
Sx On URL syntax and credential lookup .
S-nail will try to add built-in support for the following message
digests, names are case-insensitive:
`BLAKE2b512'
,
`BLAKE2s256'
,
`SHA3-512'
,
`SHA3-384'
,
`SHA3-256'
,
`SHA3-224'
,
as well as the widely available
`SHA512'
,
`SHA384'
,
`SHA256'
,
`SHA224'
,
and the proposed insecure
`SHA1'
,
finally
`MD5'
More digests may [Option]ally be available through dynamic loading via the
OpenSSL function
EVP_get_digestbyname3.
For the purpose of the mechanisms involved here,
`USER [at] HOST'
refers to the content of the internal variable
from
(or, if that contains multiple addresses,
sender )
The pseudo-host
`USER [at] HOST.smime-include-certs'
will be used for performing password lookups for these certificates,
shall they have been given one, therefore the lookup can be automated
via the mechanisms described in
Sx On URL syntax and credential lookup .
String capabilities form
`cap=value'
pairs and are expected unless noted otherwise.
Numerics have to be notated as
`cap#number'
where the number is expected in normal decimal notation.
Finally, booleans do not have any value but indicate a true or false
state simply by being defined or not; this indeed means that S-nail
does not support undefining an existing boolean.
String capability values will undergo some expansions before use:
for one notations like
`^LETTER'
stand for
`control-LETTER'
,
and for clarification purposes
`\E'
can be used to specify
`escape'
(the control notation
`^['
could lead to misreadings when a left bracket follows, which it does for
the standard CSI sequence);
finally three letter octal sequences, as in
`\061'
,
are supported.
To specify that a terminal supports 256-colours, and to define sequences
that home the cursor and produce an audible bell, one might write:
The following terminal capabilities are or may be meaningful for the
operation of the built-in line editor or S-nail in general:
Many more capabilities which describe key-sequences are documented for
bind
Currently known features are
`conf-ctx'
( tls-config-pairs
`ctx-config'
( tls-config-module
`ctx-set-ciphersuites'
( Ciphersuites
slot of
tls-config-pairs )
`ctx-set-maxmin-proto'
( tls-config-pairs
`modules-load-file'
( tls-config-file
and
`tls-rand-file'
( tls-rand-file
In order to integrate other environment variables equally they need to
be imported (linked) with the command
environ
This command can also be used to set and unset non-integrated
environment variables from scratch, sufficient system support provided.
The following example, applicable to a POSIX shell, sets the
COLUMNS
environment variable for S-nail only, and beforehand exports the
EDITOR
in order to affect any further processing in the running shell:
S-nail inspects the contents of this variable: if its contains the string
``less''
then a non-existing environment variable
LESS
will be set to (the portable)
`RI'
,
likewise for
``lv''
LV
will optionally be set to
`-c'
Also see
colour-pager
The content of these files is interpreted as follows:
Errors while loading these files are subject to the settings of
errexit
and
posix
More files with syntactically equal content can be
source ed
The following, saved in a file, would be an examplary content:
where
`type/subtype'
define the MIME media type, as standardized in RFC 2046:
`type'
is used to declare the general type of data, while the
`subtype'
specifies a specific format for that type of data.
One or multiple filename
`extension'
Ns
s, separated by whitespace, can be bound to the media type format.
Comments may be introduced anywhere on a line with a number sign
`#'
,
causing the remaining line to be discarded.
S-nail also supports an extended, non-portable syntax in especially
crafted files, which can be loaded via the alternative value syntax of
mimetypes-load-control
and prepends an optional
`type-marker'
:
The following type markers are supported:
Further reading:
for sending messages:
mimetype
mime-allow-text-controls
mimetypes-load-control
For reading etc. messages:
Sx HTML mail and MIME attachments ,
Sx The Mailcap files ,
mimetype
mime-counter-evidence
mimetypes-load-control
pipe-TYPE/SUBTYPE
pipe-EXTENSION
``Mailcap''
files consist of a set of newline separated entries.
Comment lines start with a number sign
`#'
(in the first column!) and are ignored.
Empty lines are ignored.
All other lines are interpreted as mailcap entries.
An entry definition may be split over multiple lines by placing the
reverse solidus character
`\'
last in all but the final line.
The standard does not specify how leading whitespace of successive lines
is to be treated, therefore they are retained.
``Mailcap''
entries consist of a number of semicolon
`;'
separated fields.
The first two fields are mandatory and must occur in the specified
order, the remaining fields are optional and may appear in any order.
Leading and trailing whitespace of field content is ignored (removed).
The reverse solidus
`\'
character can be used to escape any following character including
semicolon and itself in the content of the second field, and in value
parts of any optional key/value field.
The first field defines the MIME
`TYPE/SUBTYPE'
the entry is about to handle (case-insensitively).
If the subtype is specified as an asterisk
`*'
the entry is meant to match all subtypes of the named type, e.g.,
`audio/*'
would match any audio type.
The second field is the
view
shell command used to display MIME parts of the given type.
Data consuming shell commands will be fed message (MIME part) data on
standard input unless one or more instances of the (unquoted) string
`%s'
are used: these formats will be replaced with a temporary file(name)
that has been prefilled with the parts data.
Data producing shell commands are expected to generata data on their
standard output unless that format is used.
In all cases any given
`%s'
format is replaced with a properly shell quoted filename.
When a command requests a temporary file via
`%s'
then that will be removed again, as if the
x-mailx-tmpfile
and
x-mailx-tmpfile-fill
flags had been set; unless the command requests
x-mailx-async
the
x-mailx-tmpfile-unlink
flag is also implied; see below for more.
Optional fields define single-word flags (case-insensitive), or key
/ value pairs consisting of a case-insensitive keyword, an equals sign
`='
,
and a shell command; whitespace surrounding the equals sign is removed.
Optional fields include the following:
The standard includes the possibility to define any number of additional
fields, prefixed by
`x-'
Flag fields apply to the entire
``Mailcap''
entry --- in some unusual cases, this may not be desirable, but
differentiation can be accomplished via separate entries, taking
advantage of the fact that subsequent entries are searched if an earlier
one does not provide enough information.
For example, if a
view
command needs to specify the
needsterminal
flag, but the
compose
command shall not, the following will help out the latter:
In value parts of command fields any occurrence of the format string
`%t'
will be replaced by the
`TYPE/SUBTYPE'
specification.
Any named parameter from a messages'
`Content-type:'
field may be embedded into the command line using the format
`%{'
followed by the parameter name and a closing brace
`}'
character.
The entire parameter should appear as a single command line argument,
regardless of embedded spaces, shell quoting will be performed by the
RFC 1524 processor, thus:
Note that S-nail does not support handlers for multipart MIME parts as
shown in this example (as of today).
It does not support the additional formats
`%n'
and
`%F'
An example file, also showing how to properly deal with the expansion of
`%s'
,
which includes any quotes that are necessary to make it a valid shell
argument by itself and thus will cause undesired behaviour when placed
in additional user-provided quotes:
Further reading:
Sx HTML mail and MIME attachments ,
Sx The mime.types files ,
mimetype
MAILCAPS
mime-counter-evidence
pipe-TYPE/SUBTYPE
pipe-EXTENSION
The file consists of space, tabulator or newline separated tokens.
This parser implements a superset of the original BSD syntax, but users
should nonetheless be aware of portability glitches, shall their
.netrc
be usable across multiple programs and platforms:
Of the following list of supported tokens this parser uses (and caches)
machine
login
and
password
An existing
default
entry will not be used.
As an extension that should not be the cause of any worries this parser
supports a single wildcard prefix for
name
which would match
`xy.example.com'
as well as
`pop3.example.com'
,
but neither
`example.com'
nor
`local.smtp.example.com'
In the example neither
`pop3.example.com'
nor
`smtp.example.com'
will be matched by the wildcard, since the exact matches take
precedence (it is however faster to specify it the other way around).
When storing passwords in
~/.mailrc
appropriate permissions should be set on this file with
`$'
chmod 0600 ~/.mailrc .
If the [Option]al
netrc-lookup
is available user credentials can be stored in the central
~/.netrc
file instead; e.g., here is a different version of the example account
that sets up SMTP and POP3:
and, in the
~/.netrc
file:
This configuration should now work just fine:
For personal use it is recommended to get a S/MIME certificate from
one of the major CAs on the Internet.
Many CAs offer such certificates for free.
Usually offered is a combined certificate and private key in PKCS#12
format which S-nail does not accept directly.
To convert it to PEM format, the following shell command can be used;
please read on for how to use these PEM files.
There is also
Lk https://www.CAcert.org
which issues client and server certificates to members of their
community for free; their root certificate
( Lk https://www.cacert.org/certs/root.crt
is often not in the default set of trusted CA root certificates, though,
which means their root certificate has to be downloaded separately,
and needs to be part of the S/MIME certificate validation chain by
including it in
smime-ca-dir
or as a vivid member of the
smime-ca-file
But let us take a step-by-step tour on how to setup S/MIME with
a certificate from CAcert.org despite this situation!
First of all you will have to become a member of the CAcert.org
community, simply by registrating yourself via the web interface.
Once you are, create and verify all email addresses you want to be able
to create signed and encrypted messages for/with using the corresponding
entries of the web interface.
Now ready to create S/MIME certificates, so let us create a new
``client certificate''
ensure to include all email addresses that should be covered by the
certificate in the following web form, and also to use your name as the
``common name''
Create a private key and a certificate request on your local computer
(please see the manual pages of the used commands for more in-depth
knowledge on what the used arguments etc. do):
Afterwards copy-and-paste the content of
``creq.pem''
into the certificate-request (CSR) field of the web form on the
CAcert.org website (you may need to unfold some
``advanced options''
to see the corresponding text field).
This last step will ensure that your private key (which never left your
box) and the certificate belong together (through the public key that
will find its way into the certificate via the certificate-request).
You are now ready and can create your CAcert certified certificate.
Download and store or copy-and-paste it as
``pub.crt''
Yay.
In order to use your new S/MIME setup a combined private key/public key
(certificate) file has to be created:
This is the file S-nail will work with.
If you have created your private key with a passphrase then S-nail will
ask you for it whenever a message is signed or decrypted, unless this
operation has been automated as described in
Sx Signed and encrypted messages with S/MIME .
Set the following variables to henceforth use S/MIME (setting
smime-ca-file
is of interest for verification only):
S-nail accepts CRLs in PEM format only;
CRLs in DER format must be converted, like, e.g.:
To tell S-nail about the CRLs, a directory that contains all CRL files
(and no other files) must be created.
The
smime-crl-dir
or
tls-crl-dir
variables, respectively, must then be set to point to that directory.
After that, S-nail requires a CRL to be present for each CA that is used
to verify a certificate.
Different to Kerberos / GSSAPI, which is developed since the mid of the
1980s, where a user can easily create a local authentication ticket for
her- and himself with the locally installed
kinit(1)
program, that protocol has no such local part but instead requires
a world-wide-web query to create or fetch a token; since there is no
local cache this query would have to be performed whenever S-nail is
invoked (in interactive sessions situation may differ).
S-nail does not directly support OAuth.
It, however, supports XOAUTH2 / OAUTHBEARER, see
Sx But, how about XOAUTH2 / OAUTHBEARER?
If that is not used it is necessary to declare S-nail a
``less secure app''
(on the providers account web page) in order to read and send mail.
However, it also seems possible to take the following steps instead:
Some hurdles must be taken before being able to use this method.
Using GMail as an example, an application (that is a name) must be
registered, for which credentials, a
``client ID''
and a
``client secret''
need to be created and saved locally (in a secure way).
These initial configuration steps can be performed at
Lk https://console.developers.google.com/apis/credentials .
Thereafter a refresh token can be requested;
a python program to do this for GMail accounts is
Lk https://github.com/google/gmail-oauth2-tools/raw/master/python/oauth2.py :
The generated refresh token must also be saved locally (securely).
The procedure as a whole can be read at
Lk https://github.com/google/gmail-oauth2-tools/wiki/OAuth2DotPyRunThrough .
Since periodic timers are not yet supported, keeping an access token
up-to-date (from within S-nail) can only be performed via the hook
on-main-loop-tick
or (for sending only)
on-compose-enter
(for more on authentication please see the section
Sx On URL syntax and credential lookup ) :
Or second, terminal libraries (see
Sx On terminal control and line editor,
bind
termcap
may report different codes than the terminal really sends, rendering
bindings dysfunctional because expected and received data do not match; the
verbose
listing of
bind ings will show the byte sequences that are expected.
(One common source of problems is that the --- possibly even
non-existing --- keypad is not turned on, and the resulting layout
reports the keypad control codes for the normal keyboard keys.)
To overcome the situation use for example the program
cat(1)
with its option
-v
if available, to see the byte sequences which are actually produced
by keypresses, and use the variable
termcap
to make S-nail aware of them.
The terminal this is typed on produces some unexpected sequences,
here for an example the shifted home key:
Newer
git(1)
versions (v2.33.0) added the option
sendmailCmd
Patches can also be send directly, for example:
By sending a mail to yourself the local MTA can use its normal queue
mechanism to try the delivery multiple times, finally decide a lock file
has become stale, and remove it.
IMAP uses the
`imap://'
and
`imaps://'
protocol prefixes, and an IMAP-based
folder
may be used.
IMAP URLs (paths) undergo inspections and possible transformations
before use (and the command
imapcodec
can be used to manually apply them to any given argument).
Hierarchy delimiters are normalized, a step which is configurable via the
imap-delim
variable chain, but defaults to the first seen delimiter otherwise.
S-nail supports internationalised IMAP names, and en- and decodes the
names from and to the
ttycharset
as necessary and possible.
If a mailbox name is expanded (see
Sx Filename transformations )
to an IMAP mailbox, all names that begin with `+' then refer to IMAP
mailboxes below the
folder
target box, while folder names prefixed by `@' refer to folders below
the hierarchy base, so the following will list all folders below the
current one when in an IMAP mailbox:
`folders'
@ .
Note: some IMAP servers do not accept the creation of mailboxes in
the hierarchy base, but require that they are created as subfolders of
`INBOX' - with such servers a folder name of the form
should be used (the last character is the server's hierarchy
delimiter).
The following IMAP-specific commands exist:
The following IMAP-specific internal variables exist:
BSD Mail, in large parts compatible with
UNIX
mail, was written in 1978 by Kurt Shoens and developed as part of the
BSD UNIX
distribution until 1995.
This manual page is derived from
``The Mail Reference Manual''
that Kurt Shoens wrote for Mail 1.3, included in 3BSD in 1980.
The common
UNIX
and
BSD denominator became standardized as
mailx(1)
in the X/Open Portability Guide Issue 2 (January 1987).
After the rise of Open Source
BSD variants
Mail saw continuous development in the individual code forks,
noticeably by Christos Zoulas in
Net BSD
Based upon this Nail, later Heirloom Mailx, was developed by Gunnar
Ritter in the years 2000 until 2008.
Since 2012 S-nail is maintained by Steffen Nurpmeso.
Electronic mail exchange in general is a concept even older.
The earliest well documented electronic mail system was part of the
Compatible Time Sharing System (CTSS) at MIT, its MAIL command had been
proposed in a staff planning memo at the end of 1964 and was implemented
in mid-1965 when Tom Van Vleck and Noel Morris wrote the necessary code.
Similar communication programs were built for other timesharing systems.
One of the most ambitious and influential was Murray Turoff's EMISARI.
Created in 1971 for the United States Office of Emergency Preparedness,
EMISARI combined private electronic messages with a chat system, public
postings, voting, and a user directory.
During the 1960s it was common to connect a large number of terminals to
a single, central computer.
Connecting two computers together was relatively unusual.
This began to change with the development of the ARPANET, the ancestor
of today's Internet.
In 1971 Ray Tomlinson adapted the SNDMSG program, originally developed
for the University of California at Berkeley timesharing system, to give
it the ability to transmit a message across the network into the mailbox
of a user on a different computer.
For the first time it was necessary to specify the recipient's computer
as well as an account name.
Tomlinson decided that the underused commercial at
`@'
would work to separate the two.
Sending a message across the network was originally treated as a special
instance of transmitting a file, and so a MAIL command was included in
RFC 385 on file transfer in 1972.
Because it was not always clear when or where a message had come from,
RFC 561 in 1973 aimed to formalize electronic mail headers, including
``from''
``date''
and
``subject''
In 1975 RFC 680 described fields to help with the transmission of
messages to multiple users, including
``to''
``cc''
and
``bcc''
In 1977 these features and others went from best practices to a binding
standard in RFC 733.
Queen Elizabeth II of England became the first head of state to send
electronic mail on March 26 1976 while ceremonially opening a building
in the British Royal Signals and Radar Establishment (RSRE) in Malvern.
The SMTP and POP3 protocol support of S-nail is very basic.
Also, if it fails to contact its upstream SMTP server, it will not make
further attempts to transfer the message at a later time (setting
save
and
sendwait
may be useful).
If this is a concern, it might be better to set up a local SMTP server
that is capable of message queuing.
After deleting some message of a POP3 mailbox the header summary falsely
claims that there are no messages to display, one needs to perform
a scroll or dot movement to restore proper state.
In
`thread'
Ns
ed
sort
mode a power user may encounter crashes very occasionally (this is may
and very).
Please report bugs to the
contact-mail
address, for example from within s-nail:
`?'
Ns Ic eval Ns Ic mail Ns $contact-mail .
Including the
verbose
output of the command
version
may be helpful:
Information on the web at
`$'
s-nail -X 'echo Ns $ Ns Va contact-web Ns ; x' .
COMMANDS
S-nail reads input in lines.
An unquoted reverse solidus
`\'
at the end of a command line
``escapes''
the newline character: it is discarded and the next line of input is
used as a follow-up line, with all leading whitespace removed;
once an entire line is completed, the whitespace characters
space , tabulator , newline
as well as those defined by the variable
ifs
are removed from the beginning and end.
Placing any whitespace characters at the beginning of a line will
prevent a possible addition of the command line to the [Option]al
history
? define __xv {
# Before v15: need to enable sh(1)ell-style on _entire_ line!
localopts yes;wysh set verbose;ignerr eval "${@}";return ${?}
}
? commandalias xv '\call __xv'
? xv help set
Command modifiers
Commands may be prefixed by none to multiple command modifiers.
Some command modifiers can be used with a restricted set of commands
only, the
verbose
version of
list
will ([Option]ally) show which modifiers apply.
Old-style argument quoting
[v15 behaviour may differ] This section documents the traditional and POSIX standardized
style of quoting non-message list arguments to commands which expect
this type of arguments: whereas still used by the majority of such
commands, the new
Sx Shell-style argument quoting
may be available even for those via
wysh
one of the
Sx Command modifiers .
Nonetheless care must be taken, because only new commands have been
designed with all the capabilities of the new quoting rules in mind,
which can, for example generate control characters.
Shell-style argument quoting
sh(1)
ell-style, and therefore POSIX standardized, argument parsing and
quoting rules are used by most commands.
[v15 behaviour may differ] Most new commands only support these new rules and are flagged
[Only new quoting rules], some elder ones can use them with the command modifier
wysh
in the future only this type of argument quoting will remain.
Compatibility note:
[v15 behaviour may differ] Please note that even many new-style commands do not yet honour
ifs
to parse their arguments: whereas the
sh(1)
ell is a language with syntactic elements of clearly defined semantics,
S-nail parses entire input lines and decides on a per-command base what
to do with the rest of the line.
This also means that whenever an unknown command is seen all that S-nail
can do is cancellation of the processing of the remains of the line.
? echo one; set verbose; echo verbose=$verbose.
? echo one; wysh set verbose; echo verbose=$verbose.
? echo 'Quotes '${HOME}' and 'tokens" differ!"# no comment
? echo Quotes ${HOME} and tokens differ! # comment
? echo Don"'"t you worry$'\x21' The sun shines on us. $'\u263A'
Message list arguments
Many commands operate on message list specifications, as documented in
Sx Specifying messages .
The argument input is first split into individual tokens via
Sx Shell-style argument quoting ,
which are then interpreted as the mentioned specifications.
If no explicit message list has been specified, many commands will
search for and use the next message forward that satisfies the commands'
requirements, and if there are no messages forward of the current
message, the search proceeds backwards;
if there are no good messages at all to be found, an error message is
shown and the command is aborted.
The
verbose
output of the command
list
will indicate whether a command searches for a default message, or not.
Raw data arguments for codec commands
A special set of commands, which all have the string
``codec''
in their name, like
addrcodec
shcodec
urlcodec
take raw string data as input, which means that the content of the
command input line is passed completely unexpanded and otherwise
unchanged: like this the effect of the actual codec is visible without
any noise of possible shell quoting rules etc., i.e., the user can input
one-to-one the desired or questionable data.
To gain a level of expansion, the entire command line can be
eval uated first, for example
? vput shcodec res encode /usr/Schönes Wetter/heute.txt
? echo $res
$'/usr/Sch\u00F6nes Wetter/heute.txt'
? shcodec d $res
$'/usr/Sch\u00F6nes Wetter/heute.txt'
? eval shcodec d $res
/usr/Schönes Wetter/heute.txt
Filename transformations
Filenames, where expected, and unless documented otherwise, are
subsequently subject to the following filename transformations, in
sequence:
Commands
The following commands are available:
account myisp {
set folder=~/mail inbox=+syste.mbox record=+sent.mbox
set from='(My Name) myname [at] myisp.example'
set mta=smtp://mylogin@smtp.myisp.example
}
? addrc enc "Hey, you",<diet [at] exam.ple>\ out\ there
"\"Hey, you\", \\ out\\ there" <diet [at] exam.ple>
? addrc d "\"Hey, you\", \\ out\\ there" <diet [at] exam.ple>
"Hey, you", \ out\ there <diet [at] exam.ple>
? addrc s "\"Hey, you\", \\ out\\ there" <diet [at] exam.ple>
diet [at] exam.ple
? alias cohorts bill jkf mark kridle [at] ucbcory ~/cohorts.mbox
? alias mark mark [at] exam.ple
? set mta-aliases=/etc/aliases
? bind base a,b echo one
? bind base $'\E',d mle-snarf-word-fwd # Esc(ape)
? bind base $'\E',$'\c?' mle-snarf-word-bwd # Esc,Delete
? bind default $'\cA',:khome,w 'echo Editable binding@'
? bind default a,b,c rm -irf / @ # Also editable
? bind default :kf1 File %
? bind compose :kf1 ~v
#!/bin/sh -
fg() { printf "\033[38;5;${1}m($1)"; }
bg() { printf "\033[48;5;${1}m($1)"; }
i=0
while [ $i -lt 256 ]; do fg $i; i=$(($i + 1)); done
printf "\033[0m\n"
i=0
while [ $i -lt 256 ]; do bg $i; i=$(($i + 1)); done
printf "\033[0m\n"
? commandalias xx
s-nail: `commandalias': no such alias: xx
? commandalias xx echo hello,
? commandalias xx
commandalias xx 'echo hello,'
? xx
hello,
? xx world
hello, world
define name {
command1
command2
...
commandN
}
define exmac {
echo Parameter 1 of ${#} is ${1}, all: ${*} / ${@}
return 1000 0
}
call exmac Hello macro exmac!
echo ${?}/${!}/${^ERRNAME}
? vput = msgno; digmsg create $msgno
? digmsg $msgno header list; readall x; echon $x
210 Subject From To Message-ID References In-Reply-To
? digmsg $msgno header show Subject;readall x;echon $x
212 Subject
'Hello, world'
? digmsg remove $msgno
environ link PERL5LIB TZ
define xxx {
echo "xxx arg <$1>"
shift
if $# -gt 0
\xcall xxx "$@"
endif
}
define yyy {
eval "$@ ' ball"
}
call yyy '\call xxx' "b\$'\t'u ' "
call xxx arg <b u>
call xxx arg < >
call xxx arg <ball>
? filetype bz2 'bzip2 -dc' 'bzip2 -zc' \
gz 'gzip -dc' 'gzip -c' xz 'xz -dc' 'xz -zc' \
zst 'zstd -dc' 'zstd -19 -zc' \
zst.pgp 'gpg -d | zstd -dc' 'zstd -19 -zc | gpg -e'
? set record=+sent.zst.pgp
? filetype \
gzip 'gzip -dc' 'gzip -c' \
zst.pgp 'gpg -d | zstd -dc' 'zstd -19 -zc | gpg -e'
[v15-compat] protocol://[user[:password]@]host[:port][/path]
[no v15-compat] protocol://[user@]host[:port][/path]
if receive
commands ...
else
commands ...
endif
wysh set v15-compat=yes # with value: automatic "wysh"!
if -N debug;echo *debug* set;else;echo not;endif
if "$ttycharset" == UTF-8 || "$ttycharset" ==?cas UTF8
echo ttycharset is UTF-8, the former case-sensitive!
endif
set t1=one t2=one
if [ "${t1}" == "${t2}" ]
echo These two variables are equal
endif
if "$features" =% ,+regex, && "$TERM" =~?case ^xterm.*
echo ..in an X terminal
endif
if [ [ true ] && [ [ "${debug}" != '' ] || \
[ "$verbose" != '' ] ] ]
echo Noisy, noisy
endif
if true && [ -n "$debug" || -n "${verbose}" ]
echo Left associativity, as is known from the shell
endif
define temporary_settings {
set possibly_global_option1
localopts on
set localized_option1
set localized_option2
localopts scope off
set possibly_global_option2
}
? read a b c
H e l l o
? echo "<$a> <$b> <$c>"
<H> <e> <l l o>
? wysh set ifs=:; read a b c;unset ifs
hey2.0,:"'you ",:world!:mars.:
? echo $?/$^ERRNAME / <$a><$b><$c>
0/NONE / <hey2.0,><"'you ",><world!:mars.:><><>
$ printf 'echon "hey, "\nread a\nyou\necho $a' |\
s-nail -R#
hey, you
$ LC_ALL=C printf 'echon "hey, "\nread a\necho $a' |\
LC_ALL=C 6<<< 'you' s-nail -R#X'readctl create 6'
hey, you
? wysh set indentprefix=' -> '
? wysh set atab=$' ' aspace=' ' zero=0
? vput tls result fingerprint pop3s://ex.am.ple
? echo $?/$!/$^ERRNAME: $result
? wysh set ifs=:;read i;unset ifs;echo $i;vexpr pb 2 10#$i
-009
< -009>
0b1001
? vput vexpr res -? +1 -9223372036854775808
? echo $?/$!/$^ERRNAME:$res
0/75/OVERFLOW:-9223372036854775808
? vput vexpr res regex bananarama \
(.*)NanA(.*) '\${1}au\$2'
? echo $?/$!/$^ERRNAME:$res:
1/61/NODATA::
? vput vexpr res regex?case bananarama \
(.*)NanA(.*) '\${1}uauf\$2'
? echo $?/$!/$^ERRNAME:$res:
0/0/NONE:bauauframa:
? vpospar set hey, "'you ", world!
? echo $#: <${1}><${2}><${3}>
? vput vpospar x quote
? vpospar clear
? echo $#: <${1}><${2}><${3}>
? eval vpospar set ${x}
? echo $#: <${1}><${2}><${3}>
COMMAND ESCAPES
Command escapes are available in
Sx Compose mode
during interactive usage, when explicitly requested via
-~
and in batch mode
( -#
They perform special functions, like editing headers of the message
being composed, calling normal
Sx COMMANDS ,
yielding a shell, etc.
Command escapes are only recognized at the beginning of lines, and
consist of an escape followed by a command character.
The default
escape
character is the tilde
`~'
INTERNAL VARIABLES
Internal S-nail variables are controlled via the
set
and
unset
commands; prefixing a variable name with the string
`no'
and calling
set
has the same effect as using
unset
`unset'
crt
and
`set'
nocrt
do the same thing.
varshow
will give more insight on the given variable(s), and
set
when called without arguments, will show a listing of all variables.
Both commands support a more
verbose
listing mode.
Some well-known variables will also become inherited from the
program
Sx ENVIRONMENT
implicitly, others can be imported explicitly with the command
environ
and henceforth share said properties.
? wysh set one=val\ 1 two="val 2" \
three='val "3"' four=$'val \'4\''; \
varshow one two three four; \
unset one two three four
Initial settings
The standard POSIX 2008/Cor 2-2016 mandates the following initial
variable settings:
no allnet
no append
asksub
no askbcc
no autoprint
no bang
no cmd
no crt
no debug
no dot
escape
set to
`~'
,
no flipr
no folder
header
no hold
no ignore
no ignoreeof
no keep
no keepsave
no metoo
no outfolder
no page
prompt
set to
`? '
,
no quiet
no record
save
no sendwait
no showto
no Sign
no sign
toplines
set to
`5'
Variables
define work {
eval echo \$1: \$^ERR-$1:\
\$^ERRNAME-$1: \$^ERRDOC-$1
vput vexpr i + "$1" 1
if [ $i -lt 16 ]
\xcall work $i
end
}
call work 0
? bind base abc echo 0 # abc
? bind base ab,c echo 1 # ab
? bind base abc,d echo 2 # abc
? bind base ac,d echo 3 # ac
? bind base a,b,c echo 4
? bind base a,b,c,d echo 5
? bind base a,b,cc,dd echo 6 # cc and dd
? set customhdr='Hdr1: Body1-1\, Body1-2, Hdr2: Body2'
define mboxfix {
localopts yes; wysh set mbox-rfc4155;\
wysh File "${1}"; copy * "${2}"
}
call mboxfix /tmp/bad.mbox /tmp/good.mbox
submissions://[user[:password]@]server[:port]
$ echo text | s-nail -:/ -Smta=test -s ubject ex [at] am.ple
$ </dev/null s-nail -:/ -Smta=test://./xy ex [at] am.ple
define t_ocl {
vput ! i cat ~/.mysig
if $? -eq 0
vput csop message-inject-tail trim-end $i
end
# Alternatively
readctl create ~/.mysig
if $? -eq 0
readall i
if $? -eq 0
vput csop message-inject-tail trim-end $i
end
readctl remove ~/.mysig
end
}
set on-compose-leave=t_ocl
define ocs_signature {
read version
echo '~< ~/.mysig' # '~<! fortune pathtofortunefile'
}
set on-compose-splice=ocs_signature
wysh set on-compose-splice-shell=$'\
read version;\
printf "hello $version! Headers: ";\
echo \'~^header list\';\
read status result;\
echo "status=$status result=$result";\
'
define ocsm {
read version
echo Splice protocol version is $version
echo '~^h l'; read hl; vput csop es subs "${hl}" 0 1
if "$es" != 2
echoerr 'Cannot read header list'; echo '~x'; xit
endif
if "$hl" !%?case ' cc'
echo '~^h i cc "Diet is your <mirr.or>"'; read es;\
vput csop es substring "${es}" 0 1
if "$es" != 2
echoerr 'Cannot insert Cc: header'; echo '~x'
# (no xit, macro finishes anyway)
endif
endif
}
set on-compose-splice=ocsm
? set pipe-X/Y='?!++=? vim ${MAILX_FILENAME_TEMPORARY}'
# Avoid ASCII "propagates to 8-bit" when scripting
\if ! t && "$LC_ALL" != C && "$LC_CTYPE" != C
\set sendcharsets-else-ttycharset
\end
$ ssh -D 10000 USER [at] HOST
$ s-nail -Ssocks-proxy=[socks5://]localhost:10000
# or =localhost:10000; no local DNS: =127.0.0.1:10000
? set termcap='Co#256,home=\E[H,bel=^G'
# Register a configuration section for s-nail
s-nail = mailx_master
# The top configuration section creates a relation
# in between dynamic SSL configuration and an actual
# program specific configuration section
[mailx_master]
ssl_conf = mailx_tls_config
# And that program specific configuration section now
# can map diverse tls-config-module names to sections,
# as in: tls-config-module=account_xy
[mailx_tls_config]
account_xy = mailx_account_xy
account_yz = mailx_account_yz
[mailx_account_xy]
MinProtocol = TLSv1.2
Curves=P-521
[mailx_account_yz]
CipherString = TLSv1.2:!aNULL:!eNULL:
MinProtocol = TLSv1.1
Options = Bugs
ENVIRONMENT
The term
``environment variable''
should be considered an indication that these variables are either
standardized as vivid parts of process environments, or that they are
commonly found in there.
The process environment is inherited from the
sh(1)
once S-nail is started, and unless otherwise explicitly noted handling of
the following variables transparently integrates into that of the
Sx INTERNAL VARIABLES
from S-nail's point of view.
This means they can be managed via
set
and
unset
causing automatic program environment updates (to be inherited by
newly created child processes).
$ EDITOR="vim -u ${HOME}/.vimrc"
$ export EDITOR
$ COLUMNS=80 s-nail -R
$ SOURCE_DATE_EPOCH=`date +%s` s-nail
FILES
Resource files
Upon startup S-nail reads in several resource files, in order:
# This line is a comment command. And y\
es, it is really continued here.
set debug \
verbose
set editheaders
The mime.types files
As stated in
Sx HTML mail and MIME attachments
S-nail needs to learn about MIME (Multipurpose Internet Mail Extensions)
media types in order to classify message and attachment content.
One source for them are
mime.types
files, the loading of which can be controlled by setting the variable
mimetypes-load-control
Another is the command
mimetype
which also offers access to S-nails MIME type cache.
mime.types
files have the following syntax:
type/subtype extension [extension ...]
# For example text/html html htm
[type-marker ]type/subtype extension [extension ...]
The Mailcap files
[Option] RFC 1524 defines a
``User Agent Configuration Mechanism''
to be used to inform mail user agent programs about the locally
installed facilities for handling various data formats, i.e., about
commands and how they can be used to display, edit et cetera MIME part
contents, as well as a default path search that includes multiple
possible locations of resource files, and the
MAILCAPS
environment variable to overwrite that.
Handlers found from doing the path search will be cached, the command
mailcap
operates on that cache, and the variable
mailcap-disable
will suppress automatic loading, and usage of any mailcap handlers.
Sx HTML mail and MIME attachments
gives a general overview of how MIME types are handled.
application/postscript; ps-to-terminal %s; needsterminal
application/postscript; ps-to-terminal %s; compose=idraw %s
# Message
Content-type: multipart/mixed; boundary=42
# Mailcap file
multipart/*; /usr/local/bin/showmulti \
%t %{boundary} ; composetyped = /usr/local/bin/makemulti
# Executed shell command
/usr/local/bin/showmulti multipart/mixed 42
# Comment line
text/richtext; richtext %s; copiousoutput
text/x-perl; perl -cWT %s; nametemplate = %s.pl
# Exit EX_TEMPFAIL=75 on signal
application/pdf; \
infile=%s\; \
trap "rm -f ${infile}" EXIT\; \
trap "exit 75" INT QUIT TERM\; \
mupdf "${infile}"; \
test = [ -n "${DISPLAY}" ]; \
nametemplate = %s.pdf; x-mailx-async
application/pdf; pdftotext -layout - -; copiousoutput
application/*; echo "This is \\"%t\\" but \
is 50 \% Greek to me" \; < %s head -c 512 | cat -vet; \
copiousoutput; x-mailx-noquote; x-mailx-last-resort
The .netrc file
User credentials for machine accounts (see
Sx On URL syntax and credential lookup )
can be placed in the
.netrc
file, which will be loaded and cached when requested by
netrc-lookup
The default location
~/.netrc
may be overridden by the
NETRC
environment variable.
As long as syntax constraints are honoured the file source may be
replaced with the output of the shell command set in
netrc-pipe
to load an encrypted file, for example.
The cache can be managed with the command
netrc
machine *.example.com login USER password PASS
machine pop3.example.com login USER password PASS
machine smtp.example.com login USER password PASS
EXAMPLES
An example configuration
# This example assumes v15.0 compatibility mode
set v15-compat
# Request strict TLL transport layer security checks
set tls-verify=strict
# Where are the up-to-date TLS certificates?
# (Since we manage up-to-date ones explicitly, do not use any,
# possibly outdated, default certificates shipped with OpenSSL)
#set tls-ca-dir=/etc/ssl/certs
set tls-ca-file=/etc/ssl/certs/ca-certificates.crt
set tls-ca-no-defaults
#set tls-ca-flags=partial-chain
wysh set smime-ca-file="${tls-ca-file}" \
smime-ca-no-defaults #smime-ca-flags="${tls-ca-flags}"
# This could be outsourced to a central configuration file via
# tls-config-file plus tls-config-module if the used library allows.
# CipherString: explicitly define the list of ciphers, which may
# improve security, especially with protocols older than TLS v1.2.
# See ciphers(1). Possibly best to only use tls-config-pairs-HOST
# (or -USER [at] HOST), as necessary, again..
# Note that TLSv1.3 uses Ciphersuites= instead, which will join
# with CipherString (if protocols older than v1.3 are allowed)
# Curves: especially with TLSv1.3 curves selection may be desired.
# MinProtocol,MaxProtocol: do not use protocols older than TLS v1.2.
# Change this only when the remote server does not support it:
# maybe use chain support via tls-config-pairs-HOST / -USER [at] HOST
# to define such explicit exceptions, then, e.g.,
# MinProtocol=TLSv1.1
if "$tls-features" =% ,+ctx-set-maxmin-proto,
wysh set tls-config-pairs='\
CipherString=TLSv1.2:!aNULL:!eNULL:@STRENGTH,\
Curves=P-521:P-384:P-256,\
MinProtocol=TLSv1.1'
else
wysh set tls-config-pairs='\
CipherString=TLSv1.2:!aNULL:!eNULL:@STRENGTH,\
Curves=P-521:P-384:P-256,\
Protocol=-ALL\,+TLSv1.1 \, +TLSv1.2\, +TLSv1.3'
endif
# Essential setting: select allowed character sets
set sendcharsets=utf-8,iso-8859-1
# A very kind option: when replying to a message, first try to
# use the same encoding that the original poster used herself!
set reply-in-same-charset
# When replying, do not merge From: and To: of the original message
# into To:. Instead old From: -> new To:, old To: -> merge Cc:.
set recipients-in-cc
# When sending messages, wait until the Mail-Transfer-Agent finishs.
# Only like this you will be able to see errors reported through the
# exit status of the MTA (including the built-in SMTP one)!
set sendwait
# Only use built-in MIME types, no mime.types(5) files
set mimetypes-load-control
# Default directory where we act in (relative to $HOME)
set folder=mail
# A leading "+" (often) means: under *folder*
# *record* is used to save copies of sent messages
set MBOX=+mbox.mbox DEAD=+dead.txt \
record=+sent.mbox record-files record-resent
# Make "file mymbox" and "file myrec" go to..
shortcut mymbox %:+mbox.mbox myrec +sent.mbox
# Not really optional, e.g., for S/MIME
set from='Your Name <address [at] exam.ple>'
# It may be necessary to set hostname and/or smtp-hostname
# if the "SERVER" of mta and "domain" of from do not match.
# The `urlencode' command can be used to encode USER and PASS
set mta=(smtps?|submissions?)://[USER[:PASS]@]SERVER[:PORT] \
smtp-auth=login/plain... \
smtp-use-starttls
# Never refuse to start into interactive mode, and more
set emptystart \
colour-pager crt= \
followup-to followup-to-honour=ask-yes fullnames \
history-file=+.s-nailhist history-size=-1 history-gabby \
mime-counter-evidence=0b1111 \
prompt='?\$?!\$!/\$^ERRNAME[\$account#\$mailbox-display]? ' \
reply-to-honour=ask-yes \
umask=
# Only include the selected header fields when typing messages
headerpick type retain from_ date from to cc subject \
message-id mail-followup-to reply-to
# ...when forwarding messages
headerpick forward retain subject date from to cc
# ...when saving message, etc.
#headerpick save ignore ^Original-.*$ ^X-.*$
# Some mailing lists
mlist '@xyz-editor\.xyz$' '@xyzf\.xyz$'
mlsubscribe '^xfans [at] xfans\.xyz$'
# Handle a few file extensions (to store MBOX databases)
filetype bz2 'bzip2 -dc' 'bzip2 -zc' \
gz 'gzip -dc' 'gzip -c' xz 'xz -dc' 'xz -zc' \
zst 'zstd -dc' 'zstd -19 -zc' \
zst.pgp 'gpg -d | zstd -dc' 'zstd -19 -zc | gpg -e'
# A real life example of a very huge free mail provider
# Instead of directly placing content inside `account',
# we `define' a macro: like that we can switch "accounts"
# from within *on-compose-splice*, for example!
define XooglX {
set folder=~/spool/XooglX inbox=+syste.mbox sent=+sent
set from='Your Name <address [at] examp.ple>'
set pop3-no-apop-pop.gmXil.com
shortcut pop %:pop3s://pop.gmXil.com
shortcut imap %:imaps://imap.gmXil.com
# Or, entirely IMAP based setup
#set folder=imaps://imap.gmail.com record="+[Gmail]/Sent Mail" \
# imap-cache=~/spool/cache
set mta=smtp://USER:PASS@smtp.gmXil.com smtp-use-starttls
# Alternatively:
set mta=smtps://USER:PASS@smtp.gmail.com:465
}
account XooglX {
\call XooglX
}
# Here is a pretty large one which does not allow sending mails
# if there is a domain name mismatch on the SMTP protocol level,
# which would bite us if the value of from does not match, e.g.,
# for people who have a sXXXXeforge project and want to speak
# with the mailing list under their project account (in from),
# still sending the message through their normal mail provider
define XandeX {
set folder=~/spool/XandeX inbox=+syste.mbox sent=+sent
set from='Your Name <address [at] exam.ple>'
shortcut pop %:pop3s://pop.yaXXex.com
shortcut imap %:imaps://imap.yaXXex.com
set mta=smtps://USER:PASS@smtp.yaXXex.com:465 \
hostname=yaXXex.com smtp-hostname=
}
account XandeX {
\call Xandex
}
# Create some new commands so that, e.g., `ls /tmp' will..
commandalias lls '!ls ${LS_COLOUR_FLAG} -aFlrS'
commandalias llS '!ls ${LS_COLOUR_FLAG} -aFlS'
set pipe-message/external-body='?* echo $MAILX_EXTERNAL_BODY_URL'
# We do not support gpg(1) directly yet. But simple --clearsign'd
# message parts can be dealt with as follows:
define V {
localopts yes
wysh set pipe-text/plain=$'?*#++=?\
< "${MAILX_FILENAME_TEMPORARY}" awk \
-v TMPFILE="${MAILX_FILENAME_TEMPORARY}" \'\
BEGIN{done=0}\
/^-----BEGIN PGP SIGNED MESSAGE-----/,/^$/ {\
if(done++ != 0)\
next;\
print "--- GPG --verify ---";\
system("gpg --verify " TMPFILE " 2>&1");\
print "--- GPG --verify ---";\
print "";\
next;\
}\
/^-----BEGIN PGP SIGNATURE-----/,\
/^-----END PGP SIGNATURE-----/{\
next;\
}\
{print}\
\''
print
}
commandalias V '\'call V
define XandeX {
set folder=~/spool/XandeX inbox=+syste.mbox sent=+sent
set from='Your Name <address [at] exam.ple>'
set netrc-lookup
# Load an encrypted ~/.netrc by uncommenting the next line
#set netrc-pipe='gpg -qd ~/.netrc.pgp'
set mta=smtps://smtp.yXXXXx.ru:465 \
smtp-hostname= hostname=yXXXXx.com
set pop3-keepalive=240 pop3-no-apop-pop.yXXXXx.ru
commandalias xp fi pop3s://pop.yXXXXx.ru
}
account XandeX {
\call XandeX
}
machine *.yXXXXx.ru login USER password PASS
$ echo text | s-nail -dvv -AXandeX -s Subject user [at] exam.ple
S/MIME step by step
[Option] The first thing that is needed for
Sx Signed and encrypted messages with S/MIME
is a personal certificate, and a private key.
The certificate contains public information, in particular a name and
email address(es), and the public key that can be used by others to
encrypt messages for the certificate holder (the owner of the private
key), and to
verify
signed messages generated with that certificate('s private key).
Whereas the certificate is included in each signed message, the private
key must be kept secret.
It is used to decrypt messages that were previously encrypted with the
public key, and to sign messages.
$ openssl pkcs12 -in cert.p12 -out certpem.pem -clcerts -nodes
$ # Alternatively
$ openssl pkcs12 -in cert.p12 -out cert.pem -clcerts -nokeys
$ openssl pkcs12 -in cert.p12 -out key.pem -nocerts -nodes
$ openssl req -nodes -newkey rsa:4096 -keyout key.pem -out creq.pem
$ cat key.pem pub.crt > ME [at] HERE.com.paired
? set smime-ca-file=ALL-TRUSTED-ROOT-CERTS-HERE \
smime-sign-cert=ME [at] HERE.com.paired \
smime-sign-digest=SHA512 \
smime-sign from=myname [at] my.host
Using CRLs with S/MIME or TLS
[Option] Certification authorities (CAs) issue certificate revocation
lists (CRLs) on a regular basis.
These lists contain the serial numbers of certificates that have been
declared invalid after they have been issued.
Such usually happens because the private key for the certificate has
been compromised,
because the owner of the certificate has left the organization that is
mentioned in the certificate, etc.
To seriously use S/MIME or TLS verification,
an up-to-date CRL is required for each trusted CA.
There is otherwise no method to distinguish between valid and
invalidated certificates.
S-nail currently offers no mechanism to fetch CRLs, nor to access them on
the Internet, so they have to be retrieved by some external mechanism.
$ openssl crl -inform DER -in crl.der -out crl.pem
FAQ
In general it is a good idea to turn on
debug
( -d
and / or
verbose
( -v
twice) if something does not work well.
Very often a diagnostic message can be produced that leads to the
problems' solution.
S-nail shortly hangs on startup
This can have two reasons, one is the necessity to wait for a file lock
and cannot be helped, the other being that S-nail calls the function
uname(2)
in order to query the nodename of the box (sometimes the real one is
needed instead of the one represented by the internal variable
hostname )
One may have varying success by ensuring that the real hostname and
`localhost'
have entries in
/etc/hosts
or, more generally, that the name service is properly setup -
and does
hostname(1)
return the expected value?
Does this local hostname have a domain suffix?
RFC 6762 standardized the link-local top-level domain
`.local'
,
try again after adding an (additional) entry with this extension.
I cannot login to Google mail (via OAuth)
Since 2014 some free service providers classify programs as
``less secure''
unless they use a special authentication method (OAuth 2.0) which
was not standardized for non-HTTP protocol authentication token query
until August 2015 (RFC 7628).
But, how about XOAUTH2 / OAUTHBEARER?
Following up
Sx I cannot login to Google mail (via OAuth)
one OAuth-based authentication method is available:
the OAuth 2.0 bearer token usage as standardized in RFC 6750 (according
SASL mechanism in RFC 7628), also known as XOAUTH2 and OAUTHBEARER,
allows fetching a temporary access token via the web that can locally be
used as a
password
The protocol is simple and extendable, token updates or even password
changes via a simple TLS secured server login would be possible in
theory, but today a web browser and an external support tool are
prerequisites for using this authentication method.
The token times out and must be periodically refreshed via the web.
$ python oauth2.py --user=EMAIL \
--client-id=THE-ID --client-secret=THE-SECRET \
--generate_oauth2_token
To authorize token, visit this url and follow the directions:
https://accounts.google.com/o/oauth2/auth?client_id=...
Enter verification code: ...
Refresh Token: ...
Access Token: ...
Access Token Expiration Seconds: 3600
$ # Of which the last three are actual token responses.
$ # Thereafter access tokens can regularly be refreshed
$ # via the created refresh token (read on)
set on-main-loop-tick=o-m-l-t on-compose-enter=o-c-e
define o-m-l-t {
xcall update_access_token
}
define o-c-e {
xcall update_access_token
}
set access_token_=0
define update_access_token {
local set i epoch_sec epoch_nsec
vput vexpr i epoch
eval set $i # set epoch_sec/_nsec of vexpr epoch
vput vexpr i + $access_token_ 2100
if $epoch_sec -ge $i
vput ! password python oauth2.py --user=EMAIL \
--client-id=THE-ID --client-secret=THE-SECRET \
--refresh-token=THE-REFRESH-TOKEN |\
sed '1b PASS;d; :PASS s/^.\{1,\}:\(.\{1,\}\)$/\1/'
vput csop password trim "$password"
if -n "$verbose"
echo password is <$password>
endif
set access_token_=$epoch_sec
endif
}
Not "defunctional", but the editor key does not work
Two thinkable situations: the first is a shadowed sequence; setting
debug
or the most possible
verbose
mode, causes a printout of the
bind
tree after that is built; being a cache, this happens only upon startup
or after modifying bindings.
? set verbose
? bind*
# 1B 5B=[ 31=1 3B=; 32=2 48=H
bind base :kHOM z0
? x
$ cat -v
^[[H
$ s-nail -v -Stermcap='kHOM=\E[H'
? bind*
# 1B 5B=[ 48=H
bind base :kHOM z0
Can S-nail git-send-email?
Yes.
Put (at least parts of) the following in your
~/.gitconfig
[sendemail]
smtpserver = /usr/bin/s-nail
smtpserveroption = -t
#smtpserveroption = -Sexpandaddr
smtpserveroption = -Athe-account-you-need
##
suppresscc = all
suppressfrom = false
assume8bitEncoding = UTF-8
#to = /tmp/OUT
confirm = always
chainreplyto = true
multiedit = false
thread = true
quiet = true
annotate = true
$ git format-patch -M --stdout HEAD^ |
s-nail -A the-account-you-need -t RECEIVER
Howto handle stale dotlock files
folder
sometimes fails to open MBOX mail databases because creation of
Sx dotlock files
is impossible due to existing but unowned lock files.
S-nail does not offer an option to deal with those files, because it is
considered a site policy what counts as unowned, and what not.
The site policy is usually defined by administrator(s), and expressed in
the configuration of a locally installed MTA (for example Postfix
`stale_lock_time=500s'
) .
Therefore the suggestion:
$ </dev/null s-nail -s 'MTA: be no frog, handle lock' $LOGNAME
IMAP CLIENT
[Option]ally there is IMAP client support available.
This part of the program is obsolete and will vanish in v15 with the
large MIME and I/O layer rewrite, because it uses old-style blocking I/O
and makes excessive use of signal based long code jumps.
Support can hopefully be readded later based on a new-style I/O, with
SysV signal handling.
In fact the IMAP support had already been removed from the codebase, but
was reinstantiated on user demand: in effect the IMAP code is at the
level of S-nail v14.8.16 (with
imapcodec
being the sole exception), and should be treated with some care.
imaps://mylogin@imap.myisp.example/INBOX.
HISTORY
M. Douglas McIlroy writes in his article
``A Research UNIX Reader: Annotated Excerpts''
from the Programmer's Manual, 1971-1986
that a
mail(1)
command already appeared in First Edition
UNIX
in 1971:
Electronic mail was there from the start.
Never satisfied with its exact behavior, everybody touched it at one
time or another: to assure the safety of simultaneous access, to improve
privacy, to survive crashes, to exploit uucp, to screen out foreign
freeloaders, or whatever.
Not until v7 did the interface change (Thompson).
Later, as mail became global in its reach, Dave Presotto took charge and
brought order to communications with a grab-bag of external networks
(v8).
AUTHORS
An -nosplit
An Kurt Shoens ,
An Edward Wang ,
An Keith Bostic ,
An Christos Zoulas ,
An Gunnar Ritter .
S-nail is developed by
An Steffen Nurpmeso Aq s-mailx [at] lists.sdaoden.eu .
CAVEATS
[v15 behaviour may differ] Interrupting an operation via
SIGINT
aka
`control-C'
from anywhere else but a command prompt is very problematic and likely
to leave the program in an undefined state: many library functions
cannot deal with the
Fn siglongjmp 3
that this software (still) performs; even though efforts have been taken
to address this, no sooner but in v15 it will have been worked out:
interruptions have not been disabled in order to allow forceful breakage
of hanging network connections, for example (all this is unrelated to
ignore )
BUGS
When a network-based mailbox is open, directly changing to another
network-based mailbox of a different protocol (i.e., from POP3 to IMAP
or vice versa) will cause a
``deadlock''
? wysh set escape=! verbose; vput version xy; unset verbose;\
eval mail $contact-mail
Bug subject
!I xy
!.
SEE ALSO
bogofilter(1),
gpg(1),
more(1),
newaliases(1),
openssl(1),
sendmail(1),
sh(1),
spamassassin(1),
iconv(3),
setlocale(3),
aliases(5),
termcap(5),
terminfo(5),
locale(7),
mailaddr(7),
re_format7
(or regex(7))
mailwrapper(8),
sendmail(8)