SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

添付ファイルを除外してテキストを転送するスクリプト tenso.pl

問題

届いたメールを、添付ファイルがあれば削除して、テキストだけを転送したいです。

答え

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/

関連するメモ

コメント