S-nail

S-nail is a mail processing system with a command syntax reminiscent of ed with lines replaced by messages. It is intended to provide the functionality of the POSIX mailx command and offers (mostly optional) extensions for line editing, IDNA, MIME, S/MIME, SMTP and POP3 (and IMAP). It is usable as a mail batch language. This overview page was written based on version v14.7.10 of S-nail.

Quick shot

Since the systemwide Arch Linux configuration file (/etc/mail.rc) brings in some useful standard settings sending mail over the local mail-transport-agent (MTA) can be as easy as follows:

# echo 'This is the mail body' | mailx -s 'This is the subject' -a some_attachment.txt some@where

More is possible if the expandaddr option is set:

# echo bla | mailx -Sexpandaddr -s test ./mbox.mbox
# echo bla | mailx -Sexpandaddr -s test '|cat >> ./mbox.mbox'

First configuration adjustments

Configuration files are the user-specific $HOME/.mailrc and the systemwide /etc/mail.rc, the latter of which is subject to the usual ArchLinux update mechanism. Place the following in your private user-specific configuration file, adjusting bold strings. And note that all the remaining examples in this document are based upon this configuration template.

# All the examples require v15-compat!
set v15-compat

# ArchLinux-specific locations of certificates.
# Since these are subject to the ArchLinux update mechanism,
# use only those, don't try to load OpenSSL builtin ones.
# And use the TLS specific set: see "man 8 update-ca-trust"
#set ssl-ca-dir=/etc/ssl/certs
set ssl-ca-file=/etc/ssl/certs/ca-certificates.crt
set ssl-no-default-ca

# Require secure transport via protocol version TLS v1.2, exclusively.
# (Change this only [best on a per-account base, as below]
# when the remote server doesn't support this protocol!)
set ssl-method=tls1.2

# Request strict transport security checks
set ssl-verify=strict

# Essential setting: choose allowed character sets
# (Have a look at the "CHARACTER SETS" manual section)
set sendcharsets=utf-8,iso-8859-1

# When sending messages, wait until the Mail-Transfer-Agent finishs.
# Only like this you'll be able to see errors reported through the exit
# status of the MTA (including the builtin SMTP one)!
set sendwait

# To save a copy of sent messages somewhere (this will end up in your home directory)
set record=sentmail.mbox

# This may be interesting to gain some speedup when sending mail
set mimetypes-load-control

# This is optional, but you should get the big picture
# by reading the manual before you leave that off
set from="Your Name <youremail@domain>"

When in the below USER and PASS informations are specified as part of an URL (other possibilities exist) they must become URL percent encoded; S-nail offers the urlencode command which does this for you:

# printf 'urlencode USER PASS\nx\n' | mailx -#

Of course: printf as well as S-nail / mailx are subject to your locale settings:

# # In UTF-8:
# printf 'urlencode SPAß\nx\n' | mailx -#
  in: <SPAß> (5 bytes)
  out: <SPA%C3%9F> (9 bytes)
# # In ISO-8859-1:
# printf 'urlencode SPAß\nx\n' | mailx -#
  in: <SPAß> (4 bytes)
  out: <SPA%DF> (6 bytes)

Sending mail with an external SMTP server

To send messages via the builtin SMTP (Simple Mail Transfer Protocol) client to an external SMTP server, several options have to be set or adjusted. Add the following as appropriate to the configuration as above, changing bold strings. Setting smtp-auth is usually needed, most likely it will be smtp-auth=plain.

# It may be necessary to set hostname and/or smtp-hostname
# if the "SERVER" of smtp and "domain" of from don't match.
# Reading the "ON URL SYNTAX.." and smtp manual entries may be worthwhile
# (Remember USER and PASS must be URL percent encoded)
set smtp=(smtp[s]/submission)://[USER[:PASS]@]SERVER[:PORT] \
    smtp-auth=login/plain... \
    smtp-use-starttls

# E.g. here is a real life example of a very huge free mail provider
# (Activate this account via mailx -AXooglX from the command line,
# or use the ? acc[ount] XooglX command in interactive mode)
account XooglX {
   # Localize options, forget them when changing the account
   localopts 1
   # (The plain smtp:// proto is optional)
   set smtp=USER:PASS@smtp.gmXil.com \
       smtp-auth=plain smtp-use-starttls
   set from="Your Name <youremail@domain>"
}

# And 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
account XandeX {
   localopts 1
   set smtp=smtps://USER:PASS@smtp.yaXXex.ru:465 smtp-auth=plain \
       hostname=yaXXex.com smtp-hostname=
   set from="Your Name <youremail@domain>"
}

Note that, when storing passwords in $HOME/.mailrc, you should set appropriate permissions with chmod 0600. You can also set the netrc-lookup option and store user credentials in $HOME/.netrc (or $NETRC) instead; e.g., here is a real life example that sets up SMTP, POP3 as well as IMAP, storing all user credentials in there:

account XandeX {
   localopts 1
   set netrc-lookup
   #set agent-shell-lookup="gpg -d .pass.gpg"
   set smtp=smtps://smtp.yXXXXx.ru:465 smtp-auth=plain \
       smtp-hostname= hostname=yXXXXx.com
   set pop3-keepalive=240
   shortcut pop pop3s://pop.yXXXXx.ru
   ghost xp 'fi pop'
   set imap-keepalive=240
   shortcut imap imaps://imap.yXXXXx.ru
   ghost xi 'fi imap'
 }

and, in $HOME/.netrc:

machine *.yXXXXx.ru login USER password PASS

(Here USER and PASS are clear text, not URL encoded.) You can furtherly diversify things and use encrypted password storage, since ArchLinux compiles in password agent support. To adjust the example, simply don't specify the password PASS token in $HOME/.netrc but instead uncomment the agent-shell-lookup line in the example account above. The encrypted password storage .pass.gpg can be created like this:

# echo PASS > .pass
# gpg -e .pass
# eval `gpg-agent --daemon --pinentry-program=/usr/bin/pinentry-curses --max-cache-ttl 99999 --default-cache-ttl 99999`

Test the configuration (use the -d command line option for a(n almost) dry-run):

# echo test-body | mailx -vv -A XandeX -s test-subject some@where

Interactive usage

The ArchLinux version of S-nail includes the builtin command line editor with history capabilities as well as regular expression and coloured message display support. Because S-nail strives for POSIX standard compliance some settings have to be adjusted before using it interactively doesn't baffle all descriptions, however. Reading the lengthy and yet still pretty awkward manual is unavoidable, but add, at a minimum, the following on top of the example configuration:

# (The template configuration /etc/mail.rc also provides some commented basics;
# in particular it shows all options that POSIX mandates at program startup)

# Start into interactive mode even if the standard mailbox is empty
set emptystart

# Default directory where we act in (relative to $HOME), list content with folder command
set folder=mail
# The MBOX file -- the leading `+' means "relative to folder"
set MBOX=+mbox

set DEAD=+dead

# When composing a message, let period `.' on a line by itself finalize composition,
# before start directly into $EDITOR
set dot 
set editalong

# Start $PAGER when a message is longer than VALUE lines; without VALUE: screen $LINES
set crt=

# Colourize headers when displaying messages (note that $PAGER may require special flags,
# e.g., less(1) needs the -R option; S-nail will however set the $LESS environment
# variable accordingly, but only if that was not set before..)
set colour-pager

# A nicer prompt
set prompt="\033[31m?\?[\$ \@]\& \033[0m"

# Add more entries to the history
set history-gabby

# Make the history persistent 
set NAIL_HISTFILE=+.s-nailhist
set NAIL_HISTSIZE=-1

# When displaying messages, show only these headers
retain date from to cc subject

# Try to get around weird MIME attachment specifications
# (This option can take a value, see the manual for more)
set mime-counter-evidence

# Force some MIME attachments to be displayed as raw text
# (instead of simply not being displayed at all).
# Look once at the output of the command mimetypes (or try: ?mime)
set pipe-application/javascript=@
set pipe-application/json=@
set pipe-application/x-latex=@
set pipe-application/x-perl=@
set pipe-application/x-sh=@
set pipe-application/x-shar=@
set pipe-application/x-tex=@
set pipe-application/x-texinfo=@
set pipe-application/x-xfig=@

# Display HTML parts inline
#set pipe-text/html="lynx -stdin -dump -force_html"

# Create some new commands so that, e.g., `ls /tmp' will..
ghost ls '!ls -latro'
ghost ps '!ps axu'

Once you're in it, the command list will print all available builtin commands. ArchLinux compiles in the "DOCSTRINGS" feature, so that typing `?X' tries to expand "X" and print a help string; since S-nail will allow abbreviations of all commands this is sometimes handy; try, e.g., ?h, ?he and ?hel ... The command help will print a short summary of the most frequent used commands.

I'm in!

When starting into interactive mode a summary of the content of the initially opened mailbox is printed, via the headers command. In the header display messages are given numbers (starting at 1) which uniquely identify messages. Messages can be printed with the print command, or short: p. By default the current message (dot) is printed, but just like with many other commands it is possible to specify lists of messages, as is documented in the manual section "Specifying messages"; e.g., p:u will display all unread messages, p. will print the dot, p 1 5 will print the messages 1 and 5 and p- and p+ will print the last and the next message, respectively. Note that simply typing RETURN in an empty line acts like next (n), and thus prints the next message.

The command from (f) is nice for an overview, e.g., f '@<@arch linux' will print the header summary of all messages that contain the string "arch linux" in some message header, whereas f '@arch linux' will only match those with "arch linux" in their subject; finally, the regular expression f @^A[^[:space:]]+ finds... well, a complaint of the ArchWiki maintainer about the content of this page, ugh; that is, be aware that quoting may be necessary when there is whitespace in search expressions etc.

  • file and File open a new mailbox, the latter in readonly mode (which can be handy to avoid flag updates etc.)
  • newmail (dependent on the mailbox, checks for new mail and) prints a listing of new messages
  • he (headers) reprints the message list
  • z-, z+, z0, z$ scroll through the header display (dependent on the terminal you are using the Home/End/PageUp/PageDown keys will be working aliases)
  • folders shows a listing of mailboxes under the currently set folder
  • r replies to all addressees of the current message
  • R replies to the sender of the current message
  • move or mv moves (a) message(s)
  • (un)flag marks (a) message(s) as (un)flagged
  • new marks (a) message(s) unread
  • seen marks (a) message(s) read
  • P prints (a) message(s) with all headers
  • p prints (a) message(s) and all non-ignored headers.
  • show prints the raw message of content of (a) message(s)

Message composition

Composition is started by typing mail user@host or by replying to a message. When you return from $EDITOR (assuming editalong is set) you'll find yourself in the native editor, where many operations can be performed using tilde escapes (short help available via ~?). Of particular interest is ~@, which allows the attachment list to be edited.

To send the mail, signal EOT with Ctrl+d or type "." on its own line (the latter requires the dot option).

Using an IMAP mailbox

The following is only a quick hint, it is also possible to define folder to point to an IMAP server folder, for example.

set v15-compat

# or many servers will expire the session
set imap-keepalive=240
set imap-cache=~/.imap_cache

# You may want to define shortcuts to folders, for example:
shortcut myimap "imaps://USER:PASS@server:port"