# alpine, nagios and display filters

I’ve been aware of alpine’s “display filter” feature for some time, used as it is for on-the-fly GPG interpretation amongst other things. But I’d never really examined the feature before now. The manual says:

The [filter] command is executed and the message is piped into its standard input. The standard output of the command is read back by Alpine.

This says it all: display filters turn out to be an extremely powerful generic mechanism for reformatting and enhancing text; it works particularly well when applied to machine generated messages. Maybe its power is best explained by the example which caused me to investigate in in the first place:

### An example (the nagios bit):

A longstanding irritant to me has been a my difficulty in shutting nagios up. For a long time I’ve been relying on a filter to parse nagios’ incoming emails and generate a URL. The display filter closes the loop, automatically injecting that magic URL at the end of the message.

Here’s a simplified version of the filter, reminiscent of the one in the previous post:


#!/usr/bin/gawk -f
# Crude detection of problem type for acknowledgement link
# Don't forget to validate these inputs...
/Notification Type: / { TYPE=$3; } /Service:/ { SERVICE=substr($0,length($1)+1,length($0)); }
/Host:/ { HOST=\$2; }
# Important: this is a filter, so don't forget to print input lines back out!
// {print;}
# Now add the acknowledgement link below:
END {
if (HOST && TYPE == "PROBLEM") {
# this is the script which generates the URL.
# ideally this should be replaced with some awk to do the same thing
cmd="~/bin/nagack "HOST" "SERVICE
cmd | getline url
close(cmd)
# now add the link to the email.
print "[Acknowledgement link: "url" ]"
}



Now, to alpine’s Display Filters setting, add:


Display Filters    = _LEADING("***** Nagios")_ /path/to/nagios-filter-script


that’s it! My emails from nagios now look like:


***** Nagios *****
Service: ssh
Host: myhost
State: CRITICAL
...
[Acknowledgement link: https://nagiosserver/nagios/cgi-bin/cmd.cgi?cmd_typ=3... ]



### Important caveats:

• If you’re not careful, by adding these filters you will have introduced a trivial local shell injection attack to your mail client. Validate your inputs — just like I didn’t above!
• The developers have this to note about running filters on every message:

Testing for the trigger and invoking the filter doesn’t come for free. There is overhead associated with searching for the trigger string, testing for the filter’s existence and actually piping the text through the filter. The impact can be reduced if the Trigger Modifying Tokens […] are employed.

I’ve certainly noticed a small (immeasurable, but noticeable) delay in opening messages with triggers. Large enough to be annoying if I’d planned to filter every message, even using a trivial bash filter which itself is quick to complete.

• One additional caveat on DICE: if your alpine session outlives your AFS credentials, and you’ve stored your display filters in your home directory, you will find that the display filters simply disappear. As good a reminder as any to renew, and thankfully a “renc” is all that’s required to restore your filters to former glory.

That’s it! Surprisingly trivial, and with a handful of these triggers, the benefits are huge. I’m using five so far, mostly generating clickable links to some of our automated systems, but I’d be pleased to hear what other people are doing with these filters.

# something I didn’t know about mailcap

For a few weeks I’ve been idly wondering why I’ve been unable to get alpine to take advantage of the syntax-highlighted goodness of vim, when viewing attached patches. Having just won another small victory against my own ignorance, I thought it best to share.

Like any sensible mail client, alpine chooses viewers for attached files using lookups of the system mailcap files, /etc/mailcap and ~/.mailcap. Enabling plain-text viewing in vim should be as simple as assigning vim to the appropriate type(s) in ~/.mailcap (and, for some types, unchecking the alpine Show Plain Text Internally preference).

However, attempts to open plain-text files (in this case specifically text/x-patch) in the multi-talented vim editor failed: alpine simply returned a “finished” status, as if viewing had been successful. My suspicion was confirmed when I redirected vim’s ouptut (hidden by alpine) to a file:

Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal


The latter message was well known to me; it’s usually triggered by my forgetting to affix the “stdin hyphen” whilst piping input to vim.

The problem is that both vim and alpine require control of the terminal to function; vim does not simply return beautifully ANSI-escaped coloured text for later display. Attempts to somehow force alpine to relinquish control of the terminal, or for vim to take it, failed until I discovered the secret amongst mailcap’s flags, as described by the manual:

    copiousoutput
This flag should be given whenever the interpreter is
capable of producing more than a few lines of output
on stdout, and does no interaction with the user. [...]


I’d seen this, but for some reason had always assumed ‘copiousoutput’ to be some sort of magic external pager, with no connection to the mailcap system. Reading on, the solution was clear:

    needsterminal
If this flag is given, the named interpreter needs to
interact with the user on a terminal. [...]


So, a few amendments to ~/.mailcap later:

  Text/X-Patch;    /usr/bin/vim -R -- '%s'; needsterminal


and alpine had gained magical powers to invoke terminal-based viewers. There’s more to this; in particular the ‘edit=‘ and ‘compose=‘ fields, not to mention print support. But that’s enough to get basic viewing in vim.

+1 for reading the manual. -1 for not reading it before embarking on terminal manipulation…