Procmail
Mail::Audit
Mettre de l'ordre dans mon répertoire Mail
Configuration de Gnus
Rafinements
Installation du filtre
Que se passe-t-il en cas d'erreur ?
Obsolete
Ces notes expliquent comment je me suis débarassé de Procmail.
On peut faire deux critiques à procmail.
D'une part, sa syntaxe est particulièrement cryptique. Ainsi, mon ~/.procmailrc commençait par des rappels de cette syntaxe.
# b Feed the body to the pipe (default). # f Consider the pipe as a filter. # h Feed the header to the pipe (default). # w Wait for the filter or program to finish # and check its exitcode (normally ignored); # if the filter is unsuccessful, then the # text will not have been filtered. # A This recipe will depend on the last preceding # recipe (on the current block-nesting level) # without the `A' or `a' flag. This allows you to # chain actions that depend on a common condition.
Plus loin, dans le même fichier (auquel je n'ai pas vraiment touché depuis près de trois ans), je constate que les règles commencent l'une des trois lignes suivantes. Quelle est la différence ? Que signifient les deux points au début ? à la fin ? le zéro ?
:0 :0 c :0: :0 B :
D'autre part, ce n'est pas un vrai langage de programmation, il y a donc certaines choses que l'on ne peut pas faire (on peut toujours s'en tirer en écrivant un programme externe, qui va lire un message ou son en-tête puis dire à procmail (à l'aide de son code de retour) ce qu'il faut en faire).
Mail::Audit est un module Perl permettant d'écrire des programmes de filtrage de courrier électronique.
http://www.perl.com/pub/a/2001/07/17/mailfiltering.html
Voici le programme que j'utilise réellement.
#!/share/nfs/users1/umr-tge/zoonek/gnu/Linux/bin/perl -w use strict; use Mail::Audit; sub mess { my $mess = shift; open(A, '>>', "/share/nfs/users1/umr-tge/zoonek/log"); print A "$mess\n"; close A; } mess("begin"); my $mail = Mail::Audit->new(emergency=>"~/Mail/emergency_mbox"); $mail->noexit(1); $mail->accept("~/Mail/backup"); $mail->noexit(0); # Mailing lists my %lists = qw( omega-admin Omega pstricks-admin pstricks owner-ctan-ann CTAN-Announce owner-maple-list maple ); foreach my $a (keys %lists){ # PROBLEME: il faudrait une méthode "sender" $mail->accept("~/Mail/$lists{$a}.spool") if $mail->header =~ m/^Sender:.*$a/m; } mess(" not a mailing list"); # Important mails that should be _copied_ in a folder my %important = qw( paypal Argent florachanxxx Argent ebay Argent amazon Argent jamall Argent bk1 Argent ); $mail->noexit(1); foreach my $a (keys %important) { $mail->accept("~/Mail/$important{$a}.spool") if $mail->from =~ m/$a/i or $mail->to =~ m/$a/i; } $mail->noexit(0); mess(" perhaps not something important"); # Poubelle my @poubelle = qw/glegrand@ccr.jussieu.fr/; foreach my $a (@poubelle) { $mail->accept("~/Mail/poubelle") if $mail->from =~ m/$a/; } my $body = join('', @{ $mail->body }); $mail->accept("~/Mail/poubelle") if $body =~ m/armée|militaire/; mess(" It dit not go into the trash can"); ## Probablement du spam # Reconnu par son sujet $mail->accept("~/Mail/spam.spool") if $mail->subject =~ m/\b(congratulation|breast|money|mortgage|viagra|sex|cigar)s?\b/i; $mail->accept("~/Mail/spam.spool") if $mail->subject =~ m/\$\s*[0-9,]{3,}/; # Reconnu par son absence de destinataire $mail->accept("~/Mail/spam.spool") unless $mail->to =~ m/(zoonek|jussieu)/ or $mail->from =~ m/(zoonek|jussieu)/ or $mail->cc =~ m/(zoonek|jussieu)/; mess(" no spam"); ## Probablement quelque chose de correct #$mail->accept(); $mail->noexit(1); $mail->accept("~/Mail/zoonek"); $mail->noexit(0); # This should be the very last line mess(" accepting"); $mail->accept(); mess("accepted -- you should NOT be reading this");
Le programme est encore perfectible : j'ai envie de surcharger la méthode accept dans une sous-classe pour indiquer dans un journal (log) ce qui est advenu des messages (cela rendrait mon code plus simple : il n'y aurait plus de mess(...) partout).
Je pourrais aussi me débarasser des $mail->noexit() en définissant deux méthodes $mail->accept_and_leave et $mail->accept_and_continue.
On pourrait aussi rajouter un appel à Mail::SpamAssassin.
A FAIRE
Pour l'instant, il y a : des répertoires correspondant aux diverses mailing lists auxquelles je suis abonné, des fichiers de sauvegarde (sauvegarde des messages avant qu'ils ne passent par procmail, au début de leur passage dans procmail, à la fin de leur passage dans procmail, et aussi les messages rejetés par procmail), des fichiers de sauvegardes divers (innombrables), quelques répertoires de sauvegarde (en particulier pour les sites de commerce élecrtonique que j'utilise).
Les fichiers sont au format mailbox (tout dans un seul fichier, les messages se terminent par une ligne blanche et commencent par m/^From /), les répertoires sont au format nnmh, i.e., un fichier par message.
Je vais changer tout cela. Il y aura juste : les fichiers de sauvegarde automatique, les fichiers *.spool qui contiendront les messages non encore vus par Gnus, un répertoire mail contenant des répertoires correspondant aux différentes mailing lists ainsi que des répertoires : misc, pour le courrier normal, Argent, pour tout ce qui est commerce électronique, spam pour le spam ou les messages qui y ressemblent, Divers pour les messages sauvegardés (je sauvegarderai tout en même temps, en vrac, sans classer les choses par sujet, de manière à pouvoir faire des recherches à l'aide d'un simple grep).
Il faut donc convertir les différents format des fichiers utilisés en quelque chose d'uniforme.
cat **/*(.) > ALL.spool perl -p -i -e 's/^X-From-Line:/From/; s/^From /\n\nFrom /' ALL.spool
Je me retrouve donc avec les fichiers
Mail/Argent.spool Mail/CTAN-Announce.spool Mail/Divers.spool Mail/maple.spool Mail/Omega.spool Mail/pstricks.spool
Je veux que Gnus fasse les choses suivantes.
1. Prendre le courrier dans $MAIL et le mettre dans ~/Mail/mail/misc
2. Prendre le courrier dans les différents ~/Mail/*.spool et le mettre dans le répertoire correspondant ~/Mail/mail/$1
Je commence par effacer complètement la partie de mon ~/.emacs (en fait, ~/.xemacs/init.el) correspondant à Gnus.
(autoload 'gnus "gnus" "The Gnus Newsreader" t) (setq gnus-nntp-server (or (getenv "NNTPSERVER") "news")) (setq gnus-local-domain (or (getenv "DOMAINNAME") "math.jussieu.fr")) (setq gnus-local-organization (or (getenv "ORGANIZATION") "Universite Paris VII")) (setq gnus-default-article-saver 'gnus-summary-save-in-file) (setq gnus-use-generic-from t) (setq gnus-use-generic-path t) (setq gnus-auto-select-same t) (setq news-reply-header-hook nil) (setq gnus-use-long-file-name t) (setq gnus-default-subscribed-newsgroups '("nndoc:gnus-help" "fr.comp.text.tex" "comp.text.tex")) (add-hook 'gnus-post-prepapare-hook 'mime-editor/set-transfer-level-8bit) (add-hook 'gnus-article-display-hook 'gnus-article-highlight) (add-hook 'gnus-article-display-hook 'gnus-article-hide-headers) (setq gnus-group-sort-groups '(gnus-group-sort-by-real-name gnus-group-sort-by-level)) (add-hook 'gnus-summary-exit-hook 'gnus-summary-bubble-group) (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) (add-hook 'gnus-summary-mode-hook 'my-alter-summary-map) (defun my-alter-summary-map () (local-set-key "E" 'gnus-summary-put-mark-as-expirable-next)) ; Essayons de lire notre courrier avec Gnus... ; Je suggère d'utiliser nnmh qui va mettre un fichier par message ; (il y a aussi nnml, qui est beaucoup plus rapide, mais il ; s'attend à trouver une base de données contenant la liste ; des messages. C'est peut-etre un peu difficile à créer automatiquement ; et un peu long à créer lorsque l'on lande Gnus...) (setq gnus-secondary-select-methods '((nnmh "private"))) ;(setq nnmail-spool-file nil) ; Sinon Gnus prend le courrier dans $MAIL ; et je ne le vois pas... (setq nnmail-procmail-directory "Mail") (setq nnmail-use-procmail t) (setq nnmail-procmail-suffix ".procmail")
J'efface les autres fichiers de configuration de gnus
rm ~/.newsrc*
Dans le ~/.xemacs/init.el, on rajoute
(autoload 'gnus "gnus" "The Gnus Newsreader" t)
Ce n'est bien évidemment pas suffisant : quand je lance Gnus, il me propose un unique groupe (l'étoile devant indique le nombre d'articles contenus dans ce groupe : ici, le groupe n'a pas été trouvé).
*: nndraft:drafts
Pour charger les Niouzes, on pourrait ajouter dans le ~/.gnus
(setq gnus-select-method '(nntp "news.jussieu.fr"))
Mais ce n'est pas nécessaire, car ma variable d'environement NNTPSERVER a déjà la bonne valeur
% echo $NNTPSERVER news.jussieu.fr
Il est possible d'avoir un serveur NNTP principal et d'autres secondaires (pour des groupes qui ne sont pas sur le serveur principal : il fut un temps où le groupe fr.lettres.langue.japonaise n'était pas sur news.jussieu.fr), simplement en tapant B une fois Gnus lancé.
Si c'est l'IS qui définit un fichier de configuration général, il peut renseigner la variable gnus-default-subscribed-newsgroups qui contient la liste des groupes par défaut (mais je n'en aurai pas besoin).
(setq gnus-default-subscribed-newsgroups '("nndoc:gnus-help" "fr.comp.text.tex" "comp.text.tex"))
On peut s'inscrire à quelques groupes, en tapant j (jump) pour trouver le groupe puis u (unsubscribe) pour le retenir.
*: nndraft:drafts 249: fr.lettres.langue.japonaise 697: fr.comp.text.tex 221: fr.comp.lang.perl 1092: comp.text.tex 157: comp.lang.perl 4: comp.lang.perl.announce 1568: comp.lang.perl.misc 198: comp.lang.perl.modules 149: comp.lang.perl.tk 40: comp.lang.perl.moderated
Ah, mais ça n'est pas dans l'ordre !
C-c C-s
C'est mieux.
157: comp.lang.perl 4: comp.lang.perl.announce 1568: comp.lang.perl.misc 40: comp.lang.perl.moderated 198: comp.lang.perl.modules 149: comp.lang.perl.tk 1092: comp.text.tex 221: fr.comp.lang.perl 697: fr.comp.text.tex 249: fr.lettres.langue.japonaise *: nndraft:drafts
(On peut aussi sélectionner certains groupe, à l'aide de la commande # pour marquer un groupe ou à l'aide de la commande M w (attention, c'est bien M w et pas M-w) (la commande M U enlève toutes les marques) puis les trier à l'aide de la commande G P a.)
Commandes diverses
a Ecrit un article (dans le groupe courrant) M-g Regarde s'il y a quelque chose de nouveau dans le groupe courrant q Quitte le groupe courrant ou gnus c Quitte le groupe courrant en décrétant que tous les articles ont été lus R répond à l'auteur d'un article en le citant F répond à un article (au groupe entier si c'est un message des Niouzes, à l'auteur et aux gens mis en copie si c'est un courriel). C-k Marque comme lus tous les articles suivants du fil de discussion courrant u Marque l'article courrant comme "non lu" d Marque l'article courrant comme lu (attention : il ne sera pas effacé) E Marque l'article courrant comme expiré (il sera effacé) = Rentre dans un groupe -= Rentre dans un groupe en affichant tous les articles, y compris ceux qui ont déjà été lus
Ajoutons maintenant le mail. Le manuel nous dit que
It's quite easy to use Gnus to read your new mail. You just plonk the mail back end of your choice into gnus-secondary-select-methods, and things will happen automatically.
Par exemple, la ligne suivante prend le courrier dans $MAIL et le met dans ~/Mail/mail/misc
(setq gnus-secondary-select-methods '((nnml "")))
Voilà :
110: comp.lang.perl 2: comp.lang.perl.announce 1235: comp.lang.perl.misc 35: comp.lang.perl.moderated 144: comp.lang.perl.modules 119: comp.lang.perl.tk 80376: comp.text.tex 187: fr.comp.lang.perl 597: fr.comp.text.tex 197: fr.lettres.langue.japonaise 6: nndraft:drafts 1477: nnml:mail.misc
Le problème, c'est que les anciens messages ont disparu ???
Ah, oui : avant j'utilisais nnmh et pas nnml. Dans les deux cas, les messages sont mis chacun dans un fichier, mais avec nnml, il y a en plus une base de données qui permet de les manipuler plus facilement. Il suffit de recréer cette base de données.
M-x nnml-generate-nov-databases
Il reste maintenant le plus dur : ajouter les fichiers *.spool
Après avoir consulté
http://www.gnusfr.org/gen.php4/2002/02/27/27,0,1,0.html http://www.gjefle.com/emacs/dot-gnus-v1.el
j'essaye
(setq mail-sources '((file) (directory :path "~/Mail" :suffix ".spool") ) )
Oui, ça marche ! (La toute première fois, il doit lire et indexer les quelques 30 Mo de Mail qui trainent sur mon compte, cela prend une trentaine de secondes.
Problème : il n'utilise pas naturellement UTF8 quand on mélange du japonais et du français dans un même message, il découpe le message en plusieurs morceaux MIME...
Cela semble être géré par la variable gnus-group-charset-alist, qui contient une liste de couple groupe/codage (en fait, ce ne sont pas les noms exacts des groupes mais des expressions régulières) et dont la valeur par défaut est
( ("^hk\\>\\|^tw\\>\\|\\<big5\\>" cn-big5) ("^cn\\>\\|\\<chinese\\>" cn-gb-2312) ("^fj\\>\\|^japan\\>" iso-2022-jp-2) ("^tnn\\>\\|^pin\\>\\|^sci.lang.japan" iso-2022-7bit) ("^relcom\\>" koi8-r) ("^fido7\\>" koi8-r) ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2) ("^israel\\>" iso-8859-1) ("^han\\>" euc-kr) ("^alt.chinese.text.big5\\>" chinese-big5) ("^soc.culture.vietnamese\\>" vietnamese-viqr) ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1) (".*" iso-8859-1) )
On va simplement rajouter, au début de la liste, le couple
("^fr.lettres.langue.japonaise\\>" utf-8)
Cela peut se faire ainsi :
(require 'gnus-sum) (setq gnus-group-charset-alist ( cons '("^fr.lettres.langue.japonaise\\>" utf-8) gnus-group-charset-alist ) )
Ou alors, si on veut rajouter plusieurs groupes
(require 'gnus-sum) (setq gnus-group-charset-alist ( append (list '("^fr.lettres.langue.japonaise\\>" utf-8) '("^fr.test\\>" utf-8) ) gnus-group-charset-alist ) )
On aurait aussi pu modifier la variable de manière un peu plus interactive :
M-x customize-variable gnus-group-charset-alist
Mais ça ne marche pas : d'une part, ca lui demande d'ignorer le codage normalement indiqué dans l'en-tete des messages, d'autre part, il n'utilise pas utf8 lorsqu'il en envoie.
Essayons avec la variable gnus-group-posting-charset-alist.
(require 'gnus-sum) (setq gnus-group-posting-charset-alist ( append (list '("^fr.lettres.langue.japonaise\\>" utf-8) '("^fr.test\\>" utf-8) ) gnus-group-charset-alist ) )
Ca ne marche pas non plus.
A FAIRE
(On me dit qu'il suffit de charger ucs avant gnus, mais c'est bien ce que je fais...)
Problème : quand je lis un message, les commandes pour le faire défiler ne marchent pas (SPC ou RET, par contre > marche). Je suis obligé d'utiliser la souris...
Je vérifie, en tapant C-h k SPC puis C-h k RET que ces touches sont bien liées aux bonnes fonction.
SPC runs `gnus-summary-next-page' `gnus-summary-next-page' is an interactive compiled Lisp function -- loaded from "gnus-sum" (gnus-summary-next-page &optional LINES CIRCULAR) Documentation: Show next page of the selected article. If at the end of the current article, select the next article. LINES says how many lines should be scrolled up. If CIRCULAR is non-nil, go to the start of the article instead of selecting the next article when reaching the end of the current article. RET runs `view-scroll-lines-up' `view-scroll-lines-up' is an interactive compiled Lisp function -- loaded from "view-less" (view-scroll-lines-up P) Documentation: Scroll up prefix-arg lines, default 1. > runs `gnus-summary-end-of-article' `gnus-summary-end-of-article' is an interactive compiled Lisp function -- loaded from "gnus-sum" (gnus-summary-end-of-article) Documentation: Scroll to the end of the article.
On regarde donc dans le fichier gnus-sum.el quelles sont les différences entre les fonctions gnus-summary-end-of-article (qui marche) et gnus-summary-next-page (qui ne marche pas).
(defun gnus-summary-end-of-article () "Scroll to the end of the article." (interactive) (gnus-summary-select-article) (gnus-configure-windows 'article) (gnus-eval-in-buffer-window gnus-article-buffer (widen) (goto-char (point-max)) (recenter -3) (when gnus-page-broken (gnus-narrow-to-page))))
La fonction gnus-summary-next-page a une définition beaucoup trop longue. Je vais donc la redéfinir moi-même.
(defun my-gnus-summary-next-page () "Scroll down the article" (interactive) (gnus-summary-select-article) (gnus-configure-windows 'article) (gnus-eval-in-buffer-window gnus-article-buffer (widen) ;(goto-char (point-max)) (next-line (- (window-height) next-screen-context-lines)) (recenter -3) (when gnus-page-broken (gnus-narrow-to-page))))
Je constate qu'en tapant M-x my-gnus-summary-next-page à l'endroit voulu, ça marche. On peut maintenant la lier à la touche SPC.
(defun my-alter-summary-map () ; pour les deux lignes suivantes, voir ci-dessous ;(local-set-key "E" 'gnus-summary-put-mark-as-expirable-next) ;(local-set-key "d" 'gnus-summary-put-mark-as-read-next) (local-set-key " " 'my-gnus-summary-next-page) )
Exercice : faire la même chose pour avancer d'une ligne.
Problème : il ne reconnait pas le codage ISO-8859-15. Ca vient d'Emacs, pas de Gnus... (il faudra regarder avec une version un peu plus récente).
Problème : la commande E (pour faire expirer les messages) se positionne ensuite sur le message non lu suivant -- je préfèrerais le message suivant. Idem pour la commande d (pour dire qu'un message est lu).
(add-hook 'gnus-summary-mode-hook 'my-alter-summary-map) (defun my-alter-summary-map () (local-set-key "E" 'gnus-summary-put-mark-as-expirable-next) (local-set-key "d" 'gnus-summary-put-mark-as-read-next )
Problème : quand on veut sauvegarder des messages (pas pour le mail, mais pour les Niouzes), le fichier qu'il propose par défaut n'est plus le même.
(setq gnus-default-article-saver 'gnus-summary-save-in-file) (setq gnus-file-save-name 'gnus-plain-save-name)
Maintenant, les articles du groupe foo.bar seront sauvegardés dans le fichier ~/News/foo.bar.
Le problème, c'est que j'ai déjà plein de fichiers sous un format différent : ~/News/foo.bar/1
cd ~/News mkdir TMP mv *(/) TMP/ rename 's#^TMP/(.*)/1$#$1# TMP/*/1 rm -rf TMP
Il est possible de répartir les groupes en une hiérarchie. Il faut pour cela être dans le mode (mineur) "topic".
(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)
Quand on lance Gnus, on voit alors
[ Gnus -- 3950 ] [ misc -- 3950 ] 123: comp.lang.perl 6: comp.lang.perl.announce 1443: comp.lang.perl.misc 35: comp.lang.perl.moderated 168: comp.lang.perl.modules 135: comp.lang.perl.tk 73: comp.text.tex 25: fr.comp.lang.perl 69: fr.comp.text.tex 227: fr.lettres.langue.japonaise 91: fr.rec.anime * 0: fr.rec.anime.selection * 0: nnml:Argent 221: nnml:CTAN-Announce 837: nnml:Divers 230: nnml:Omega 2: nnml:mail.misc 142: nnml:maple 122: nnml:pstricks 1: nnml:spam
Ensuite, on joue avec les commandes
T n crée un Topic C-k Cut C-y Paste
Voici le résultat :
[ Gnus -- 3950 ] [ Mail -- 1555 ] 221: nnml:CTAN-Announce 837: nnml:Divers 230: nnml:Omega 2: nnml:mail.misc 142: nnml:maple 122: nnml:pstricks 1: nnml:spam [ News -- 2395 ] 123: comp.lang.perl 6: comp.lang.perl.announce 1443: comp.lang.perl.misc 35: comp.lang.perl.moderated 168: comp.lang.perl.modules 135: comp.lang.perl.tk 73: comp.text.tex 25: fr.comp.lang.perl 69: fr.comp.text.tex 227: fr.lettres.langue.japonaise 91: fr.rec.anime * 0: fr.rec.anime.selection
On peut ouvrir ou fermer un Topic (i.e., afficher ou cacher ses éléments) à l'aide de la commande = ou en cliquant dessus avec la touche du milieu de la souris.
[ Gnus -- 3950 ] [ Mail -- 1555 ] 221: nnml:CTAN-Announce 837: nnml:Divers 230: nnml:Omega 2: nnml:mail.misc 142: nnml:maple 122: nnml:pstricks 1: nnml:spam [ News -- 2395 ]...
Cette hiérarchie (ainsi qu'une grande partie de la configuration de Gnus, ainsi que la liste des messages lus, expirables, sauvegardés, auxquels on a répondu, etc.) est stoquée dans le fichier ~/.newsrc.eld, sous la forme suivante.
(setq gnus-topic-topology '( ("Gnus" visible) (("Mail" visible nil nil)) (("News" visible nil nil)) ) ) (setq gnus-topic-alist '( ("Mail" "nnml:Argent" "nnml:CTAN-Announce" "nnml:Divers" "nnml:Omega" "nnml:mail.misc" "nnml:maple" "nnml:pstricks" "nnml:spam" ) ("News" "comp.lang.perl" "comp.lang.perl.announce" "comp.lang.perl.misc" "comp.lang.perl.moderated" "comp.lang.perl.modules" "comp.lang.perl.tk" "comp.text.tex" "fr.comp.lang.perl" "fr.comp.text.tex" "fr.lettres.langue.japonaise" "fr.rec.anime" "fr.rec.anime.selection" "nndraft:drafts" ) ("Gnus") ) )
Il tournera sur la machine qui gère le mail, i.e.,
% host smtp smtp.institut.math.jussieu.fr. is an alias for smtp.math.jussieu.fr. smtp.math.jussieu.fr. is an alias for riemann.math.jussieu.fr. riemann.math.jussieu.fr. has address 134.157.13.100
Ca n'est pas comme ça qu'on est sensé trouver la machine qui gère le mail. Le plus simple est de regarder l'en-tête des messages qu'on reçoit.
From nobody@mailgate.org Fri Jun 14 12:05:30 2002 Return-Path: <nobody@mailgate.org> Received: from shiva.jussieu.fr (shiva.jussieu.fr [134.157.0.129]) by riemann.math.jussieu.fr (8.12.1/jtpda-5.3.3) with ESMTP id g5EA5TTp084132 for <zoonek@borel4.institut.math.jussieu.fr>; Fri, 14 Jun 2002 12:05:30 +0200 (CEST) Received: from mail.mailgate.org (mail.mailgate.org [212.177.105.138]) by shiva.jussieu.fr (8.12.4/jtpda-5.4) with ESMTP id g5EA5T2D032720 for <zoonek@borel4.institut.math.jussieu.fr>; Fri, 14 Jun 2002 12:05:29 +0200 (CEST) Received: (from news@localhost) by mail.mailgate.org (8.11.3/8.11.3) id g5EA5NR00843 for zoonek@borel4.institut.math.jussieu.fr; Fri, 14 Jun 2002 12:05:23 +0200
Une autre manière de trouver cette machine (mais qui ne donne pas la bonne réponse : on n'a pas la machine qui gère le courrier en ...@math.jussieu.fr, mais celle qui sait trouver la machine qui le gère), est de taper
host -t mx math.jussieu.fr
Revenons donc à riemann.math.jussieu.fr. D'après http://www.institut.math.jussieu.fr/informatique/serveurs.html il s'agit d'un PC sous FreeBSD 4.2.
Pour pouvoir installer mon filtre, il me faut Perl et Mail::Audit. Le problème, c'est que certains modules (pas Mail::Audit, mais peut-petre certains des modules qu'il utilise) contiennent des morceaux en C, qu'il faut compiler pour une plateforme donnée. De surcroit, pour que les dépendances entre modules se résolvent toutes seules, je préfère utiliser le module CPAN, qui suppose que c'est moi-même qui ai installé Perl. Enfin, je ne pense pas avoir le droit de me logguer sur cette machine (mais je n'ai pas vérifié -- en tout cas, un utilisateur normal n'a aucune raison de vouloir se logguer sur cette machine). Je vais donc essayer de tout compiler sur cantor (qui est sous FreeBSD 4.3, ce n'est pas la même version, mais j'espère que ça marchera).
sh Configure -Dprefix=$HOME/gnu/`uname` -Uinstallusrbinperl -des make make test make install
Ensuite on essaye d'installer Mail::Audit
perl -MCPAN -e shell install Mail::Audit
Mais ça plante complètement : les chemins d'accès aux différents exécutables sont faux.
perl -MCPAN -e shell o conf ftp /usr/local/bin/ncftp o conf gzip /usr/bin/gzip o conf ncftpget /usr/local/bin/ncftpget o conf lynx /usr/local/bin/lynx o conf tar /usr/bin/tar install Mail::Audit
Ca plante toujours, car lynx décompresse les fichiers *.gz sans le dire.
rename 's/\.gz$//' `file ~/.cpan/**/*.gz | grep ASCII | sed 's/:.*//'` gzip ~/.cpan/**/*.(txt|data) perl -MCPAN -e shell install Mail::Audit
Lors de l'installation, on constate qu'il est effectivement amené à compiler certaines choses.
Je met mon script de filtrage de mail dans ~/bin/scripts/mail_filter.pl
Je l'appelle depuis le ~/.forward de la manière suivante
/share/nfs/users1/umr-tge/zoonek/Mail/dot_forward_backup /share/nfs/users1/umr-tge/zoonek/Mail/SAVE_qskdbgskdgf "|IFS=' ' && f=/share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl && test -f $f && p=/share/nfs/users1/umr-tge/zoonek/gnu/`uname`/bin/perl && test -x $p && exec $p $f || exit 75 #zoonek"
On remarquera les deux première lignes du ~/.forward : la première est toujours là et garde une copie de chaque message ; la seconde n'est là que le temps d'installer le filtre -- c'est là, par exemple, qu'on trouvera les messages d'erreur, qui sont envoyés par mail à l'expéditeur du message qui n'est pas passé. Voici un exemple de tel message.
From Mailer-Daemon Thu Jun 13 16:00:52 2002 Return-Path: <Mailer-Daemon> Received: from localhost (localhost) by riemann.math.jussieu.fr (8.12.1/jtpda-5.3.3) id g5DE0qTp084765 ; Thu, 13 Jun 2002 16:00:52 +0200 (CEST) Date: Thu, 13 Jun 2002 16:00:52 +0200 (CEST) From: Mailer-Daemon (Mail Delivery Subsystem) Subject: Returned mail: see transcript for details Message-Id: <200206131400.g5DE0qTp084765@riemann.math.jussieu.fr> To: <zoonek> MIME-Version: 1.0 Content-Type: multipart/report; report-type=delivery-status; boundary="g5DE0qTp084765.1023976852/riemann.math.jussieu.fr" Auto-Submitted: auto-generated (failure) This is a MIME-encapsulated message --g5DE0qTp084765.1023976852/riemann.math.jussieu.fr The original message was received at Thu, 13 Jun 2002 16:00:51 +0200 (CEST) from borel4.institut.math.jussieu.fr [134.157.13.114] ----- The following addresses had permanent fatal errors ----- "|IFS=' ' && f=/share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl && test -f $f && p=/share/nfs/users1/umr-tge/zoonek/gnu/`uname`/bin/perl && test -x $p && exec $p $f || exit 75 #zoonek" (expanded from: <zoonek>) ----- Transcript of session follows ----- Semicolon seems to be missing at /share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl line 81. syntax error at /share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl line 82, near ") mess" Execution of /share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl aborted due to compilation errors. 554 5.3.0 unknown mailer error 255 --g5DE0qTp084765.1023976852/riemann.math.jussieu.fr Content-Type: message/delivery-status Reporting-MTA: dns; riemann.math.jussieu.fr Received-From-MTA: dns; borel4.institut.math.jussieu.fr Arrival-Date: Thu, 13 Jun 2002 16:00:51 +0200 (CEST) Final-Recipient: rfc822; zoonek@riemann.math.jussieu.fr X-Actual-Recipient: rfc822; |IFS=' ' && f=/share/nfs/users1/umr-tge/zoonek/bin/scripts/mail_filter.pl && test -f $f && p=/share/nfs/users1/umr-tge/zoonek/gnu/`uname`/bin/perl && test -x $p && exec $p $f || exit 75 #zoonek@riemann.math.jussieu.fr Action: failed Status: 5.0.0 Last-Attempt-Date: Thu, 13 Jun 2002 16:00:52 +0200 (CEST) --g5DE0qTp084765.1023976852/riemann.math.jussieu.fr Content-Type: message/rfc822 Return-Path: <zoonek> Received: from borel4.math.jussieu.fr (borel4.institut.math.jussieu.fr [134.157.13.114]) by riemann.math.jussieu.fr (8.12.1/jtpda-5.3.3) with ESMTP id g5DE0pTp084764 for <zoonek>; Thu, 13 Jun 2002 16:00:51 +0200 (CEST) From: zoonek (Vincent Zoonekynd) Received: from (zoonek@localhost) by borel4.math.jussieu.fr (8.11.6/jtpda-5.3.2) id g5DE0o800791 for zoonek; Thu, 13 Jun 2002 16:00:50 +0200 Date: Thu, 13 Jun 2002 16:00:50 +0200 Message-Id: <200206131400.g5DE0o800791@borel4.math.jussieu.fr> To: zoonek Subject: llllllllllll lllllllll --g5DE0qTp084765.1023976852/riemann.math.jussieu.fr--
Si l'erreur est dans le script, celui-ci se terminera avec un code de retour égal à 255 et Sendmail concluera à une erreur fatale permanente ("The following addresses had permanent fatal errors", comme dans l'exemple ci-dessus) et renverra le message à son expéditeur.
Si l'erreur est ailleurs, par exemple, si le script n'est plus à cet endroit, ou si perl n'est plus là, la ligne correspondante du ~/.forward renverra un code de retour égal à 75, qui désigne une erreur temporaire (voir sysexits.h pour les détails). Dans ce cas, Sendmail met le message en attente et réessaye de l'envoyer trois heures plus tard. En cas de nouvel échec, il est renvoyé à l'expéditeur.
Notes prises il y a quelques années (été 1999)
Pour invoquer procmail à la main... ORGMAIL=/var/spool/mail/$LOGNAME lockfile -l3600 -ml cat $ORGMAIL >> .newmail && cat /dev/null >$ORGMAIL lockfile -mu formail -s procmail <.newmail && rm -f .newmail Sur gauss : - procmail n'est pas installé au même endroit - procmail n'est pas installé correctement (si je le compile moi-même, ça marche très bien) Voir si on a le droit de mettre $HOME/gnu/bin/`uname`/procmail dans ~/.forward Oui, on peut. Quelques explications sur le contenu du ~/.forward "|/usr/bin/procmail -Yf- || exit 75 #zoonek" Il faut que tout soit compris entre guillemets. Le début de la commande est relativement clair. La liste des codes d'erreurs est dans le fichier sysexits.h. Celui qui nous intéresse correspond à #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ On lui demande donc de recommencer en cas d'erreur, un peu plus tard, généralement une heure, en espérant que l'erreur soit corrigée entre temps. Si trois jours plus tard l'erreur n'est pas corrigée, on abandonne et le message revient à l'envoyeur. Attention : cela permet de repérer des erreurs dans le programme lancé dans le .forward, par exemple dans le fichier de configuration. Si on commet un erreur dans le ~/.forward lui-meme, par exemple sur l'emplacement de procmail, ça ne marchera pas : le .forward peut contenir plusieures lignes, on va réessayer celle qui a posé problème ; si elle a été modifiée entre temps, on n'en tient pas compte. Quant à la fin de la ligne, à savoir #zoonek, je ne sais pas du tout ce que c'est. Je constate que dans les messages d'erreur, c'est remplacé par ...#zoonek@math.jussieu.fr
Vincent Zoonekynd
<zoonek@math.jussieu.fr>
latest modification on ven jun 14 12:26:48 CEST 2002