Perl/CGI研究室 'PERL-LABO'

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Cc、Bccに対応

研究内容

メールのヘッダには、To、Fromなどの必須のものの他に、 返信先メールアドレスを表すReply-toや、 同じメールを他の人にも送るCc、Bccなどがあります。 今回はCc、Bccに対応しましょう。

詳細

今回対応するメールヘッダ

今回の研究では、次のメールヘッダに対応したいと思います。

Cc カーボンコピーの略。「シーシー」と読みます。 ここに指定したメールアドレスにも同じメールが送信されます。 この人にもそのメールが送信されたことを、Toに指定されたメールの受信者は知ることができます。 メールの受信者はあくまでToに指定された人で、Ccに指定された人は参考というかオマケ的に 送信されたっていうイメージです。
Bcc ブラインドカーボンコピーの略。「ビーシーシー」と読みます。 ここに指定したメールアドレスにも同じメールが送信されます。 この人にもそのメールが送信されたことを、Toに指定されたメールの受信者は知ることが「できません」。 同じメールを内緒で他の人にも送るときに使います。

作成したCGIプログラム

sendmail.pl
# v 1.03

package plab;

# Jcode.pm を使用します。
use Jcode;

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

# 引数 (差出人名, 差出人メールアドレス, 送信先名, 送信先メールアドレス, 
#       件名, 本文 [, 返信先名, 返信先メールアドレス, 日時とホストを追加しない1]
#       [, Cc名, Ccアドレス, Bcc名, Bccアドレス])
# いずれも空欄可
sub sendmail
{
	local $from_name  = $_[0];
	local $from_adr   = $_[1];
	local $to_name    = $_[2];
	local $to_adr     = $_[3];
	local $subject    = $_[4];
	local $body       = $_[5];
	local $rep_name   = $_[6];
	local $rep_adr    = $_[7];
	local $notimehost = $_[8];
	local $cc_name    = $_[9];
	local $cc_adr     = $_[10];
	local $bcc_name   = $_[11];
	local $bcc_adr    = $_[12];

	# Fromメールアドレスがからっぽだとエラーになるので
	if ($from_adr eq "") {
		return 0;
	}

	# JIS に変換します。
	local $jis_body = Jcode::convert($body, 'jis');

	# MIMEヘッダ内の日本語をエンコードします。
	local $header_subject = mimeencode_headnamemail('Subject',  $subject);
	local $header_from    = mimeencode_headnamemail('From',     $from_name, $from_adr);
	local $header_to      = mimeencode_headnamemail('To',       $to_name,   $to_adr);
	local $header_replyto = mimeencode_headnamemail('Reply-To', $rep_name,  $rep_adr);
	local $header_cc      = mimeencode_headnamemail('Cc',       $cc_name,   $cc_adr);
	local $header_bcc     = mimeencode_headnamemail('Bcc',      $bcc_name,  $bcc_adr);

	if (! open(MAIL, "| $sendmailpath -t")) {
		return 0;
	}

	# メールヘッダ〜本文を出力します。
	print MAIL "$header_from\n";
	print MAIL "$header_to\n";
	if ($rep_adr ne "") { print MAIL "$header_replyto\n"; }
	if ($cc_adr  ne "") { print MAIL "$header_cc\n"; }
	if ($bcc_adr ne "") { print MAIL "$header_bcc\n"; }
	print MAIL "$header_subject\n";
	print MAIL "Content-Transfer-Encoding: 7bit\n";
	print MAIL "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
	print MAIL "\n";
	print MAIL "$jis_body";

	if ($notimehost ne "1") {
		# ホスト名、送信時間を付加します。
		local $ip   = $ENV{'REMOTE_ADDR'};
		local $host = gethostbyaddr(pack("C4", split('\.', $ip)), 2) || $ip;
		local @tim  = localtime(time());
		local $year = $tim[5] + 1900;
		local $mon  = $tim[4] + 1;
		local $t    = sprintf('%02d:%02d:%02d', $tim[2], $tim[1], $tim[0]);

		print MAIL "\n";
		print MAIL "----------------------------\n";
		print MAIL "DateTime : $year/$mon/$tim[3] $t\n";
		print MAIL "Host     : $host";
	}

	close MAIL;

	return 1;
}

# メールヘッダを作る
# 引数(ヘッダ名, 名前, メールアドレス)
sub mimeencode_headnamemail
{
	local ($head, $name, $mail) = @_;

	if ($name eq "" && $mail eq "") { return ""; }

	# 汚染チェック
	$mail =~ s/\r|\n//g;

	local $jis_name  = Jcode::convert($name, 'jis');
	local $mime_name = Jcode::mime_encode([\$jis_name]);

	if ($name ne "" && $mail eq "") { return "$head: $mime_name";        }
	else                            { return "$head: $mime_name<$mail>"; }
}

1;

考察

引数がさらに増えました

引数がどんどん増えていきますね。 でも、新しく追加した引数は、不要なら指定しなければいままで通りの働きをしますし。 さらに機能が増えて使い道も増えたと思います。

まとまった処理は別関数に

文字コードをjisに変えたり、MIMEエンコードしたりといった処理を それぞれのヘッダでする必要がありますので、 別関数 mimeencode_headnamemail としました。 同じ処理を関数にするっていうのはプログラム作成の基本ですね。 でもこの sendmail 関数、あんまり綺麗じゃありません。 なんだか納得がいかないのですが、 よい案も浮かばず…。です。

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Copyright (c) 'PERL-LABO' All Rights Reserved.  リンクフリーです。