#!/usr/bin/perl
use GD;
以下のサンプルファイルを image.cgi と名前を付けて保存、アクセス権を chmod +x image.cgi とかして ブラウザから http://yourname.com/image.cgi とかにアクセスすればよい。
注意点としては、このスクリプトは画像しか表示できないことである。これと一緒に HTML ファイルを表示しようと思っても、HTTP プロトコルの仕様上不可能である。なぜかというと HTTP プロトコルを通して画像を表示する場合は、すでにこのスクリプトが HTTP ヘッダとして Content-type: image/jpeg を最初に出力してブラウザが受け取っているからで、このスクリプトの中で同時に(画像を表示した後に) HTML 文書を表示させようとて Content-type: text/html を出力(print "Content-type: text/html\n\n)してもブラウザは受け付けてくれないのである。
#!/usr/bin/perl
use GD;
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
のようにBase64 でエンコードされていることである。
それでは Perl でサブジェクトを Base64 処理してメールを送るにはどうしたらいいだろう?ズバリ、「Base64エンコード・デコードする」が詳しい。より具体的には、リンク先のページを少し下にいったところの、add_econde_word という関数である。しかしこのモジュールは jcode.pl を使う。
Perl 5.8 以上であれば、use Encode; とできそうだが、このモジュール、個人的にはあまり完成度が高くないと思っている。完成度なら Unicode::Japanese の方がスマートだし使いやすい。従って以下にjcode.pl の部分を、Unicode::Japanese で置き換えた例を示す。
使用するクラス
use Unicode::Japanese;
use MIME::Base64;
#!/usr/bin/perl
use Unicode::Japanese;
use MIME::Base64;
sub add_encode_word {
my($str, $line) = @_;
my $result;
my $ascii = '[\x00-\x7F]';
my $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
my $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
# この次の while 以下は EUC の文字列を対象に処理することになっているため
$str = Unicode::Japanese->new($str, 'auto')->euc;
while (length($str)) {
my $target = $str;
$str = '';
if (length($line) + 22 + ($target =~ /^(?:$twoBytes|$threeBytes)/o) * 8
> 76) {
$line =~ s/[ \t\n\r]*$/\n/;
$result .= $line;
$line = ' ';
}
while (1) {
# EUC を JIS に直す
$target = Unicode::Japanese->new($target, 'euc')->jis;
my $encoded = '=?ISO-2022-JP?B?' .
encode_base64($target, '') . '?=';
if (length($encoded) + length($line) > 76) {
$target =~ s/($threeBytes|$twoBytes|$ascii)$//o;
$str = $1 . $str;
} else {
$line .= $encoded;
last;
}
}
}
$result . $line;
}
print add_encode_word('サブジェクトのテストです', 'Subject: ');
1;
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
わざわざ Subject: というヘッダを含めて add_encode_word 関数に渡している理由は、メールの場合は Subject: ヘッダに日本語が来る場合、Base64 でエンコードするにしても 1行は 76バイト以内と決まっているためで、この 1行とは、ヘッダ名の Subject: 自体の文字数(9バイト)を勘案する必要があるためだ。
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
のようにBase64 でエンコードされていることである。
それでは Perl でサブジェクトを Base64 処理してメールを送るにはどうしたらいいだろう?ズバリ、「Base64エンコード・デコードする」が詳しい。より具体的には、リンク先のページを少し下にいったところの、add_econde_word という関数である。しかしこのモジュールは jcode.pl を使う。
Perl 5.8 以上であれば、use Encode; とできそうだが、このモジュール、個人的にはあまり完成度が高くないと思っている。完成度なら Unicode::Japanese の方がスマートだし使いやすい。従って以下にjcode.pl の部分を、Unicode::Japanese で置き換えた例を示す。
使用するクラス
use Unicode::Japanese;
use MIME::Base64;
#!/usr/bin/perl
use Unicode::Japanese;
use MIME::Base64;
sub add_encode_word {
my($str, $line) = @_;
my $result;
my $ascii = '[\x00-\x7F]';
my $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
my $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
# この次の while 以下は EUC の文字列を対象に処理することになっているため
$str = Unicode::Japanese->new($str, 'auto')->euc;
while (length($str)) {
my $target = $str;
$str = '';
if (length($line) + 22 + ($target =~ /^(?:$twoBytes|$threeBytes)/o) * 8
> 76) {
$line =~ s/[ \t\n\r]*$/\n/;
$result .= $line;
$line = ' ';
}
while (1) {
# EUC を JIS に直す
$target = Unicode::Japanese->new($target, 'euc')->jis;
my $encoded = '=?ISO-2022-JP?B?' .
encode_base64($target, '') . '?=';
if (length($encoded) + length($line) > 76) {
$target =~ s/($threeBytes|$twoBytes|$ascii)$//o;
$str = $1 . $str;
} else {
$line .= $encoded;
last;
}
}
}
$result . $line;
}
print add_encode_word('サブジェクトのテストです', 'Subject: ');
1;
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
わざわざ Subject: というヘッダを含めて add_encode_word 関数に渡している理由は、メールの場合は Subject: ヘッダに日本語が来る場合、Base64 でエンコードするにしても 1行は 76バイト以内と決まっているためで、この 1行とは、ヘッダ名の Subject: 自体の文字数(9バイト)を勘案する必要があるためだ。
open(SEND, '/usr/sbin/sendmail') || die;use Net::SMTP; use MIME::Entity;
#!/usr/bin/perl
use Net::SMTP;
use MIME::Entity;
# Settings
our $SENDER = '送信元のメールアドレス';
our $RECIPIENT = '送信先のメールアドレス';
our $SUBJECT = 'タイトル';
our $ATTACHED_FILE_1 = '/home/youraccount/添付ファイル名その1.jpg';
our $ATTACHED_FILE_2 = '/home/youraccount/添付ファイル名その2.jpg';
# Create object
my $smtp=Net::SMTP->new('localhost',
HELLO=>'yourmailsever.yourdomain.com');
# Built headers
$smtp->mail($SENDER); # Sender
$smtp->to ($RECIPIENT); # Receiver
# Built Data (Create data by MIME::Entity)
$smtp->data();
my $mime = MIME::Entity->build(
From => $SENDER , # Sender (data)
To => $RECIPIENT, # Receiver (data)
Subject => $SUBJECT , # Subject
Data => ['']); # body
# Attached file
$mime->attach(
Path => $ATTACHED_FILE_1,
Type => 'image/jpeg',
Encoding => 'Base64'
);
# Attached file
$mime->attach(
Path => $ATTACHED_FILE_2,
Type => 'image/jpeg',
Encoding => 'Base64'
);
# Attached file (Text)
# $mime->attach(
# Path => $ATTACHED_FILE,
# Type => 'text/plain',
# Encoding => '-SUGGEST'
#);
$smtp->datasend($mime->stringify); # transfer strings
# Data termination and send mail
$smtp->dataend();
#Quit SMTP connection
$smtp->quit;
# for debug
print "Sender : $SENDER\n";
print "Recipient : $RECIPIENT\n";
print "Attached : $ATTACHED_FILE\n";
1;open(SEND, '/usr/sbin/sendmail') || die;use Net::SMTP; use MIME::Entity;
#!/usr/bin/perl
use Net::SMTP;
use MIME::Entity;
# Settings
our $SENDER = '送信元のメールアドレス';
our $RECIPIENT = '送信先のメールアドレス';
our $SUBJECT = 'タイトル';
our $ATTACHED_FILE_1 = '/home/youraccount/添付ファイル名その1.jpg';
our $ATTACHED_FILE_2 = '/home/youraccount/添付ファイル名その2.jpg';
# Create object
my $smtp=Net::SMTP->new('localhost',
HELLO=>'yourmailsever.yourdomain.com');
# Built headers
$smtp->mail($SENDER); # Sender
$smtp->to ($RECIPIENT); # Receiver
# Built Data (Create data by MIME::Entity)
$smtp->data();
my $mime = MIME::Entity->build(
From => $SENDER , # Sender (data)
To => $RECIPIENT, # Receiver (data)
Subject => $SUBJECT , # Subject
Data => ['']); # body
# Attached file
$mime->attach(
Path => $ATTACHED_FILE_1,
Type => 'image/jpeg',
Encoding => 'Base64'
);
# Attached file
$mime->attach(
Path => $ATTACHED_FILE_2,
Type => 'image/jpeg',
Encoding => 'Base64'
);
# Attached file (Text)
# $mime->attach(
# Path => $ATTACHED_FILE,
# Type => 'text/plain',
# Encoding => '-SUGGEST'
#);
$smtp->datasend($mime->stringify); # transfer strings
# Data termination and send mail
$smtp->dataend();
#Quit SMTP connection
$smtp->quit;
# for debug
print "Sender : $SENDER\n";
print "Recipient : $RECIPIENT\n";
print "Attached : $ATTACHED_FILE\n";
1;