s-nail (1) - Linux Man Pages
s-nail: send and receive Internet mail
NAME
S-nail [v14.9.15] - send and receive Internet mail
SYNOPSIS
s-nail -words [-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
-words
[-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
-words
[-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 2020). 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. Using -d or -v enables obsoletion warnings.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 =..
- Explicitly control which of the Sx Resource files shall be source d (loaded): if the letter `s' is (case-insensitively) part of the spec then the system wide s-nail.rc is sourced, likewise the letter `u' controls sourcing of the user's personal ~/:.mailrc file, whereas the letters `-' and `/' explicitly forbid sourcing of any resource files. Scripts should use this option: to avoid environmental noise they should ``detach'' from any configuration and create a script-specific environment, setting any of the desired Sx INTERNAL VARIABLES via -S and running configurating commands via -X This option overrides -n
- -A name , --account =..
- Executes an account command for the given user email account name after program startup is complete (all resource files are loaded, any -S setting is being established, but -X commands have not been evaluated yet). Being a special incarnation of define d macros for the purpose of bundling longer-lived set tings, activating such an email account also switches to the accounts Sx primary system mailbox (most likely the inbox ) If the operation fails the program will exit if it is used non-interactively, or if any of errexit or posix are set.
- -a file [=input-charset [#output-charset ] ]
-
Fl Fl attach Ns =.. Attach file to the message (for compose mode opportunities refer to ~@ and ~^ ) Sx Filename transformations (also see file will be performed, except that shell variables are not expanded. Shall file not be accessible but contain a `=' character, then anything before the last `=' will be used as the filename, anything thereafter as a character set specification. If an input character set is specified, but no output character set, then the given input character set is fixed as-is, and no conversion will be applied; giving the empty string or the special string hyphen-minus `-' will be treated as if ttycharset has been specified (the default).
If an output character set has also been given then the conversion will be performed exactly as specified and on-the-fly, not considering the file type and content. As an exception the empty string or hyphen-minus `-' , select the default conversion algorithm (see Sx Character sets ) : no conversion is performed on-the-fly, file and its contents will be MIME-classified ( Sx HTML mail and MIME attachments , The mime.types files) Only this mode is supported without support for character set conversions ( features does not mention `+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 a blind carbon copy to recipient addr if the set ting of expandaddr one of the Sx INTERNAL VARIABLES , allows; the `shquote' expandaddr flag is supported. 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, e.g., `-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 =..
- Just like -b except it places the argument in the list of carbon copies.
- -D , --disconnected
- ([Option]) Startup with disconnected set
- -d , --debug
- Almost enable a sandbox mode with the internal variable debug the same can be achieved via `-S ' Va debug or `set ' Va debug .
- -E , --discard-empty-messages
- set skipemptybody and thus discard messages with an empty message part body.
- -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
- 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 file ) 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 file (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 , --header-search =..
- Display a summary of headers of all messages that match the given spec in the file 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 (e.g., by using the option -v ) Quickrun: does not open an interactive session.
- -M type
- Special send mode that 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
- Special send mode that will 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 =..
- Special send mode that will initialize the message body with the contents of the specified file which may be standard input `-' only in non-interactive context. Also see -M , m , t
- -R , --read-only
- Any mailbox folder aka file opened will be in read-only mode.
- -r from-addr , --from-address =..
- Whereas the source address that appears in the from header of a message (or in the sender header if the former contains multiple addresses) is honoured by the built-in SMTP transport, it is not used by a file-based mta (Mail-Transfer-Agent) for the RFC 5321 reverse-path used for relaying and delegating a message to its destination(s), for delivery errors etc., but it 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 ing 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 =..
- 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 =..
- 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
- 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, e.g., `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 ting the internal variable verbose enables display of some informational context messages. (Will increase the level of verbosity when used multiple times.)
- -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 be used to, e.g., 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 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:
$ LC_ALL=C printf 'm bob\n~s ubject\nText\n~.\nx\n' |\ LC_ALL=C s-nail -d#:/ -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 .
All given to-addr arguments and all receivers established via -b and -c as well as -T are subject to the checks established by expandaddr one of the Sx INTERNAL VARIABLES ; they all support the flag `shquote' 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
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 purposes. 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.Because S-nail strives for compliance with POSIX mailx(1) it is likely that some configuration settings have to be adjusted before using it is a smooth experience. (Rather complete configuration examples can be found in the section Sx EXAMPLES . ) The provided global s-nail.rc (one of the Sx Resource files ) template bends those standard imposed settings of the Sx INTERNAL VARIABLES a bit towards more user friendliness and safety, however.
For example, it set s hold and keepsave 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 if posix aka POSIXLY_CORRECT mode has been enabled) to avoid mangling of file permissions when files eventually get recreated.
To enter interactive mode even if the initial mailbox is empty it sets emptystart editheaders to allow editing of headers as well as fullnames to not strip down addresses in 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.
Some random remarks. The file mode creation mask can be managed explicitly via the variable umask Files and shell pipe output can be source d for evaluation, also during startup from within the Sx Resource files .
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 -:/ -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 -. \ eric [at] exam.ple < /tmp/letter.txt
If standard input is a terminal rather than the message to be sent, the user is expected to type in the message contents. In this compose mode S-nail treats lines beginning with the character `~' 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; e.g., ~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.
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' ).
A number of Sx ENVIRONMENT and Sx INTERNAL VARIABLES can be used to alter default behavior. set ting (also via -S editalong will automatically startup an editor when compose mode is entered, and editing of headers additionally to plain body content can be enabled via editheaders [v15 behaviour may differ] some, but not all headers can be created, edited or deleted in an editor, then. askcc and askbcc will cause the user to be prompted actively for (blind) carbon-copy recipients, respectively, and (the default) asksend will request confirmation whether the message shall be sent.
The envelope sender address 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 MIME parts aka attachments need to be assigned a mimetype usually taken out of Sx The mime.types files . Saving a copy of sent messages in a record mailbox may be desirable - as for most mailbox file targets the value will undergo Sx Filename transformations . Some introductional -d or debug sandbox dry-run tests will prove correctness.
Message recipients are subject to alternates filtering, and may not only be email addresses, but can also be names of mailboxes and even complete shell command pipe specifications. If the variable expandaddr is not set then only email addresses like `bob [at] exam.ple' and plain user names (including MTA aliases) may be used, other types will be filtered out, giving a warning message. expandaddr indeed allows further control over and adjustments of message recipients, e.g., user names can be expanded to network addresses by specifying `namehostex' A network address that contains no domain-, but only a valid local user `<name>' in angle brackets will be automatically expanded to a valid address when hostname is not set, or set to a non-empty value; setting it to the empty value instructs S-nail that the used mta will perform the necessary expansion. The command addrcodec may help to generate standard compliant network addresses.
If the variable expandaddr is set then an extended set of recipient addresses will be accepted: 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.
$ 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 -:/ -Sv15-compat -Sttycharset=utf8 \ --set mime-force-sendout \ -Sexpandaddr=fail,-all,+addr,failinvaddr -s test \ -. bob [at] exam.ple
To create file-carbon-copies the special recipient header `Fcc:' may be used as often as desired. Its entire value (or body in standard terms) is interpreted as a file target, after having been subject to Sx Filename transformations . Beside using the command escape ~^ (to create a `Fcc' header) this is the only way to create a file-carbon-copy without introducing an ambiguity regarding the interpretation of the address, e.g., to use file names with leading vertical bars or commercial ats. 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
It is possible to create personal distribution lists via the alias command, so that, for instance, the user can send mail to `cohorts' and have it go to a group of people. Different to the alias mechanism of most local mta s, often documented in aliases(5) and subject to the `name' constraint of expandaddr personal aliases will be expanded by S-nail before the message is sent. They are thus a convenient alternative to specifying each addressee by itself, correlate with the active set of alternates and are subject to metoo filtering. [Option]ally MTA aliases can be expanded before sending messages by setting mta-aliases
? alias cohorts bill jkf mark kridle [at] ucbcory ~/cohorts.mbox ? alias mark mark [at] exam.ple ? set mta-aliases=/etc/aliases
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 it is also possible to use a flat configuration, making use of so-called variable chains which automatically pick `USER [at] HOST' or `HOST' context-dependent variable variants: for example addressing `File ' 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. See Sx On URL syntax and credential lookup and Sx INTERNAL VARIABLES .
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.)
To avoid environmental noise scripts should ``detach'' S-nail from any configuration files and create a script-local environment, ideally with the command line options -: to disable any configuration file 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 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, which is introduced in the next section, messages can be sent by calling the mail command with a list of recipient addresses:
$ s-nail -d -Squiet -Semptystart "/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
On reading mail, and 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 file 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 ) , e.g., `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, e.g., 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 file 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). The command Lreply knows 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 regulary 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
Messages which are HTML-only become more and more common, and of course many messages come bundled with a bouquet of MIME (Multipurpose Internet Mail Extensions) parts. To get a notion of MIME types S-nail has a default set of types built-in, 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 with the command mimetype To improve interaction with faulty MIME part declarations which are often seen in real-life messages, setting mime-counter-evidence will allow verification of the given assertion, and possible provision of an alternative, better MIME type.Whereas S-nail [Option]ally supports a simple HTML-to-text filter for displaying HTML messages (indicated by `+filter-html-tagsoup' in features ) it cannot handle MIME types other than plain text itself. Instead programs need to become registered to deal with specific MIME types or file extensions. These programs may either prepare plain text versions of their input in order to enable S-nail to integrate their output neatlessly in its own message visualization (a mode which is called copiousoutput ) or display the content themselves, for example in an external graphical window: such handlers will only be considered by and for the command mimeview
To install a handler program for a specific MIME type an according pipe-TYPE/SUBTYPE variable needs to be set; to instead define a handler for a specific file extension the respective pipe-EXTENSION variable can be used - these handlers take precedence. [Option]ally S-nail supports mail user agent configuration as defined in RFC 1524; this mechanism (see Sx The Mailcap files ) will be queried for display or quote handlers if none of the former two did; it will be the sole source for handlers of other purpose. A last source for handlers is the MIME type definition itself, if a type-marker has been registered with the command mimetype which many of the built-in MIME types do.
For example, to display a HTML message inline (converted to a more fancy plain text representation than the built-in filter is capable to produce) with either of the text-mode browsers lynx(1) or elinks(1), teach S-nail about MathML documents and make it display them as plain text, 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=? ? endif ? mimetype ? 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}"'
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 and Lreply ) 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, e.g., when list-replying via Lreply when 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 such address which contains 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.
? 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.
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 becoming 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
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 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
[v15-compat] For accessing protocol-specific resources usage of Uniform Resource Locators (URL, RFC 3986) has become omnipresent. S-nail expects and understands URLs in a ``normalized'' variant which is 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 in question, or because the part is protocol-specific, e.g., `/path' is used by the [Option]al Maildir file type and the IMAP protocol, but not by POP3. If as part of the URL any of `USER' and `PASSWORD' is specified, then the URL percent encoded form must be used (RFC 3986; the command urlcodec can be used to perform the encoding):
PROTOCOL://[USER[:PASSWORD]@]server[:port][/path]
Many internal variables of S-nail exist in multiple versions, called variable chains for the rest of this document: the plain `variable' as well as `variable-HOST' and `variable-USER [at] HOST' Here `HOST' indeed means `server:port' if a `port' had been specified in the respective URL, otherwise it refers to the plain `server' Also, `USER' is not truly the `USER' that had been found when doing the user chain lookup as is described below, i.e., this `USER' will never be in URL percent encoded form, whether it came from an URL or not; i.e., variable chain name extensions of Sx INTERNAL VARIABLES must not be URL percent encoded.
For example, whether an hypothetical URL `smtp://hey%3Ayou@our.house' had been given that includes a user, or whether the URL was `smtp://our.house' and the user had been found differently, to lookup the variable chain smtp-use-starttls S-nail first looks for whether `smtp-:use-:starttls-:hey:you [at] our.house' is defined, then whether `smtp-:use-:starttls-:our.house' exists before finally ending up looking at the plain variable itself.
S-nail obeys the following logic scheme when dealing with the necessary credential information of an account:
-
A user is always required.
If no
`USER'
has been given in the URL the variables
user-HOST
and
user
are looked up.
If no such variable(s) can be found then S-nail will,
when enforced by the [Option]al variables
netrc-lookup-HOST
or
netrc-lookup
search
Sx The .netrc file
of the user for a
`HOST'
specific entry which provides a
`login'
name: this lookup will only succeed if unambiguous (one possible matching
entry for
`HOST'
) .
If there is still no `USER' then S-nail will fall back to the user who is supposed to run S-nail, the identity of which has been fixated during S-nail startup and is known to be a valid user on the current host.
- Authentication: unless otherwise noted this will lookup the PROTOCOL-auth-USER [at] HOST , PROTOCOL-auth-HOST , PROTOCOL-auth variable chain, falling back to a protocol-specific default should this have no success.
-
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 already provided the password, too.
Otherwise the variable chain
password-USER [at] HOST , password-HOST , password
is looked up and used if existent.
Afterwards the complete [Option]al variable chain netrc-lookup-USER [at] HOST , netrc-lookup-HOST , netrc-lookup is looked up. 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 that 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. 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
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 is that of certificates: as part of each network connection setup a (set of) certificates will be exchanged, and by using those the identity of the network peer can be cryptographically verified; if possible the TLS/SNI (ServerNameIndication) extension will be enabled in order to allow servers fine-grained control over the certificates being used. TLS works by using a locally installed pool of trusted certificates, and verifying the connection peer succeeds if that provides a certificate which has been issued or is trusted by any certificate in the trusted local pool.The local pool of trusted so-called CA (Certification Authority) certificates is usually delivered with the used TLS library, and will be selected automatically. It is also possible to use a specific pool of trusted certificates. If this is desired, tls-ca-no-defaults should be set to avoid using the default certificate pool, and tls-ca-file and/or (with special preparation) tls-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. For inspection or other purposes, the certificate of a server (as seen when connecting to it) can be fetched like this:
$ </dev/null openssl s_client -showcerts -connect \ the-server.example:pop3s 2>&1 | tee log.txt
S-nail also supports a mode of operation in which certificates are not at all matched against a local pool of CA certificates. Instead a message digest will be calculated for the certificate presented by the connection peer, and be compared against tls-fingerprint (a variable chain that picks up `USER [at] HOST' or `HOST' context-dependent variable variants), and the connection will succeed if the calculated digest equals the expected one. The used message digest can be configured via (the chain) tls-fingerprint-digest The command tls may be helpful.
It depends on the used protocol whether encrypted communication is possible, and which configuration steps have to be taken to enable it. Some protocols, e.g., 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 specify the allowed protocols or cipher lists that a communication channel may use. 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) can be used and 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] S-nail detects the character set of the terminal by using mechanisms that are controlled by the LC_CTYPE environment variable (in fact LC_ALL LC_CTYPE LANG in that order, see there). 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, e.g., set and varshowHowever, the user may give ttycharset a value during startup, making it possible to send mail in a completely ``faked'' locale environment, an option which can be used to generate and send, e.g., 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 ) . Changing the value does not mean much beside that, because several aspects of the real character set are implied by the locale environment of the system, which stays unaffected by ttycharset
Messages and attachments which consist of 7-bit clean data will be classified as consisting of charset-7bit character data. This is a problem if the ttycharset character set is a multibyte character set that is also 7-bit clean. For example, the Japanese character set ISO-2022-JP is 7-bit clean but 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! To achieve this, the variable charset-7bit must 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.)
If the [Option]al character set conversion capabilities are not available ( features does not include the term `+iconv' ) , then ttycharset will be the only supported character set, it is simply assumed that it can be used to exchange 8-bit messages (over the wire an intermediate, configurable mime-encoding may be applied), and the rest of this section does not apply; it may however still be necessary to explicitly set it if automatic detection fails, since in that case it defaults to LATIN1 aka ISO-8859-1 unless the operating system environment is known to always and exclusively support UTF-8 locales.
[Option] When reading messages, their text 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 proper substitution characters. Character set mappings for source character sets can be established with the command charsetalias which may be handy to work around faulty character set catalogues (e.g., to add a missing LATIN1 to ISO-8859-1 mapping), or to enforce treatment of one character set as another one (e.g., to interpret LATIN1 as CP1252). Also see charset-unknown-8bit to deal with another hairy aspect of message interpretation.
When sending messages their parts and attachments are classified. Whereas no character set conversion is performed on those parts which appear to be binary data, the character set being used must be declared within the MIME header of an outgoing text part if it contains characters that do not conform to the set of characters that are allowed by the email standards. Permissible values for character sets used in outgoing messages can be declared using the sendcharsets variable, and charset-8bit which defines a catch-all last-resort fallback character set that is implicitly appended to the list of character sets in sendcharsets
When replying to a message and the variable reply-in-same-charset is set, then the character set of the message being replied to is tried first (still being a subject of charsetalias ) And it is also possible to make S-nail work even more closely related to the current locale setting automatically by using the variable sendcharsets-else-ttycharset please see there for more information.
All the specified character sets are tried in order unless the conversion of the part or attachment succeeds. If none of the tried (8-bit) character sets is capable to represent the content of the part or attachment, then the message will not be send and its text will optionally be save d in DEAD If that is not acceptable, the variable mime-force-sendout can be set in order to force sending of non-convertible text as `application/octet-stream' classified binary content instead; like this receivers still have the option to inspect message content (for example by setting mime-counter-evidence )
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 S-nail is run in a UTF-8 locale on an 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 from aka search type and delete can be given a list of message numbers as arguments to apply to a number of messages at once. Thus `delete' 1 2 deletes 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. 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.
- 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, e.g.,
'@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, e.g.,
- :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 quotes `' 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, e.g., `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 will be realized through one of the standard UNIX libraries, either the Lb libtermcap , or, alternatively, the Lb libterminfo , both of which will be initialized to work with the environment variable TERM Terminal control will enhance or enable interactive usage aspects, e.g., Sx Coloured display , and extend behaviour of the Mailx-Line-Editor (MLE), which may learn the byte-sequences of keys like the cursor- and function-keys.The internal variable termcap can be used to overwrite settings or to learn (correct(ed)) keycodes. Actual library interaction can be disabled completely by setting termcap-disable termcap will be queried regardless, which is true even if the [Option]al library support has not been enabled at configuration time as long as some other [Option] which (may) query terminal control sequences has been enabled. S-nail can be told to enter an alternative exclusive screen, the so-called ca-mode, by setting termcap-ca-mode this requires sufficient terminal support, and the used PAGER may also need special configuration, dependent on the value of crt
[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 the internal variable 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 fine 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, e.g., `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; combinations not mentioned either cause job control signals or do not generate a (unique) keycode:
- `\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] S-nail can be configured to support a coloured display and font attributes by emitting ANSI aka ISO 6429 SGR (select graphic rendition) escape sequences. Usage of colours and font attributes solely depends upon the capability of the detected terminal type that is defined by the environment variable TERM and which can be fine-tuned by the user via the internal variable termcapOn top of what S-nail knows about the terminal the boolean variable colour-pager defines whether the actually applicable colour and font attribute sequences should also be generated when output is going to be paged through the external program defined by the environment variable PAGER (also see crt ). This is not enabled by default because different pager programs need different command line switches or other configuration in order to support those sequences. S-nail however knows about some widely used pagers and in a clean environment it is often enough to simply set colour-pager please refer to that variable for more on this topic.
Colours and font attributes can be managed with the multiplexer command colour and uncolour can be used to remove mappings of a given colour type. If the variable colour-disable is set then any active usage of colour and font attribute sequences is suppressed without affecting possibly established colour mappings. Since colours are available if any of the standard I/O descriptors it opened on a terminal, it might make sense to conditionalize the colour setup by encapsulating it with 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.
S-nail will never be able to handle
`?'
set one=value two=$one
in a single statement, because the variable assignment is performed by
the command
( set
not the language.
The command
list
can be used to show the list of all commands, either alphabetically
sorted or in prefix search order (these do not match, also because the
POSIX standard prescribes a set of abbreviations).
[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, e.g., 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, e.g.,
`^G'
,
the reverse solidus notation has been standardized:
`\cG'
Some control codes also have standardized (ISO-10646, ISO C) aliases,
as shown above (e.g.,
`\a'
,
`\n'
,
`\t'
) :
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, e.g., 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
file )
a possibly installed
folder-hook
will be run, and the internal variable
account
will be updated.
The two argument form is identical to defining a macro as via
define
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 address alias is newly defined or will be
appended to: target arguments must either be valid alias names, or any
other address type.
Recursive expansion of (what looks like) alias name(s) targets can be
prevented by prefixing the target with the modifier reverse solidus
\
A valid alias name conforms to the Postfix MTA
aliases(5)
rules, and may consist of alphabetic characters, digits, the underscore,
the number sign, colon, commercial at and hyphen-minus; extensions:
exclamation mark
`!'
,
period
`.'
as well as
``any character that has the high bit set''
may be used:
`[[:alnum:]_#:@!.-]+'
The number sign may need be quoted to avoid misinterpretation as the
shell comment character.
[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 binding is (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, and any remaining arguments form the expansion.
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 to compose mode only.
``Keys''
which form the binding are specified as a comma-separated list of
byte-sequences, where each list entry corresponds to one key(press).
A list entry may, indicated by a leading colon character
`:'
,
also refer to the name of a terminal capability; several dozen names
will be 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.
It is possible to use any capability, 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, so that an exact match is
required to update or remove a binding.
Examples:
Note that the entire comma-separated list is first parsed (over) as a
shell-token with whitespace as the field separator, before being 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.
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
It is advisable to use an initial escape or other control character (e.g.,
`\cA'
)
for bindings which describe user key combinations (as opposed to purely
terminal capability based ones), in order to avoid ambiguities whether
input belongs to key sequences or not; it also reduces search time.
Adjusting
bind-timeout
may help shall keys and sequences be falsely recognized.
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.
Without further arguments the list of all currently defined mappings
for the given colour type is shown (as a special case giving
`all'
or
`*'
will show the mappings of all types).
Otherwise the second argument defines the mappable slot, and the third
argument a (comma-separated list of) colour and font attribute
specification(s), and the optional 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 precondition available depend on the mappable slot (see
Sx Coloured display
for some examples), 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, e.g., 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 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 ) :
Afterwards changing such variables with
set
will cause automatic updates of the program environment, and therefore
be inherited by newly created child processes.
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 program environment, but in any way
the knowledge they ever have been
`link'
Ns
ed will be lost.
Note that this implies that
localopts
may cause loss of such links.
The command
`unlink'
will remove an existing link, but leaves the variables as such intact.
Additionally the subcommands
`set'
and
`unset'
are provided, which work exactly the same as the documented commands
set
and
unset
but (additionally un)link the variable(s) with the program environment
and thus immediately export them to, or remove them from (if possible),
respectively, the program environment.
Sx Filename transformations
will be applied to the
name
argument, and
`protocol://'
prefixes are, i.e., URL syntax is understood, e.g.,
`mbox:///tmp/mdirbox'
:
if a protocol prefix is used the mailbox type is fixated and neither
the auto-detection (read on) nor the
newfolders
mechanisms apply.
[Option]ally URLs can also be used to access network resources, which may
be accessed securely via
Sx Encrypted network communication
if so supported.
Network communication socket timeouts are configurable, e.g.,
socket-connect-timeout
All generated network traffic may be proxied over the SOCKS5 server given in
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 .
If the resulting file protocol (MBOX database)
name
is located on a local filesystem then the list of all registered
filetype s is traversed in order to see whether a transparent intermediate
conversion step is necessary to handle the given mailbox, in which case
S-nail will use the found hook to load and save data into and from
a temporary file, respectively.
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:
filetype s also provide limited (case-sensitive) auto-completion capabilities.
For example
`mbox.gz'
will be found for
`?'
file mbox
provided that a corresponding handler is installed.
It will neither find
`mbox.GZ'
nor
`mbox.Gz however,
'
on the other hand doing an explicit
`?'
file mbox.GZ
will find and use the handler for
`gz'
MBOX databases will always be protected via file-region locks
( fcntl(2)
during file operations in order to avoid inconsistencies due to
concurrent modifications.
[Option] In addition mailbox files treated as the system
inbox
( MAIL
as well as
Sx primary system mailbox Ns
es in general 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 for the duration of the synchronization ---
as necessary an external privileged dotlock helper will be used
to create the dotlock file in the same directory and with the same user
and group identities as the file of interest.
dotlock-disable
can be used to turn off additional dotlock files, shall the need arise.
There is also a related entry in the
Sx FAQ :
Sx Howto handle stale dotlock files .
S-nail by default uses tolerant POSIX rules when reading MBOX database
files, but it will detect invalid message boundaries in this mode and
complain (even more with
debug
if any is seen: in this case
mbox-rfc4155
can be used to create a valid MBOX database from the invalid input.
[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.
[v15 behaviour may differ] If no protocol has been fixated and no existing file has
been found, the variable
newfolders
controls the format of mailboxes yet to be created.
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.
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified,
^ERR -PERM
if some addressees where rejected by
expandaddr
^ERR -NODATA
if no applicable messages have been given,
^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.
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, e.g.,
`-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, e.g.,
`==?'
,
`==?satu'
and
`==?saturated'
are 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, e.g.,
`==?'
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 -NODATA
if no applicable messages have been given,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
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 -NODATA
if no applicable messages have been given,
^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.
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 .
E.g. (this example requires a modern shell):
This may generate the errors
^ERR -DESTADDRREQ
if no receiver has been specified,
^ERR -PERM
if some addressees where rejected by
expandaddr
^ERR -NODATA
if no applicable messages have been given,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
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 the addressee was rejected by
expandaddr
^ERR -NODATA
if no applicable messages have been given,
^ERR -IO
if an I/O error occurs,
^ERR -NOTSUP
if a necessary character set conversion fails, and
^ERR -INVAL
for other errors.
Occurrence of some of the errors depend on the value of
expandaddr
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 alter the command to work in block-scope all variables
have values (may they be empty), and creation of names which shadow
Sx INTERNAL VARIABLES
is actively prevented ([v15 behaviour may differ] shadowing of linked
Sx ENVIRONMENT
variables and free-form versions of variable chains is not yet detected).
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, e.g.,
`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), e.g.,
`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, e.g.,
`+?'
,
`+?satu'
,
and
`+?saturated'
are 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, e.g.,
`regex?'
and
`regex?case'
are 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 convience 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.
[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 noted all compose mode command escapes ensure proper
updates of the variables which represent the error number
!
and the exit status
?
If the variable
errexit
is set they will, unless stated otherwise, error out message compose mode
and cause a program exit if an operation fails;
an effect equivalent to the command modifier
ignerr
can however be achieved by placing a hyphen-minus
`-'
after (possible whitespace following) the escape character.
If the [Option]al key bindings are available it is possible to create
bind ings specifically for the compose mode.
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, e.g.,
`~||'
echo Fcc: /tmp/test; cat
will prepend a file-carbon-copy message header.
Also see
~e , ~v
If a command indicates failure then the message will have remained
unmodified.
Most commands can fail with
`500'
if required arguments are missing (false command usage).
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.
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''
which is a boolean string that can optionally be prefixed with the
(case-insensitive) term
`ask-'
,
as in
`ask-yes'
,
which causes prompting of the user in interactive mode, with the given
boolean as the default value.
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.
Indeed the value is interpreted as a comma-separated list of
case-insensitive strings.
Hard send errors can be enforced for disallowed address types by setting
`fail'
;
by default these are only filtered out.
User name receivers addressing valid local users can be expanded to
a network address (also see
hostname
by setting
`namehostex'
Address targets can be added and removed with a plus sign
`+'
or hyphen-minus
`-'
prefix, respectively: the value
`all'
addresses all possible specifications,
`fcc'
whitelists targets specified via
`Fcc:'
headers regardless of other settings,
`file'
file targets (it includes
`fcc'
) ,
`pipe'
command pipeline targets,
`name'
plain user names left for further expansion by the MTA (implicitly
disallowed for the SMTP based
mta )
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 address may be used, then.
Historically invalid network addressees were silently stripped off ---
shall they cause hard errors instead it must be ensured that
`failinvaddr'
is an entry of the list (it really acts like
`failinvaddr,:+addr'
) .
Likewise,
`domaincheck'
(actually : `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, e.g., 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 enforced to appear as the envelope sender address at
the MTA protocol level (the RFC 5321 reverse-path), either by using the
-r
command line option (with an empty argument; see there for the complete
picture on this topic), or by setting the internal variable
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.
[Option]ally S-nail can take care of expansion of the usual
mta-aliases
( aliases(5))
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 S-nail will also (not) pass
-f
as well as possibly
-F
[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, e.g.,
socket-connect-timeout
All generated network traffic may be proxied over the SOCKS5 server given in
socks-proxy
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 1''
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, e.g.,
`set'
pipe-application/xml=?
will henceforth display XML
``as is''
(The same could also be achieved by adding a MIME type marker with the
mimetype
command.
And [Option]ally MIME type handlers may be defined via
Sx The Mailcap files
--- these directives,
copiousoutput
has already been used, should be referred to for further documentation.
The question mark
`?'
can in fact be used as a trigger character to adjust usage and behaviour
of a following shell command specification more thoroughly by appending
more special characters which refer to further mailcap directives, e.g.,
the following hypothetical command specification could be used:
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, e.g.,
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.
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 recipient's 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's addresses
using different encryption keys, decryption might fail.
For signing and decryption purposes it is possible to use encrypted
keys, and the pseudo-host(s)
`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)
will be used for performing any necessary password lookup,
therefore the lookup can be automated via the mechanisms described in
Sx On URL syntax and credential lookup .
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 needed passwords would then be looked up via the pseudo hosts
`bob [at] exam.ple.smime-cert-key'
(and
`bob [at] exam.ple.smime-cert-cert'
) .
To include intermediate certificates, use
smime-sign-include-certs
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,
e.g., 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
`Ri ,
'
likewise for
``lv''
LV
will optionally be set to
`-c'
Alse see
colour-pager
The content of these files is interpreted as follows:
Unless S-nail is about to enter interactive mode syntax errors that occur
while loading these files are treated as errors and cause program exit.
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 also ignored.
All other lines form individual entries that must adhere to the syntax
described below.
To extend a single entry (not comment) its line can be continued on
follow lines if newline characters are
``escaped''
by preceding them with the reverse solidus character
`\'
The standard does not specify how leading whitespace of follow lines
is to be treated, therefore S-nail retains it.
``Mailcap''
entries consist of a number of semicolon
`;'
separated fields, and the reverse solidus
`\'
character can be used to escape any following character including
semicolon and itself.
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 content is ignored (removed).
The first field defines the MIME
`TYPE/SUBTYPE'
the entry is about to handle (case-insensitively, and no reverse solidus
escaping is possible in this field).
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 defines the shell command which shall be used to
``display''
MIME parts of the given type; it is implicitly called the
view
command.
For data
``consuming''
shell commands message (MIME part) data is passed via standard input
unless the given shell command includes one or more instances of the
(unquoted) string
`%s'
,
in which case these instances will be replaced with a temporary filename
and the data will have been stored in the file that is being pointed to.
Likewise, for data
``producing''
shell commands data is assumed to be generated on standard output unless
the given command includes (one ore multiple)
`%s'
In any case any given
`%s'
format is replaced with a(n already) properly quoted filename.
Note that when a command makes use of a temporary file via
`%s'
then S-nail will remove it again, as if the
x-mailx-tmpfile
x-mailx-tmpfile-fill
and
x-mailx-tmpfile-unlink
flags had been set; see below for more.
The optional fields either define a shell command or an attribute (flag)
value, the latter being a single word and the former being a keyword
naming the field followed by an equals sign
`='
succeeded by a shell command, and as usual for any
``Mailcap''
content any whitespace surrounding the equals sign will be removed, too.
Optional fields include the following:
The standard includes the possibility to define any number of additional
entry 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.
E.g., if a
view
command needs to specify the
needsterminal
flag, but the
compose
command shall not, the following will help out the latter (with enabled
debug
or an increased
verbose
level S-nail will show information about handler evaluation):
In fields any occurrence of the format string
`%t'
will be replaced by the
`TYPE/SUBTYPE'
specification.
Named parameters from the
`Content-type:'
field may be placed in the command execution line using
`%{'
followed by the parameter name and a closing
`}'
character.
The entire parameter should appear as a single command line argument,
regardless of embedded spaces; thus:
Note that S-nail does not support handlers for multipart MIME parts as
shown in this example (as of today).
S-nail 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.
S-nail implements a parser that supports a superset of the original BSD
syntax, but users should nonetheless be aware of portability glitches
of that file format, shall their
.netrc
be usable across multiple programs and platforms:
Of the following list of supported tokens S-nail only uses (and caches)
machine
login
and
password
At runtime the command
netrc
can be used to control S-nail's
.netrc
cache.
As an extension that should not be the cause of any worries
S-nail 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'
Note that 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 support OAuth.
Because of this 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:
Before being able to use OAUTHBEARER, some hurdles must be taken.
Using GMail as an example, an application (a simple name) needs to be
registered, for which credentials need to be created.
This configuration step generates a
``client ID''
and a
``client secret''
These two strings need to be saved locally in a secure way.
For GMail these initial configuration steps can be performed via
Lk https://developers.google.com/identity/protocols/OAuth2 .
Thereafter access tokens can be requested, the program available for
download do do this for a GMail account is
Lk https://github.com/google/:gmail-oauth2-tools/:blob/:master/:python/:oauth2.py :
S-nail does not (yet) offer the possibility to (lazy) expand aka run
shell commandos which are embedded in variable content, or periodically
run some command, therefore keeping an access token up-to-date from
within it can only be performed by setting the hook
on-main-loop-tick
or (for sending only)
on-compose-splice
For more on authentication please see the section
Sx On URL syntax and credential lookup .
To overcome the situation, use, e.g., the program
cat(1),
in conjunction with the command line 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.
E.g., the terminal this is typed on produces some false sequences, here
an example showing the shifted home key:
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, e.g., the following lists 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.
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.
This man page is derived from
``The Mail Reference Manual''
that was originally written by Kurt Shoens.
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, e.g., from within s-nail:
`?'
Ns Ic eval Ns Ic mail Ns $contact-mail .
Including the
verbose
output of the command
version
may be helpful, e.g.,
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 one or 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 old, traditional 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, e.g., 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, e.g.,
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, e.g.,
? 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
? 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
}
# E.g.
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 Status
? digmsg $msgno header show Status;readall x;echon $x
212 Status
RO
? 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>
[v15-compat] protocol://[user[:password]@]host[:port][/path]
[no v15-compat] protocol://[user@]host[:port][/path]
? filetype \
gzip 'gzip -dc' 'gzip -c' \
zst.pgp 'gpg -d | zstd -dc' 'zstd -19 -zc | gpg -e'
? 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
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" ==?case 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.:><><>
$ LC_ALL=C printf 'echon "hey, "\nread a\nyou\necho $a' |\
LC_ALL=C 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 compose mode, and are used to perform
special functions when composing messages.
Command escapes are only recognized at the beginning of lines, and
consist of a trigger (escape), and a command character.
The actual escape character can be set via the internal variable
escape
it defaults to the tilde
`~'
Otherwise ignored whitespace characters following the escape character
will prevent a possible addition of the command line to the [Option]al
history.
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
? 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 user [at] exam.ple
$ </dev/null s-nail -:/ -Smta=test://./xy -s ub user [at] exam.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 vexpr 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 substring "${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 finishs anyway)
endif
endif
}
set on-compose-splice=ocsm
? set pipe-X/Y='?!++=? vim ${MAILX_FILENAME_TEMPORARY}'
if [ "$LC_ALL" == C ] || [ "$LC_CTYPE" == C ]
unset sendcharsets-else-ttycharset
end
# Create local proxy server in terminal 1 forwarding to HOST
$ ssh -D 10000 USER [at] HOST
# Then, start a client that uses it in terminal 2
$ s-nail -Ssocks-proxy-USER [at] HOST=localhost: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
# Well that actual program specific configuration section
# now can map individual tls-config-module names to sections,
# e.g., 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 that, e.g., 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 ...]
# E.g.: text/html html htm
[type-marker ]type/subtype extension [extension ...]
The Mailcap files
This feature is not available in v14.9.0, sorry!
RFC 1524 defines a
``User Agent Configuration Mechanism''
which S-nail [Option]ally supports (see
Sx HTML mail and MIME attachments ) .
It defines a file format 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
``mailcap''
files and the
MAILCAPS
environment variable that can be used to overwrite that (repeating here
that it is not a search path, but instead a path search specification).
Any existing files will be loaded in sequence, appending any content to
the list of MIME type handler directives.
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
application/pdf; \
infile=%s\; \
trap "rm -f ${infile}" EXIT\; \
trap "exit 75" INT QUIT TERM\; \
mupdf %s; \
x-mailx-async; x-mailx-tmpfile-keep
application/*; echo "This is \"%t\" but \
is 50 \% Greek to me" \; < %s head -c 1024 | cat -vet; \
copiousoutput; x-mailx-noquote
The .netrc file
The
.netrc
file contains user credentials for machine accounts.
The default location
~/:.netrc
may be overridden by the
NETRC
environment variable.
It is possible to load encrypted
.netrc
files by using an appropriate value in
netrc-pipe
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
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,
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 refreshed via the web periodically; in
Kerberos / GSSAPI the local programs
kinit(1)
and
kdestroy(1)
offer user local control, the latter also while offline.
$ 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
$ # The last three are the actual token responses.
$ # To refresh the granted token:
$ python oauth2.py --user=EMAIL \
--client-id=THE-ID --client-secret=THE-SECRET \
--refresh-token=THE-REFRESH-TOKEN
Not "defunctional", but the editor key does not work
It can happen that the terminal library (see
Sx On terminal control and line editor,
bind
termcap
reports different codes than the terminal really sends, in which case
S-nail will tell that a key binding is functional, but will not be able to
recognize it because the received data does not match anything expected.
Especially without the [Option]al terminal capability library support one
reason for this may be 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.
The
verbose
listing of
bind ings will show the byte sequences that are expected.
? 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 mail-patch HEAD^ |
s-nail -Athe-account-you-need -t RECEIVER
Howto handle stale dotlock files
file
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)