2008年07月03日

sendmailで悪戦苦闘

 テキスト碁盤を使ってメール碁をするとメールソフトの設定によっては碁盤が崩れて表示されて用を足さない。
 棋譜データをメッセージに貼り込んでメール交換をすればいいのだが棋譜ソフトが必要だ。
 メールのやりとりやホームページを見ることはできるがPCの操作は苦手だという人には棋譜ソフトのダウンロードやインストールはハードルが高すぎる。
 そこで棋譜ソフトがなくてもメール碁ができるようにめんさんの棋譜をメールで送信するツールや通りすがりさんから教えていただいた碁盤付きコメント作成ツールをアレンジしてメール碁支援ツールを作ってみた。
 ドシロウトが作るのだから動くまでにも半日費やしたが動いてからが大変だ。
 なんと!メッセージが文字化けしてしまう。
 「sendmail 文字化け」をキーワードにグー検し対策記事を頼りに試行錯誤を重ねても直らない。
 1日費やしてふと気がついた。めんさんの棋譜をメールで送信するツールは文字化けしない。
 ということはsendmailを使ったソースが文字化けの犯人ではなくjavascript内のformから送信したのがいけなかったのだ。
 formをjavascriptから外に出し試行錯誤を重ねて文字化けしないようにすることができた。 しかし、このツールでは自分宛にBCCできないから送信メールの確認ができない。
 そこでsendmail.cgiの
$M_name = $QUERY{'name'};
$M_from = $QUERY{'from'};
$M_subject = $QUERY{'subject'};
$M_to = $QUERY{'mail'};
$M_message = $QUERY{'body'};
$M_message = "【送信者】 $M_name\n ================= \n$M_message";
main::sdmail($sendmail,$M_to,$M_name,$M_from,$M_subject,$M_message);
にfromアドレスをbccアドレスにしようと思い
$M_name = $QUERY{'name'};
$M_from = $QUERY{'from'};
$M_subject = $QUERY{'subject'};
$M_to = $QUERY{'mail'};
$M_bcc = "$M_to,$M_from";
$M_message = $QUERY{'body'};
$M_message = "【送信者】 $M_name\n ================= \n$M_message";
main::sdmail($sendmail,$M_to,$M_name,$M_from,$M_subject,$M_message,$M_bcc);
 しかし、これでは全然機能しない。
 とりあえず
$M_name = $QUERY{'name'};
$M_from = $QUERY{'from'};
$M_subject = $QUERY{'subject'};
$M_to = $QUERY{'mail'};
$M_to = "$M_to,$M_from";
$M_message = $QUERY{'body'};
$M_message = "【送信者】 $M_name\n ================= \n$M_message";
main::sdmail($sendmail,$M_to,$M_name,$M_from,$M_subject,$M_message);
としてみた。
 これで送信先に自分のアドレスが追加され送信メールを確認することができるようになったがToに自分のアドレスが加わるのはなんだかなぁという気分だ。
 senmailにBCCを加える方法はないものだろうか。「senmail BCC」でグー検しても役に立つ情報が得られない。
 どなたか教えていただければ幸いです。
 (島谷的舞録゛@FC2に移動します。)
#!/usr/bin/perl

require './pack.pl';

# sendmailのパス
$sendmail = '/usr/sbin/sendmail';

# 分かりやすいように、個々の変数にコピーします
$M_name = '$name'; #名前
$M_from = '$from'; #送信元アドレス
$M_subject = '$subject';#タイトル
$M_message = '$body'; #本文
$M_to = '$mail';#送信先アドレス

if($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $QUERY_DATA, $ENV{'CONTENT_LENGTH'}); }
else { $QUERY_DATA = $ENV{'QUERY_STRING'}; }

@pairs = split(/&/,$QUERY_DATA);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$QUERY{$name} = $value;
}
$M_name = $QUERY{'name'};
$M_from = $QUERY{'from'};
$M_subject = $QUERY{'subject'};
$M_to = $QUERY{'mail'};
$M_to = "$M_to,$M_from";
$M_message = $QUERY{'body'};
$M_message = "【送信者】 $M_name\n ================ \n$M_message";

main::sdmail($sendmail,$M_to,$M_name,$M_from,$M_subject,$M_message);

print "Content-type: text/html\n\n";
print "<div style='font-size:30px; font-weight:bold; line-height:60px; background:#ddfdbd;' align=center margin-top:100px;><hr><p>";
print "送信成功";
print "<p><input type=button onClick=location.replace('../hogehoge.html') value='閉じる'>";
print "<p><input type=button onClick=window.open('http://honyarara.html/','_top') value='戻る'>";
print "</div><hr>";
exit;

sub error {
print "Content-type: text/html\n\n";
print "$_[0]";
exit;
}

package main;
sub sdmail {

require './jcode.pl';

($sendmail,$to,$name,$from,$subject,$message) = @_ ;

#$sendmail #sendmailのパス
#$name #名前
#$from #送信元アドレス
#$subject #タイトル
#$message #本文
#$to #送信先アドレス

#文字コードをJISに変換する
&jcode'convert(*subject, 'jis');
&jcode'convert(*message, 'jis');

unless (-e $sendmail) { &error("sendmailのパスが不正です。"); exit; }

# sendmailをパイプで書き込みオープンします
open(MAIL, "| $sendmail -t") || &error("送信失敗");

# メールを送る

print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n";
print MAIL "MIME-Version: 1.0\n";
print MAIL "Content-type: text/plain; charset=ISO-2022-JP\n";
print MAIL "Content-Transfer-Encoding: 7bit\n";
print MAIL "$message\n";

# パイプを閉じる
close (MAIL);

}

1;
posted at 05:57 | 情報技術