franta-hg@21
|
1 |
#!/usr/bin/env perl
|
franta-hg@21
|
2 |
|
franta-hg@21
|
3 |
use strict;
|
franta-hg@21
|
4 |
use MIME::Parser;
|
franta-hg@21
|
5 |
use Net::SMTP;
|
franta-hg@21
|
6 |
|
franta-hg@21
|
7 |
# K doručenkám typu:
|
franta-hg@21
|
8 |
# Content-Type: multipart/report; report-type=delivery-status; ~ Delivery Status Notification (DSN)
|
franta-hg@21
|
9 |
# doplňujeme hlavičku References,
|
franta-hg@21
|
10 |
# aby si je e-mailový klient mohl zařadit do vlákna pod zprávu, ke které doručenka patří.
|
franta-hg@21
|
11 |
|
franta-hg@21
|
12 |
# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Entity.pm
|
franta-hg@21
|
13 |
# viz http://search.cpan.org/~dskoll/MIME-tools-5.502/lib/MIME/Head.pm
|
franta-hg@21
|
14 |
# viz http://search.cpan.org/~gbarr/libnet-1.21/Net/SMTP.pm
|
franta-hg@21
|
15 |
|
franta-hg@21
|
16 |
|
franta-hg@21
|
17 |
# Nastavení --------------------------------------------------------------------
|
franta-hg@21
|
18 |
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í
|
franta-hg@21
|
19 |
# ------------------------------------------------------------------------------
|
franta-hg@21
|
20 |
|
franta-hg@21
|
21 |
my $znacka = "X-DSN-Pridej-References"; # hlavička, kterou si poznačíme, že zpráva prošla tímto programem
|
franta-hg@21
|
22 |
my $stav = "chyba - nedefinovano"; # výchozí hodnota naší hlavičky
|
franta-hg@21
|
23 |
|
franta-hg@21
|
24 |
|
franta-hg@21
|
25 |
# Načteme zprávu
|
franta-hg@21
|
26 |
my $parser = new MIME::Parser;
|
franta-hg@21
|
27 |
$parser->output_to_core(1);
|
franta-hg@21
|
28 |
my $dorucenka = $parser->parse(\*STDIN);
|
franta-hg@21
|
29 |
|
franta-hg@21
|
30 |
|
franta-hg@21
|
31 |
# Kontrola, že se zpráva nezacyklila (chybí naše značka)
|
franta-hg@21
|
32 |
if ($dorucenka->head->count($znacka) == 0) {
|
franta-hg@21
|
33 |
|
franta-hg@21
|
34 |
# Podle hlavičky Delivered-To zjistíme, kam máme zprávu poslat zpátky
|
franta-hg@21
|
35 |
my $deliveredTo = $dorucenka->head->get("Delivered-To", 1); # [0] = adresa tohoto skriptu, [1] = předchozí adresa – původní příjemce doručenky
|
franta-hg@21
|
36 |
if ($deliveredTo) {
|
franta-hg@21
|
37 |
$deliveredTo =~ s/\s+$//; # zbavíme se přebytečného konce řádku
|
franta-hg@21
|
38 |
$komu = $deliveredTo;
|
franta-hg@21
|
39 |
$dorucenka->head->delete("Delivered-To", 1); # aby si poštovní server nemyslel, že se zpráva zacyklila
|
franta-hg@21
|
40 |
|
franta-hg@21
|
41 |
# Pokud hlavička References chybí, doplníme ji
|
franta-hg@21
|
42 |
if ($dorucenka->head->count("References") == 0) {
|
franta-hg@21
|
43 |
|
franta-hg@21
|
44 |
# Zjistíme Message-ID původní zprávy
|
franta-hg@21
|
45 |
my $messageID;
|
franta-hg@21
|
46 |
my @casti = $dorucenka->parts;
|
franta-hg@21
|
47 |
for my $cast (@casti) {
|
franta-hg@21
|
48 |
if ($cast->mime_type eq "text/rfc822-headers") {
|
franta-hg@21
|
49 |
my @radky = $cast->bodyhandle->as_lines;
|
franta-hg@21
|
50 |
for my $radek (@radky) {
|
franta-hg@21
|
51 |
if ($radek =~ /^Message-ID:\s*(<.*>)$/) {
|
franta-hg@21
|
52 |
$messageID = $1;
|
franta-hg@21
|
53 |
}
|
franta-hg@21
|
54 |
}
|
franta-hg@21
|
55 |
}
|
franta-hg@21
|
56 |
}
|
franta-hg@21
|
57 |
|
franta-hg@21
|
58 |
# Nastavíme nalezené Message-ID do References hlavičky
|
franta-hg@21
|
59 |
if ($messageID) {
|
franta-hg@21
|
60 |
$stav = "ok";
|
franta-hg@21
|
61 |
$dorucenka->head->add("References", $messageID);
|
franta-hg@21
|
62 |
} else {
|
franta-hg@21
|
63 |
$stav = "chyba - Message-ID nenalezeno";
|
franta-hg@21
|
64 |
}
|
franta-hg@21
|
65 |
|
franta-hg@21
|
66 |
} else {
|
franta-hg@21
|
67 |
$stav = "hlavicka References uz byla nastavena drive";
|
franta-hg@21
|
68 |
}
|
franta-hg@21
|
69 |
} else {
|
franta-hg@21
|
70 |
$stav = "chyba - nevime, kam zpravu poslat zpet";
|
franta-hg@21
|
71 |
}
|
franta-hg@21
|
72 |
} else {
|
franta-hg@21
|
73 |
# Zpráva se zacyklila → pouze přidáme svoji značku
|
franta-hg@21
|
74 |
# a pošleme správci (nezměníme $komu)
|
franta-hg@21
|
75 |
$stav = "chyba - cyklus";
|
franta-hg@21
|
76 |
}
|
franta-hg@21
|
77 |
|
franta-hg@21
|
78 |
|
franta-hg@21
|
79 |
$stav .= " [pid=$$,uid=$>]"; # přidáme PID a UID
|
franta-hg@21
|
80 |
$dorucenka->head->add($znacka, $stav);
|
franta-hg@21
|
81 |
|
franta-hg@21
|
82 |
# Výpis (nepotřebujeme, jen pro ladění)
|
franta-hg@21
|
83 |
#$dorucenka->print(\*STDOUT);
|
franta-hg@21
|
84 |
#print "Pošleme komu: $komu\n";
|
franta-hg@21
|
85 |
|
franta-hg@21
|
86 |
# Odeslání přes SMTP (pro ostrý provoz):
|
franta-hg@21
|
87 |
my $smtp = Net::SMTP->new("localhost");
|
franta-hg@21
|
88 |
$smtp->mail('<>');
|
franta-hg@21
|
89 |
$smtp->to($komu);
|
franta-hg@21
|
90 |
$smtp->data();
|
franta-hg@21
|
91 |
$dorucenka->print($smtp);
|
franta-hg@21
|
92 |
$smtp->dataend();
|
franta-hg@21
|
93 |
$smtp->quit;
|