Doručenky: sieve přesměrování + skript v perlu (přes aliasy) místo milteru.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/doručenky/aliases Wed Nov 30 15:44:34 2011 +0100
1.3 @@ -0,0 +1,3 @@
1.4 +# /etc/aliases
1.5 +
1.6 +dorucenky: |/usr/local/bin/dorucenky.pl
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/doručenky/dorucenky.pl Wed Nov 30 15:44:34 2011 +0100
2.3 @@ -0,0 +1,93 @@
2.4 +#!/usr/bin/env perl
2.5 +
2.6 +use strict;
2.7 +use MIME::Parser;
2.8 +use Net::SMTP;
2.9 +
2.10 +# K doručenkám typu:
2.11 +# Content-Type: multipart/report; report-type=delivery-status; ~ Delivery Status Notification (DSN)
2.12 +# doplňujeme hlavičku References,
2.13 +# aby si je e-mailový klient mohl zařadit do vlákna pod zprávu, ke které doručenka patří.
2.14 +
2.15 +# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Entity.pm
2.16 +# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Head.pm
2.17 +# viz http://search.cpan.org/~gbarr/libnet-1.21/Net/SMTP.pm
2.18 +
2.19 +
2.20 +# Nastavení --------------------------------------------------------------------
2.21 +my $komu = 'noreply@example.com'; # adresa správce – sem pošleme zprávy, pokud nevíme, kam je poslat (chybí Delivered-To), nebo máme podezření na zacyklení
2.22 +# ------------------------------------------------------------------------------
2.23 +
2.24 +my $znacka = "X-DSN-Pridej-References"; # hlavička, kterou si poznačíme, že zpráva prošla tímto programem
2.25 +my $stav = "chyba - nedefinovano"; # výchozí hodnota naší hlavičky
2.26 +
2.27 +
2.28 +# Načteme zprávu
2.29 +my $parser = new MIME::Parser;
2.30 +$parser->output_to_core(1);
2.31 +my $dorucenka = $parser->parse(\*STDIN);
2.32 +
2.33 +
2.34 +# Kontrola, že se zpráva nezacyklila (chybí naše značka)
2.35 +if ($dorucenka->head->count($znacka) == 0) {
2.36 +
2.37 + # Podle hlavičky Delivered-To zjistíme, kam máme zprávu poslat zpátky
2.38 + my $deliveredTo = $dorucenka->head->get("Delivered-To", 1); # [0] = adresa tohoto skriptu, [1] = předchozí adresa – původní příjemce doručenky
2.39 + if ($deliveredTo) {
2.40 + $deliveredTo =~ s/\s+$//; # zbavíme se přebytečného konce řádku
2.41 + $komu = $deliveredTo;
2.42 + $dorucenka->head->delete("Delivered-To", 1); # aby si poštovní server nemyslel, že se zpráva zacyklila
2.43 +
2.44 + # Pokud hlavička References chybí, doplníme ji
2.45 + if ($dorucenka->head->count("References") == 0) {
2.46 +
2.47 + # Zjistíme Message-ID původní zprávy
2.48 + my $messageID;
2.49 + my @casti = $dorucenka->parts;
2.50 + for my $cast (@casti) {
2.51 + if ($cast->mime_type eq "text/rfc822-headers") {
2.52 + my @radky = $cast->bodyhandle->as_lines;
2.53 + for my $radek (@radky) {
2.54 + if ($radek =~ /^Message-ID:\s*(<.*>)$/) {
2.55 + $messageID = $1;
2.56 + }
2.57 + }
2.58 + }
2.59 + }
2.60 +
2.61 + # Nastavíme nalezené Message-ID do References hlavičky
2.62 + if ($messageID) {
2.63 + $stav = "ok";
2.64 + $dorucenka->head->add("References", $messageID);
2.65 + } else {
2.66 + $stav = "chyba - Message-ID nenalezeno";
2.67 + }
2.68 +
2.69 + } else {
2.70 + $stav = "hlavicka References uz byla nastavena drive";
2.71 + }
2.72 + } else {
2.73 + $stav = "chyba - nevime, kam zpravu poslat zpet";
2.74 + }
2.75 +} else {
2.76 + # Zpráva se zacyklila → pouze přidáme svoji značku
2.77 + # a pošleme správci (nezměníme $komu)
2.78 + $stav = "chyba - cyklus";
2.79 +}
2.80 +
2.81 +
2.82 +$stav .= " [pid=$$,uid=$>]"; # přidáme PID a UID
2.83 +$dorucenka->head->add($znacka, $stav);
2.84 +
2.85 +# Výpis (nepotřebujeme, jen pro ladění)
2.86 +#$dorucenka->print(\*STDOUT);
2.87 +#print "Pošleme komu: $komu\n";
2.88 +
2.89 +# Odeslání přes SMTP (pro ostrý provoz):
2.90 +my $smtp = Net::SMTP->new("localhost");
2.91 +$smtp->mail('<>');
2.92 +$smtp->to($komu);
2.93 +$smtp->data();
2.94 +$dorucenka->print($smtp);
2.95 +$smtp->dataend();
2.96 +$smtp->quit;
3.1 --- a/doručenky/doručenky.sieve Wed Nov 30 15:40:16 2011 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,7 +0,0 @@
3.4 -require ["fileinto"];
3.5 -# rule:[doručenky]
3.6 -if anyof (header :contains "Content-Type" "report-type=disposition-notification;", header :contains "Content-Type" "report-type=delivery-status;")
3.7 -{
3.8 - fileinto "Sent";
3.9 - stop;
3.10 -}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/doručenky/global.sieve Wed Nov 30 15:44:34 2011 +0100
4.3 @@ -0,0 +1,21 @@
4.4 +# Kompilace:
4.5 +# sievec global.sieve
4.6 +
4.7 +require ["fileinto"];
4.8 +
4.9 +# rule:[doručenky]
4.10 +if allof (
4.11 + not exists "X-DSN-Pridej-References",
4.12 + header :contains "Content-Type" "report-type=delivery-status;"
4.13 + )
4.14 +{
4.15 + redirect "dorucenky@example.com";
4.16 + stop;
4.17 +}
4.18 +elsif anyof (
4.19 + header :contains "Content-Type" "report-type=disposition-notification;",
4.20 + header :contains "Content-Type" "report-type=delivery-status;"
4.21 + )
4.22 +{
4.23 + fileinto "Sent";
4.24 +}