LinkStation v2.30改造の記録

[ホーム][戻る][次へ] 12 by A.Sato


■perlでメールを送信(SMTPモジュール編)

perlのCGIでBBSを開設し、投稿された内容をみんなに転送したいようなときに、CGIの中でsendmailを使うことが多いと思います。しかし、マイサーバにsendmailを立ち上げるには、きちんとした設定をしてDNSに載っていないと送り先のメールサーバに拒否されたりします。また、マイサーバがspamメールの送信元にされる心配もあります。
いろいろ調べたところ、perlのNet::SMTPモジュール(SMTP.pm)を使って、Outlook Expressでメールを送信するように、自分の契約しているプロバイダのメールサーバにsmtpでメールを送信することができます。
HD-HLANシリーズでは、perl5.6.1はインストールされていますが、SMTPモジュールがインストールされていないので、各自インストールする必要があります。
モジュールをインストールするには、CPAN(Comprehensive Perl Archive Network)でインストールするのが楽のようです。しかし、CPANからインストールするには、あらかじめCPAN.pmが入っている必要があり、これまた、入っていなかったし、コンパイル環境もないので、コンパイル済みのMIPSel用のモジュールを手動でコピーしていきます。

その設定手順は以下の通りです。
testmail.cgiを作って、それを実行しながら足りないモジュールを入れていきました。

testmail.cgi
-------------------------------------------------------------------------------
#! /usr/bin/perl
#
# Net::SMTP でメール送信

require './jcode.pl';
use Net::SMTP;

$smtp_server_name='smtp.abc.ne.jp'; #SMTPサーバ名
$smtp_server_domain='abc.ne.jp"; #SMTPサーバのドメイン名
$smtp_from='mailfrom@abc.ne.jp'; #送信元の指定
$smtp_to='mailto@abc.ne.jp'; #宛先の指定
$subject='こんにちは'; #タイトル
$main_msg='メールの本文です'; #メッセージ本文

# オブジェクトの作成
$smtp = Net::SMTP->new($smtp_server_name, Hello=>$smtp_server_domain) or die;

#ヘッダ部の組み立て
$smtp->mail($smtp_from); #送信元の指定
$smtp->to($smtp_to); #宛先の指定

#データ部の組み立て
$date = &date;
$smtp->data();
$smtp->datasend("Date: $date\n");
#$smtp->datasend("From: $smtp_from\n");
$smtp->datasend("To: $smtp_to\n");
$smtp->datasend(&jis("Subject:$subject\n")); #漢字も送れるようにJIS変換して送る
$smtp->datasend("Content-Transfer-Encoding: 7bit\n");
$smtp->datasend("Content-Type: text/plain;charset=\"ISO-2022-JP\"\n\n");

#本文
$smtp->datasend(&jis("$main_msg\n")); #漢字も送れるようにJIS変換して送る

#最後の処理
$smtp->dataend(); #データの終わり
$smtp->quit; #SMTP接続の終了

sub jis {
$msg = $_[0]; &jcode'convert(*msg,'jis'); return $msg;
} # JIS変換

sub date {
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
@month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
$d = sprintf("%s, %d %s %04d %02d:%02d:%02d +0900 (JST)",
$week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec);
return $d;
}
-------------------------------------------------------------------------------

●testmail.cgiをwww/cgi-binに入れて実行してみる

bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't locate Net/SMTP.pm in @INC (@INC contains: /usr/lib/perl/5.6.1 /usr/share/
perl/5.6.1 /usr/local/lib/perl/5.6.1 /usr/local/share/perl/5.6.1 /usr/local/shar
e/perl /usr/lib/perl5 /usr/share/perl5 /usr/share/perl5 .) at ./testmail.cgi line
16.
BEGIN failed--compilation aborted at ./testmail.cgi line 16.
--------------------------------------------------------------------------------
このようなエラーが出るので足りないモジュールを入れていく

●Net/SMTP.pmを入れる(libnet-perl_1.19-1_all.deb 124KB)

http://packages.debian.org/stable/perl/ の libnet-perl (1:1.19-1) の all の
libnet-perl_1.19-1_all.deb をダウンロードします。
前のページで紹介した 7-Zip File Manager で解凍します。

libnet-perl_1.19-1_all.deb\data.tar.gz\data.tar\.\usr\share\perl5\Net\の中の
SMTP.pmを/mnt/hda/wwwにFTPで入れる
bash-2.05a# cd /mnt/hda/www
bash-2.05a# mkdir /usr/share/perl/5.6.1/Net
bash-2.05a# mv SMTP.pm /usr/share/perl/5.6.1/Net
bash-2.05a# ls /usr/share/perl/5.6.1/Net (SMTP.pmを確認するsato,hdusers,rw-rw-rw)
bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't locate Socket.pm in @INC (@INC contains: /usr/lib/perl/5.6.1 /usr/share/pe
rl/5.6.1 /usr/local/lib/perl/5.6.1 /usr/local/share/perl/5.6.1 /usr/local/share/
perl /usr/lib/perl5 /usr/share/perl5 /usr/share/perl5 .) at /usr/share/perl/5.6.
1/Net/SMTP.pm line 13.
BEGIN failed--compilation aborted at /usr/share/perl/5.6.1/Net/SMTP.pm line 13.
Compilation failed in require at ./testmail.cgi line 16.
BEGIN failed--compilation aborted at ./testmail.cgi line 16.
--------------------------------------------------------------------------------
このようなエラーが出るので更に足りないモジュールを入れていく

●Socket.pmなどを入れる(perl-base_5.6.1-8.9_mipsel.deb 182KB)

http://packages.debian.org/oldstable/base/perl-base の mipsel の
perl-base_5.6.1-8.9_mipsel.debをダウンロードします。
前のページで紹介した 7-Zip File Manager で解凍します。

perl-base_5.6.1-8.9_mipsel.deb\data.tar.gz\data.tar\.\usr\lib\perl\の中の5.6.1
フォルダをwwwにFTPで入れる
bash-2.05a# cd /mnt/hda/www
bash-2.05a# mkdir /usr/lib/perl
bash-2.05a# mv 5.6.1 /usr/lib/perl
bash-2.05a# ls /usr/lib/perl (5.6.1を確認する)
bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't locate Symbol.pm in @INC (@INC contains: /usr/lib/perl/5.6.1 /usr/share/pe
rl/5.6.1 /usr/local/lib/perl/5.6.1 /usr/local/share/perl/5.6.1 /usr/local/share/
perl /usr/lib/perl5 /usr/share/perl5 /usr/share/perl5 .) at /usr/lib/perl/5.6.1/
IO/Handle.pm line 7.
BEGIN failed--compilation aborted at /usr/lib/perl/5.6.1/IO/Handle.pm line 7.
Compilation failed in require at /usr/lib/perl/5.6.1/IO/Socket.pm line 11.
BEGIN failed--compilation aborted at /usr/lib/perl/5.6.1/IO/Socket.pm line 11.
Compilation failed in require at /usr/share/perl/5.6.1/Net/SMTP.pm line 15.
BEGIN failed--compilation aborted at /usr/share/perl/5.6.1/Net/SMTP.pm line 15.
Compilation failed in require at ./testmail.cgi line 16.
BEGIN failed--compilation aborted at ./testmail.cgi line 16.
--------------------------------------------------------------------------------
このようなエラーが出るので更に足りないモジュールを入れていく

●Symbol.pmなどを入れる(perl-base_5.6.1-8.9_mipsel.deb 前と同じ)

http://packages.debian.org/oldstable/base/perl-base の mipsel の
perl-base_5.6.1-8.9_mipsel.debをダウンロードします。
前のページで紹介した 7-Zip File Manager で解凍します。

perl-base_5.6.1-8.9_mipsel.deb\data.tar.gz\data.tar\.\usr\share\perl\の中の5.6.1
フォルダをwwwにFTPで入れる
念のため元からのファイルとダブるもの(★)はコピーしないようにFTPしたものを消しておく
参考:/usr/share/perl/5.6.1の中の元からあるもの
--------------------------------------------------------------------------------
-r--r--r-- 1 root root 4166 Dec 24 2003 Carp.pm ★
-r--r--r-- 1 root root 10377 Dec 24 2003 Exporter.pm ★
drwxr-xr-x 2 root root 1024 Jun 15 2004 Getopt
-r--r--r-- 1 root root 2624 Dec 24 2003 strict.pm ★
-r--r--r-- 1 root root 2746 Dec 24 2003 vars.pm ★
drwxr-xr-x 2 root root 1024 Jun 15 2004 warnings ★
-r--r--r-- 1 root root 14333 Dec 24 2003 warnings.pm ★
--------------------------------------------------------------------------------
bash-2.05a# cd /mnt/hda/www
bash-2.05a# mv 5.6.1/* /usr/share/perl/5.6.1
エラーが出るのでGetoptの中のLong.pmだけコピーし直します。
bash-2.05a# mv 5.6.1/Getopt/* /usr/share/perl/5.6.1/Getopt
bash-2.05a# ls /usr/share/perl (5.6.1を確認する)
bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't locate Net/Cmd.pm in @INC (@INC contains: /usr/lib/perl/5.6.1 /usr/share/p
erl/5.6.1 /usr/local/lib/perl/5.6.1 /usr/local/share/perl/5.6.1 /usr/local/share
/perl /usr/lib/perl5 /usr/share/perl5 /usr/share/perl5 .) at /usr/share/perl/5.6
.1/Net/SMTP.pm line 16.
BEGIN failed--compilation aborted at /usr/share/perl/5.6.1/Net/SMTP.pm line 16.
Compilation failed in require at ./testmail.cgi line 16.
BEGIN failed--compilation aborted at ./testmail.cgi line 16.
--------------------------------------------------------------------------------
このようなエラーが出るので更に足りないモジュールを入れていく

●Net/Cmd.pmを入れる(libnet-perl_1.19-1_all.deb 前と同じ)

http://packages.debian.org/stable/perl/ の libnet-perl (1:1.19-1) の all の
libnet-perl_1.19-1_all.deb をダウンロードします。
前のページで紹介した 7-Zip File Manager で解凍します。

libnet-perl_1.19-1_all.deb\data.tar.gz\data.tar\.\usr\share\perl5\の中のNet
をすべて/mnt/hda/wwwにFTPで入れる
bash-2.05a# cd /mnt/hda/www
bash-2.05a# mv Net/* /usr/share/perl/5.6.1/Net
bash-2.05a# ls /usr/share/perl/5.6.1/Net (Cmd.pmなどを確認する)
bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't call method "mail" on an undefined value at ./testmail.cgi line 20.
?どこが悪いんだろう? えーい、moduleの/usr/share/perl/5.6.1を全部入れちゃおう
後からわかりましたが、ここまでよさそうな気がします。
--------------------------------------------------------------------------------

●moduleの5.6.1を入れる(perl-modules_5.6.1-8.9_all.deb 1249KB)

http://packages.debian.org/oldstable/interpreters/perl-modules のperl-modules (5.6.1-8.9) [security]の all の
perl-modules (5.6.1-8.9) をダウンロードします。
前のページで紹介した 7-Zip File Manager で解凍します。

perl-modules_5.6.1-8.9_all.deb\data.tar.gz\data.tar\.\usr\share\perl\の中の
5.6.1をすべて/mnt/hda/wwwにFTPで入れる
念のため元からのファイルとダブるもの(★)はコピーしないようにFTPしたものを消しておく
参考:/usr/share/perl/5.6.1の中の元からあるもの
--------------------------------------------------------------------------------
-r--r--r-- 1 root root 4166 Dec 24 2003 Carp.pm ★
-r--r--r-- 1 root root 10377 Dec 24 2003 Exporter.pm ★
drwxr-xr-x 2 root root 1024 Jun 15 2004 Getopt
-r--r--r-- 1 root root 2624 Dec 24 2003 strict.pm ★
-r--r--r-- 1 root root 2746 Dec 24 2003 vars.pm ★
drwxr-xr-x 2 root root 1024 Jun 15 2004 warnings ★
-r--r--r-- 1 root root 14333 Dec 24 2003 warnings.pm ★
--------------------------------------------------------------------------------
bash-2.05a# cd /mnt/hda/www
bash-2.05a# mv 5.6.1/* /usr/share/perl/5.6.1
bash-2.05a# mv 5.6.1/File/* /usr/share/perl/5.6.1/File
bash-2.05a# mv 5.6.1/File/Spec/* /usr/share/perl/5.6.1/File/Spec
bash-2.05a# mv 5.6.1/Getopt/* /usr/share/perl/5.6.1/Getopt
bash-2.05a# mv 5.6.1/Net/* /usr/share/perl/5.6.1/Net
bash-2.05a# mv 5.6.1/Text/* /usr/share/perl/5.6.1/Text

bash-2.05a# ls /usr/share/perl/5.6.1 (確認する)
bash-2.05a# cd /mnt/hda/www/cgi-bin
bash-2.05a# ./testmail.cgi
--------------------------------------------------------------------------------
Can't call method "domain" on an undefined value at ./testmai.cgi line 16.
やっぱり、まだエラーだ!
$smtp = Net::SMTP->new('mail.abc.ne.jp') or die "Unable to open the connection";
のようにor die "..." としてみたら、どうも接続できていないようだ。

●Can't call method "domain"の対応

Net::PingやNet::POP3も試したがどうも接続できていないようだ。
ローカルルータの192.168.1.1にはpingはできた。

いろいろ試したが、
$smtp = Net::SMTP->new('mail.abc.ne.jp', Hello=>'abc.ne.jp') or die;
↑SMTPサーバ名を使うと×
$smtp = Net::SMTP->new('123.456.789.012', Hello=>'abc.ne.jp') or die;
↑IPアドレスは○

理由はよくわからないが、メールサーバをサーバ名でなく、IPアドレスにすることにした。

●漢字文字化け防止

jcode.plを使う方法

# JIS への変換に jcode.pl を用いる
require './jcode.pl';
# $subject, $msg を JIS に変換
&jcode::convert(\$subject,'jis');
&jcode::convert(\$msg,'jis');

# Content-type で文字コードを明示
print SDML "Content-type: text/plain;charset=\"ISO-2022-JP\"\n\n";
---------------------------------------------------------
jcode'convert(*mlsb, "jis");
jcode'convert(*mlms, "jis");
---------------------------------------------------------

base64.plを使う方法もあるようです
---------------------------------------------------------
ftp://ftp.dti.ad.jp/pub/lang/CPAN/scripts/mailstuff/base64.pl
---------------------------------------------------------

use MIME::Base64 ();
$subject = "さぶじぇくと test";
&jcode'convert(*subject, 'jis');
$subject = MIME::Base64::encode($subject);
chomp($subject);
$subject = "=?ISO-2022-JP?B?$subject?=";


●CPAN(Comprehensive Perl Archive Network)のインストール済みモジュールの確認方法

bash-2.05a# cd /
bash-2.05a# find `perl -e 'print "@INC"'` -name '*.pm' -print

モジュールの追加前と追加後のリスト

これで、perlのCGIのBBSに投稿したときに、その内容がメールで転送できるようになり、目標達成です。


[ホーム][戻る][次へ] 12 by A.Sato