Souvent, j'utilise la fonctionnalité alias de mutt
pour envoyer un message à de plus grands groupes de personnes (légitime, pas de spam!). Normalement, je place l'alias dans le champ Bcc:
pour annuler les collecteurs de spam et pour des raisons de confidentialité (tous les destinataires ne se connaissent pas).
Par accident, je place parfois l'alias dans le champ To:
ou Cc:
où il est développé, révélant toutes les adresses de tous les destinataires. C'est très mauvais, car une fois envoyé, l'information est divulguée, et il n'y a pas de return possible.
Comment puis-je faire en sorte que mutt
refuse d'envoyer un courrier, s'il y a plus que, par exemple, 1 input dans le To:
ou 5 inputs dans le champ Cc:
Amélioration: Comment puis-je faire envoyer le courrier de toute façon, si j'ajoute un en-tête défini par l'user, par exemple, X-limit-cc: 50
?
La mise en place d'un service de list de diffusion séparé n'est pas ce que je request, mais plutôt une solution distincte au problème.
AFAIK, Mutt lui-même ne peut pas faire de telles vérifications, mais il y a une solution de contournement! L'idée est de redéfinir la variable $sendmail
pour utiliser un wrapper qui vérifiera le courrier avant de l'envoyer. Par exemple, dans votre file .muttrc
:
set sendmail=$HOME/scripts/sendmail-mutt
Ce script peut se terminer par une erreur (état de sortie différent de zéro) ou se terminer avec quelque chose comme:
exec /usr/sbin/sendmail -oem -oi "$@"
dans un script shell, ou:
exec qw(/usr/sbin/sendmail -oem -oi), @ARGV;
en Perl.
#!/bin/bash set -u -e -C; shopt -s nullglob; # This script can be used as a `sendmail` replacement in `mutt`. It # performs several checks on the mail before sending ist, and it's # easy to modify these checks, or to add more. Currently, these are: # # attachment — fail on non-multipart message if text contains # keywords referring to an attachment (English, German). # # size — refuse to send excessively large mails. # # fixme — refuse to send mail containing the word `FIXME`. # # longline — refuse to send mails wit long lines, unless paths # (URLs) containing two slashes, or quoted. # # limit-to, limit-cc — limit number of recipients in the according # header. Better use Bcc field. # # Each of the tests can be disabled by puttig its name in an # `X-checks` header field. Eg, `X-checks: longline limit-cc` allows # to send mails with long lines to unlimited number of recipients in # the Cc field. # # To use this script, install it where it can be found, and configure # mutt accordingly. I have stored this script as `~/.mutt/sendmail`, # and my `~/.mutt/muttrc` contains the line # # set sendmail = "~/.mutt/sendmail" # # When sending a mail, it is stored as `mutt-sendmail.*` in a # temporary location, from where it is accessible for checks. On # success, the mail is sent, otherwise this script fails. The # temporary file is deleted. # ---- Configuration of this script ---------------------------------- # Mail is sent using `${sendmail} "$@" <"${wholemail}"`, see last line # of the script. sendmail=/usr/bin/msmtp; # You may explicitly skip some tests by putting their name in a header # field of your mail. On checking, these names are printed to stderr. # The name of the header is: myhdr='X-checks'; # ---- The script ---------------------------------------------------- # print message to stderr, maybe fail function err { echo "$@" >&2; exit 1; } function warn { echo "$@" >&2; } # store the mail in a temporary file wholemail="$(mktemp -t mutt-sendmail.XXXXXXXXXX)" && trap "rm -f '${wholemail}'" EXIT && cat >| "${wholemail}" || err 'cannot create temporary file'; # get the header, with indented lines joined header="$(sed -rn ':a;/^$/q;$!N;s/\n\s+/ /;ta;P;D' "${wholemail}")"; # get values of one particular header, each occurence on one line function getHeader { sed -rn "s/^${1}:\s+//p" <<< "$header"; } # use this function to read body of message function getBody { sed '1,/^$/d' "${wholemail}"; } # get list of checks to be ignored for this particular mail checks="$(getHeader "${myhdr}")"; function requested { if grep -q "${1}" <<< "${checks}"; then warn "${myhdr}: ${1} — skipping"; return 1; else warn "no ${myhdr}: ${1}"; return 0; fi; } # --- do all tests here ---------------------------------------------- # # `$wholemail` contains the file name of the whole mail, as passed to # sendmail. # `getBody` writes the body of the mail to stdout. # `getHeader foo` writes one line for each value of a `foo:` header. # `requested bar` fails if a `$myhdr` header contains `bar`. # make a keyword search on the whole email, if it is not multipart. requested 'attachment' && getHeader "Content-Type" | grep -vq multipart && grep -v '^>' "$wholemail" | grep -Eni 'attach|anhang|hängt|unten' && err "no multipart message, but hints to attachment."; # reject emails greater than $maxsize bytes maxsize='32768'; requested 'size' && test "$(stat -c%s "${wholemail}")" -gt "${maxsize}" && err "bigger then ${maxsize} bytes."; # reject emails containing FIXME requested 'fixme' && getBody | grep -n FIXME && err "FIXME keyword found."; # reject emails with long lines maxline=78; requested 'longline' && test "$(getBody | grep -Ev '^>|/.*/' | wc -L)" -gt "$maxline" && err "lines longer than $maxline chars found."; # count number of recipients requested 'limit-to' && test "$(getHeader "To" | grep -o ',' | wc -l)" -gt 2 && err 'Too many recipients in the To field.'; requested 'limit-cc' && test "$(getHeader "Cc" | grep -o ',' | wc -l)" -gt 5 && err 'Too many recipients in the Cc field.'; # --- now send the mail ---------------------------------------------- #err 'debugging mode: not sending'; ${sendmail} "$@" <"${wholemail}";