添付ファイルを除外してテキストを転送するスクリプト tenso.pl
2013/03/26
develop
問題
届いたメールを、添付ファイルがあれば削除して、テキストだけを転送したいです。
答え
qmail環境で、perlスクリプトで対応する例。
なお、入れ子になっているMIMEパートには未対応(消える)。
#!/usr/bin/perl
use MIME::QuotedPrint;
use MIME::Base64;
use Encode qw/from_to/;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
use Unicode::Japanese;
# 基本的には、下記の★もしくは☆を書き換えて使用する
$pg_address = '@hoge\.example\.com'; #メール受信用アドレスの一部。ループ処理用なので。★
$sendmail = "/usr/sbin/sendmail"; # sendmail プログラムの位置☆
#変数初期化
$headers = "";
$honbun = "";
$tmp_honbun = "";
$qp = 0;
$h_lines = 0;
$delfile = 0; #削除されたファイル数
$forwardto = join(" ", @ARGV);
#メインルーチン
&make_mail;
&mail_forward;
#サブルーチン メール送信
sub mail_forward {
open(OUT,"| $sendmail $forwardto") || die "Cannnot open $sendmail";
print OUT $headers;
print OUT "\n";
print OUT $honbun;
if($delfile >= 1) {
print OUT "\n!!!!! $delfile file(s) deleted. !!!!!";
}
close(OUT);
}
# サブパート本文をplainなiso-2022-jpに変換して結合する
sub convert_honbun {
if($tmp_honbun ne "") {
if($cte == 1) {
$tmp_honbun = decode_qp($tmp_honbun);
}
elsif($cte == 2) {
$tmp_honbun = decode_base64($tmp_honbun);
}
$ccode = guess_encoding($tmp_honbun)->name;
if($ccode =~ /utf8/i) {
$tmp_honbun = Unicode::Japanese->new($tmp_honbun)->conv('jis');
} else {
&from_to($tmp_honbun, $ccode, "iso-2022-jp");
}
$honbun .= $tmp_honbun;
$cte = 0;
$tmp_honbun = "";
}
}
#サブルーチン メール加工
sub make_mail {
open(STDIN);
$mainheaderf = 1; #ヘッダーフラグセット
$mixf = 0; #添付ファイル有無フラグクリア
$headf = 0; #途中のヘッダーフラグ
$outf = 0; #出力フラグ
$h_c_t = 0;
while(<STDIN>){
if($mainheaderf){ #メインのヘッダー処理
if(/^$/){ #改行だけの行
$mainheaderf = 0; #次からは本文
}
elsif(/^Return-Path:.*$pg_address/i){ #ループになったら強制終了
die "Mail loop.";
}
elsif(/^Content-Type:/i){ #コンテントタイプの書き換え
$h_c_t = 1;
if(/multipart/i || /mix/i){ #なら
$mixf = 1;
$headers .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
$headers .= "Content-Transfer-Encoding: 7bit\n";
} else {
$headers .= $_;
}
if(/boundary=/i){
($temp,$boundary) = split("=",$_,2);
$boundary =~ s/\"//g;
chomp($boundary);
}
}
elsif(/boundary=/i && $h_c_t <= 1){
$h_c_t++;
($temp,$boundary) = split("=",$_,2);
$boundary =~ s/\"//g;
chomp($boundary);
}
else{
$headers .= $_;
}
}
else{ #本文処理
if($mixf){ #添付ファイルありの場合
if(/$boundary/i){ #区切り文字列
$headf = 1; #ヘッダーの開始
$outf = 0; #出力フラグクリア
# 前回の処理が終わったら
&convert_honbun;
}
elsif($headf){ #ヘッダー処理
if(/^Content-Type:/i){ #Content-Typeの行
if(/text\/plain/i || /message/i){ #text/plainなら
$outf = 1; #出力フラグオン
}else{ #text/plainじゃないなら
$outf = 0; #出力しない
$delfile++;
}
}
elsif(/^Content-Transfer-Encoding:/i && $outf == 1){ #Content-Typeの行
if(/quoted-printable/i){ #quoted-printableなら
$cte = 1; #出力フラグオン
}
if(/base64/i){ #base64なら
$cte = 2; #出力フラグオン
}
}
elsif(/^$/){ #改行だけの行なら
$headf = 0; #ヘッダー部終了
}
}
else{ #本文処理
if($outf){ #出力して良いなら
if($h_lines < 500){
$tmp_honbun .= $_; #一時変数に格納
$h_lines++;
}
}
}
}
else{ #添付ファイルなしの場合
if($h_lines < 500){
$honbun .= $_; #一時ファイルに格納
$h_lines++;
}
}
}
}
close(STDIN);
}
tenso.pl などの名前で保存。
実行権限付与。
chmod 755 tenso.pl
使用例(引数にメールのソースを渡すとき)
cat <元メールファイル> | tenso.pl <転送先メールアドレス1> [<転送先メールアドレス2> …]
使用例(qmailで受信時に実行するとき)
.qmail に以下のように書く
| /home/tenso.pl xxxx@docomo.ne.jp
/home/vpopmail/domains/hoge.example.com/xxxuserxxx/Maildir/