wiki:ConfigTricks/CheckAttach

Version 4 (modified by MichaelRay, 4 years ago) (diff)

spelling. marc -> marc.info domain changed assuming link will still work.

This script is provided by MuttChannel user "rev_"(?) to remind you of missing attachments after you finish the msg and are ready to send it, but before it actually is being sent out by the system (sendmail).

You get the idea how it works to implement it in any shell/ code language you want or do other control stuff. Principle:

  1. mutt hands over finished full msg with headers as STDIN to $sendmail, muttrc: set sendmail="this-script"
  2. it applies various user-definable checks on the msg,
  3. if they fail, ask user for confirmation:
    • return if something is wrong
    • continue when you want it to go as it is now.

Read '#'-comments to better understand.


#!/bin/bash

SENDMAIL=/usr/sbin/sendmail

###
# this script uses a GUI app called "zenity" to ask for confirmation,
# if not in GUI, just let it pass. If you want TUI (not GUI) query,
# which means you replace "zenity" with something else, then
# drop this DISPLAY check.
###
if [ -z "$DISPLAY" ]; then
    exec $SENDMAIL "$@"
fi

###
# save msg in file to re-use it for multiple tests
###
t=`mktemp -t mutt.XXXXXX` || exit 2
cat > $t

###
# define tests for: anything you can think of can be done.
# the return code of last exec'ed cmd is used in final decision below
###
function multipart {
    grep -q '^Content-Type: multipart' $t
}

function word-attach {
    grep -v '^>' $t | egrep -q 'attach\|bijgevoegd\|bijvoeg\|patch'
}

###
# query function must return "true" to let the msg pass.
###
function ask {
    zenity --question --title 'mutt' --text 'Did you include the attachment (if you wanted to)?'
}

###
# FINAL DECISION:
# chain series of functions, use ! || && for logic connections,
# see "man $SHELL" for more possibilities like grouping, dependencies.
###
if multipart || ! word-attach || ask; then
    $SENDMAIL "$@" < $t
    status=$?
else
    status=1
fi
rm -f $t
exit $status

The above script uses zenity, which only works with X, so it's not much use in console mode. The script below is for console mode users. Maybe one day I make a hybrid solution.

Unfortunately it's not possible to query the user from the script in console mode (at least I haven't found a way) because stdin is already redirected. So instead this version simply aborts sending the message if it senses there is an attachment missing. If really no attachment was intended then the user must include "X-attached: none" in the mail headers. TODO: someone please add a link to the necessary configuration to edit mail headers as part of the mail composition. (Footnote: It would have been nice to let the user add a blank header, e.g. just "X-attached:", but it seems mutt removes such headers before sending.)

Save the script as: /usr/local/bin/mutt_check_attachment_before_send.sh

Edit muttrc to have this line:

set sendmail = "/usr/local/bin/mutt_check_attachment_before_send.sh /usr/lib/sendmail -oem -oi"

#!/bin/bash

##
## Script: /usr/local/bin/mutt_check_attachment_before_send.sh
##
## Source: http://wiki.mutt.org/?ConfigTricks/CheckAttach
##
## Edit muttrc to have this line:
## set sendmail = "/usr/local/bin/mutt_check_attachment_before_send.sh /usr/lib/sendmail -oem -oi"
##

## Attachment keywords that the message body will be searched for:
KEYWORDS='attach|bijgevoegd|bijvoeg|patch'

## Check that sendmail or other program is supplied as first argument.
if [ ! -x "$1" ]; then
    echo "Usage: $0 </path/to/mailprog> <args> ..."
    echo "e.g.: $0 /usr/sbin/sendmail -oem -oi"
    exit 2
fi

## Save msg in file to re-use it for multiple tests.
TMPFILE=`mktemp -t mutt_checkattach.XXXXXX` || exit 2
cat > "$TMPFILE"

## Define test for multipart message.
function multipart {
    grep -q '^Content-Type: multipart' "$TMPFILE"
}

## Define test for keyword search.
function word-attach {
    grep -v '^>' "$TMPFILE" | grep -E -i -q "$KEYWORDS"
}

## Header override.
function header-override {
    grep -i -E "^X-attached: *none *$" "$TMPFILE"
}

## FINAL DECISION:
if multipart || ! word-attach || header-override; then
    "$@" < "$TMPFILE"
    EXIT_STATUS=$?
else
    echo "No file was attached but a search of the message text suggests there should be one.  Add a header \"X-attached: none\" to override this check if no attachment is intended."
    EXIT_STATUS=1
fi

## Delete the temporary file.
rm -f "$TMPFILE"

## That's all folks.
exit $EXIT_STATUS

Another simple script was posted to mutt-dev http://marc.info/?l=mutt-dev&m=110663305206264&w=2