メインメニュー
  
トップ  >  perl関連
 このカテゴリには 1 件のファイルがあります  |  表示数   |  
ソート順  タイトル () 掲載日 () 評価 () ダウンロード数 ()
現在のソート順: ヒット数(少ないものから)

カテゴリ perl関連
ActivePerlでメールを送るプログラム(SendMailモドキ)
投稿者: ガキソン   バージョン: 1.00   掲載日:  2012-1-24
説明
自宅サーバーなどでホームページを作ってると
Web上からメールを送りたいor受け取りたいということもあります。
ということでSendMailを動かしてみましょう。
SendMailというソフトそのものは、この記事を書いた時点ではwindowsのほうには無いようですが、
この記事では、Windows上で動くSendMailと似た動きをするのソースを紹介します。




# ------------------------------------------------------- #
#
#      SMTPメール送信
#
# ------------------------------------------------------- #
# 【 概要 】
#    SMTPメール送信

# 動作環境  : XP & ActivePerl5.8.0 & httpd1.40d
# 書式    : perl sendmail.pl [-itfr] [address]
# 作者    : Gakison
# ------------------------------------------------------- #
# 【 Program name 】
# sendmail.pl
# ------------------------------------------------------- #
# 【 更新履歴 】
# 2003/09/09 - 作成
# ------------------------------------------------------- #
# -------- ソケットモジュ?ルの輸入 --------------------- #
use Socket;
# ------------------------------------------------------- #
# 接続情報の設定
# ------------------------------------------------------- #
#
#注:# $pop3,$user,$passは、POP before SMTP 対策用になります
#
$smtp = 'XXXX.XXXXXXX.XX.XX'; # SMTPサーバ名、又はIPアドレス(設定してね)
$from = 'XXXX.XXXXXXX.XX.XX'; # 送信元(設定してね)
$pop3 = ''; # POP3サーバ名、又はIPアドレス(なるべく空)
$user = ''; # ユーザーID (なるべく空)
$pass = ''; # ぱすわーど (なるべく空)

# ------------------------------------------------------- #
# あまり気にしなくて良い設定
# ------------------------------------------------------- #
$logs = 0 ; # 1 = エラーログの作成
$timeout = 10; # タイムアウトまでの時間(秒)
$ReOverwrite = 0 ; # 1 = 送信元をすべて $from にする
$logfile = './sendmail.log' ; # ログの出力先とファイル名
# ------------------------------------------------------- #
# 文字コード変換ライブラリの使用
# ------------------------------------------------------- #

require './jcode.pl';

###########################################################
#
# 上記までが設定情報
#
###########################################################

# ------------------------------------------------------- #
# タイムアウト処理
# ------------------------------------------------------- #
#
# 注:ActivePerl5.8.0 以下をお使いの方はalarmが実装されていないのでエラーが出ます。
#
$SIG{"ALRM"} = sub {&error('#Error#タイムアウト!')};
alarm $timeout;

# ------------------------------------------------------- #
# POP before SMTP 対策
# ------------------------------------------------------- #

unless($pop3 eq '') { &pop3; }

# ------------------------------------------------------- #
# コマンドライン引数解析処理
# ------------------------------------------------------- #
$p="rf";

while($_ = shift @ARGV){
if(s/^-(.)(.*)/$2 ne "" && "-$2"/e){
if(index($p,$1) >= 0){
$P{$1} = $2 ne "" ? $2 : shift @ARGV;
}else{
$P{$1} = 1;
redo;
}
}else{
push(@tos,$_) if /^.+\@.+\..+$/;
}
}

# ------------------------------------------------------- #
# メール本文の受信
# ------------------------------------------------------- #
while(<>){
last if !$P{i} && /^\.\x0D?\x0A/;
s/^\./../;
$mail .= $_;
@head = split(/\x0D?\x0A/,$mail) if ! @head && /^\x0D?\x0A/;
}

# ------------------------------------------------------- #
# ヘッダの解析 // -t 送信先の抽出/BCC削除/From書換処理/Bcc削除
# ------------------------------------------------------- #
foreach $i (0..$#head){
if($head[$i] =~ /^([A-Z].*?)\s*:/){
$HEAD{($n = $1)} = $head[$i];
$HEAD{$n} .= $head[++$i] if $head[$i + 1] =~ /^\s/;
}
}

$from = $P{'f'} if $P{'f'};
if($P{"t"}){
$to = $HEAD{"To"};
$cc = $HEAD{"Cc"};
$bcc = $HEAD{"Bcc"};
}

$from =~ /^.+\@.+\..+$/ || &error("#Error#fromメールアドレスが不正です。$from");
for($from,$to,$cc,$bcc){
s/^(?:To|Bcc|Cc|From)\s*:\s*//;
s/"(?:[^"]|\")*"//g;
1 while s/\([^()]*\)//g;
}
if($P{"t"}){
@to = split(/,/,$to);
@cc = split(/,/,$cc);
@bcc = split(/,/,$bcc);
}
for($from,@to,@cc,@bcc,@tos){
$_ = $1 if /<([^>]*)>/;
s/^[\s\x0D\x0A]+|[\s\x0D\x0A]+$//g;
undef $_ unless /^.+\@.+\..+$/;
$tos++;
}

$mail =~ s/Bcc\s*:(?:\s+[^\x0D\x0A]*\x0D?\x0A)+//;
if ($ReOverwrite) { $mail =~ s/From\s*:(?:\s+[^\x0D\x0A]*\x0D?\x0A)+/From: $from\x0D\x0A/; }

# ------------------------------------------------------- #
# 最終チェック
# ------------------------------------------------------- #
$ENV{'SERVER_NAME'} = $smtp unless $ENV{'SERVER_NAME'};
&error('#Error#送信元アドレスがありません') unless $from;
&error('#Error#送信先アドレスがありません') unless $tos;

# ------------------------------------------------------- #
# SOCKETの作成
# ------------------------------------------------------- #
# PORT番号を取得します
$port = '';
if ($port eq '') { $port = getservbyname('smtp','tcp'); }
if ($port eq '') { $port = 25; }

# PORT、IPで構造体を作成する
$sock_addr = sockaddr_in($port,inet_aton($smtp)) ;

# ソケットの生成
unless(socket(SOCK, PF_INET, SOCK_STREAM, 0)){
&error('ソケットの生成失敗。$!') ;
}

# 接続
unless(connect(SOCK, $sock_addr )){
&error('接続失敗。') ;
}

# ソケットのバッファリングは行わない
select(SOCK); $| = 1; select(STDOUT);

$respons = <SOCK> ;

unless($respons =~ /^220/) {
&error('接続失敗。') ;
}

# ------------------------------------------------------- #
# コマンドの送信
# ------------------------------------------------------- #

# -------- HELOコマンドの送信とレスポンスの確認 --------- #

# コマンドの作成、送信
#$command = "HELO $ENV{'SERVER_NAME'}\n";
$command = "HELO $smtp\n";
print SOCK $command ;

# レスポンスの受信、確認
$respons = <SOCK> ;
&decode(\$respons) ;

# レスポンスの確認
unless($respons =~ /^250/){
&error("HELOコマンド失敗 $!") ;
}

# -------- MAILコマンドの送信とレスポンスの確認 ------- #

# コマンドの作成、送信
$command = "MAIL FROM:<$from>\n";
print SOCK $command ;

# レスポンスの受信、確認
$respons = <SOCK> ;
&decode(\$respons) ;

unless($respons =~ /^250/){
print SOCK "RSET\n";
&error("MAILコマンド失敗 $!") ;
}

# -------- RCPTコマンドの送信とレスポンスの確認 --------- #

foreach $head (@to,@cc,@bcc,@tos){
next unless $head; # 該当する個体がなし -> スキップ

# コマンドの作成、送信
$command = "RCPT TO:<$head>\n";
print SOCK $command ;

# レスポンスの受信、確認
$respons = <SOCK> ;
&decode(\$respons) ;

unless($respons =~ /^25[0|1]/){
print SOCK "RSET\n";
&error("RCPTコマンド失敗 $!") ;
}

}

# -------- DATAコマンドの送信とレスポンスの確認 --------- #

# コマンドの作成、送信
$command = "DATA\n";
print SOCK $command ;

# レスポンスの受信、確認
$respons = <SOCK> ;
&decode(\$respons) ;

unless($respons =~ /^354/){
print SOCK "RSET\n";
&error("DATAコマンド失敗 $!") ;
}

# -------- ヘッダ、本文の送信とレスポンスの確認 --------- #

# 文字コードの変換
&jcode'convert(*mail,'jis');

# コマンドの作成、送信
$command = "$mail\n.\n";
print SOCK $command ;

# レスポンスの受信、確認
$respons = <SOCK> ;
&decode(\$respons) ;

unless($respons =~ /^250/){
print SOCK "RSET\n";
&error("本文、ヘッダ部送信失敗 $!") ;
}

# --------QUITコマンドの送信 -------- #

# コマンドの作成、送信
$command = "QUIT\n";
print SOCK $command ;

# --------切断 -------- #

close(SOCK); select(STDOUT);
&error('MAILは正常に送信されました。');

alarm 0;
exit;

# --------------------
# 改行コード変換
# --------------------
sub decode{

my $inf = $_[0];
$$inf =~ s/\x0D\x0A|\x0D|\x0A/\n/g;

}

# ------------------------------------------------------- #
# POP3処理
# ------------------------------------------------------- #
sub pop3{

# PORT番号を取得します
$port = '';
if ($port eq '') { $port = getservbyname('pop-3', 'tcp'); }
if ($port eq '') { $port = getservbyname('pop3', 'tcp'); }
if ($port eq '') { $port = 110; }

# PORT、IPで構造体を作成する
$sock_addr = sockaddr_in($port,inet_aton($pop3)) ;

# ソケットの生成
unless(socket(SOCK, PF_INET, SOCK_STREAM, 0)){
&error('ソケットの生成失敗。$!') ;
}

# 接続
unless(connect(SOCK, $sock_addr )){
&error('接続失敗。$!') ;
}

# ソケットのバッファリングは行わない
select(SOCK); $| = 1; select(STDOUT);

# レスポンスの受信、確認
$respons = <SOCK> ;

unless($respons =~ /^\+OK/) {
close(SOCK); &error("接続失敗。$!") ;
}

# -------- ユーザー名の送信とレスポンスの確認 --------- #

# コマンドの作成、送信
print SOCK "USER $user\r\n";

# レスポンスの受信、確認
$respons = <SOCK> ;

unless($respons =~ /^\+OK/) {
close(SOCK); &error("ユーザー名の送信失敗。$!") ;
}


# -------- パスワードの送信とレスポンスの確認 --------- #

# コマンドの作成、送信
print SOCK "PASS $pass\r\n";

# レスポンスの受信、確認
$respons = <SOCK> ;

unless($respons =~ /^\+OK/) {
close(SOCK); &error("パスワードの送信失敗。$!") ;
}

# --------QUITコマンドの送信 -------- #

print SOCK "QUIT\r\n";

# レスポンスの受信、確認
$respons = <SOCK> ;

unless($respons =~ /^\+OK/) {
close(SOCK); &error("切断失敗。$!") ;
}

# --------切断 -------- #

close(SOCK);
}

# ------------------------------------------------------- #
# エラー処理 (sendmail.logファイルに書き出し)
# ------------------------------------------------------- #
sub error{
@a=@_;
print SOCK "QUIT\r\n";
close(SOCK);
if($logs && open(OUT,">> $logfile")){
$a[0] =~ s/\r?\n//g;
($sec,$min,$hour,$day,$mon)=localtime(time);$mon++;
@d=("00".."59");
print OUT "[$d[$mon]/$d[$day] $d[$hour]:$d[$min]:$d[$sec]] $a[0]\n";
close(OUT);
}
exit;
}



[ ファイル名 ] sendmail.zip [ MD5 checksum ] a5a367da270bdcc6bd80bd7bd8a7da60
ダウンロード数 60   ファイルサイズ 2.96 KB   ホームページ おもいつき広場
評価 0 (0 票)
評価する  | ファイル破損/リンク切れを報告 |  友達に伝える |  詳細な説明を見る  | ガキソン さんの投稿をもっと!



Powered by おもいつき広場© 2001-2012 iexcl Project