#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃■(SS)C−BOARDライブラリ(とほほ改ver1.1.06) #┠────────────────────────────────────── #┃投稿関係の関数が含まれています。 #┃ #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ package POST; require './lib/mji.pl'; require './cmd/etc.pl'; #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ オートローダー #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub AUTOLOAD { my $name = ($AUTOLOAD =~ /^POST::(.+)$/)[0]; push(@{$::FLAG{'eval'}}, $AUTOLOAD); if (!defined $SUB{$name}) { &::error(\"定義されていない関数($AUTOLOAD)が呼ばれました。"); exit; } eval $SUB{$name}; length($@) && &::error(\"EVAL ERROR: $@ ($AUTOLOAD)"); delete $SUB{$name}; goto &{'POST::' . $name}; } %SUB = ( input => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 投稿画面表示 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub input { do "$::FLAG{'template'}/psn.txt"; #── 返信の場合 my($subject, $reference); my $body; if ($::FORM{'follow'}) { require './lib/file/msg.pl'; require './lib/htm.pl'; require './cmd/msg.pl'; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); (my $r_MSG = $o_message->one($::FORM{'follow'})) or &::error(\'返信元の記事を読み込めませんでした。'); local *MSG = $r_MSG; $o_message->close(); #── レス数制限 if ($CNF::post{'resnumres'}{'mode'}) { if ($CNF::post{'resnumres'}{'max'} == 0) { # レス完全禁止 &::error(\'管理人により返信が禁止されています。'); } else { # レス数禁止(現在のレス数をチェックする−ファイルアクセスが増える) require './lib/file/tre.pl'; my $o_tree = new FILE::TREE($CNF::place{'data'}{'path'}); my $r_topic; $r_topic = $o_tree->one($MSG{'tree'}); my $r_MSG_tpc = ${$r_topic}[0]; ${$r_MSG_tpc}{'reply'} = $#{$r_topic}; local *MSG_tpc = $r_MSG_tpc; $o_tree->close; if ($MSG_tpc{'reply'} >= $CNF::post{'resnumres'}{'max'}) { &::error(\"返信記事数が管理人が設定した制限数($CNF::post{'resnumres'}{'max'})を越えています。"); } } } if ($CNF::post{'quot'}{'number'}{'mode'}) { if ($MSG{'subject'} =~ /^Re\((\d+)\):(.*)$/) { $subject = 'Re(' . ($1 + 1) . "):$2"; } elsif ($MSG{'subject'} =~ /^Re:(.*)$/) { $subject = "Re(1):$1"; } else { $subject = "Re(1):$MSG{'subject'}";} } else { $subject = ($MSG{'subject'} =~ /^Re(?:\(\d+\))?:(.*)$/) ? "Re:$1" : "Re:$MSG{'subject'}"; } $::FLAG{'mobile'}{'hdml'} && ($subject =~ s/\$/&dol;/g); #── 引用の場合 if (!$::FORM{'no_quot'}) { $body = $MSG{'body'}; chomp($body); $CNF::post{'emoji'}{'mode'} && &EMOJI::cancel(\$body); &HTML::escape(&ETC::option_unlink(&HTML::auto_unlink(\$body))); $body =~ s/^/$CNF::post{'quot'}{'icon'}/gmo; $CNF::post{'quot'}{'name'}{'mode'} && ($body = join($MSG{'name'}, @{$CNF::post{'quot'}{'name'}{'icon'}}) . "\n" . $body); } #── 参照文 $MSG{'typewriter'} && ($MSG{'body'} = "$MSG{'body'}"); my $reference = $MSG{'body'}; $r_reference = &DESIGN::reference(&MESSAGE::quot_color(\$reference)); } #── 各種入力欄の設定 my $upload_input; $CNF::upload{'mode'} && map($upload_input .= ${&DESIGN::upload_input}, (0 .. ($CNF::upload{'enable'}{'number'} - 1))); $CNF::mail{'inform'}{'mode'} && (my $r_inform_mail_input = &DESIGN::inform_mail_input); $CNF::mail{'owner'}{'mode'} && (my $r_owner_mail_input = &DESIGN::owner_mail_input); $CNF::view{'genre'}{'mode'} && (my $r_genre_input = &DESIGN::genre_input); $CNF::view{'tree'}{'sort'}{'mode'} && $CNF::post{'sage'}{'mode'} && (my $r_sage_input = &DESIGN::sage_input); $CNF::view{'body_color'}{'mode'} && (my $r_body_color_input = &DESIGN::body_color_input); if($::FORM{'cmd'} ne "mdt"){&tohoho;} #── 表示 &BASE::head('psn'); &DESIGN::post($r_genre_input, \$subject, \$body, \$upload_input, $r_sage_input, $r_inform_mail_input, $r_owner_mail_input, $r_reference, $r_body_color_input, $r_postkey_input, $upfile_list, $upfile_size, $upfile_com, $upsize_com, $sub_com, $name_com, $email_com, $key_com, $body_com, $web_com, $gen_com); &BASE::foot('psn'); } __SUB__ parameter => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ パラメーターをセット #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub parameter { require './lib/file/msg.pl'; my @error; #── 記事番号を設定 my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); if (my $r_MSG = $o_message->read(0, 1)) { $o_message->close; $::FORM{'no'} = ${$r_MSG}{'no'} + 1; } elsif ($o_message->init()) { push(@error, '記事番号の取得に失敗しました。'); } else { $::FORM{'no'} = 1;} #── ツリー番号を設定 if ($::FORM{'follow'}) { $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); (my $r_MSG = $o_message->one($::FORM{'follow'})) or push(@error, '返信元の記事を見つけれませんでした。'); $::FORM{'tree'} = ${$r_MSG}{'tree'}; $o_message->close; } else { $::FORM{'tree'} = $::FORM{'no'};} #── ホスト情報を設定 $::FORM{'host'} = &CGI::get_host(0); $::FORM{'host_ext'} = join(', ', @{&CGI::get_host(1)}); #── 日付を設定 $::FORM{'date'} = &COMMON::date($CNF::dformat{'post'}); #── IDを設定 $::FORM{'user_id'} = $::COOKIE{'user_id'}; #── 識別番号(そのままでは長いので削る) $::FORM{'ident'} = substr(&COMMON::sha1(\"$::FORM{'name'}\t$::FORM{'key'}"), 0, 10); #── クライアント情報を設定 $::FORM{'agent'} = $ENV{'HTTP_USER_AGENT'} || 'unknown'; &COMMON::jsubstr(&HTML::escape(\$::FORM{'agent'}), 80); #── 時間を設定 $::FORM{'time'} = $::FLAG{'time'}; #── 携帯かどうか設定 $::FLAG{'mobile'}{'mode'} && ($::FORM{'mobile'} = 1); #── 添付ファイルの情報を設定 delete $::FORM{'file'}; if ($::FLAG{'file'}) { (!$CNF::upload{'mode'} || !$::FLAG{'master'} && $CNF::upload{'mode'} != 2) && &::error(\'ファイルのアップロードは禁止されています。'); $::FORM{'file'} = $::FLAG{'file'}; foreach (@{$::FORM{'file'}}) { (${$_}{'name'} =~ /\.(?:bmp|gif|jpe?g|png)$/i) or next; my $r_screen = &COMMON::get_image_size("$CNF::place{'file'}{'path'}/" . ${$_}{'name'}); if (!$r_screen) { push(@error, '画像のサイズの取得に失敗しました。'); last; } ${$_}{'screen'} = join('*', @{$r_screen}); } } return(@error ? \@error : 0); } __SUB__ check => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ いろいろチェック #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub check { my @error; #── 名前をチェック if ($ENV{'HTTP_USER_AGENT'} eq "unknown") { push(@error, "UserAgentが正しく認識できないため投稿を受け付けられません。(スパム対策)万が一このエラーのために投稿できない方は管理者までご連絡ください。");}#とほほ修正 #── 名前をチェック my $name = $::FORM{'name'}; my $master = $CNF::master{'name'}; (!$::FLAG{'master'} && (&ETC::name_matching($name,$master,$CNF::master{'mode'}))) && return(['管理人と同じ名前は使えません。']); #── 新規スレッド立てチェック if (!$::FORM{'follow'}) { (!$::FLAG{'master'} && $CNF::permission{'pst'}{'master'}{'modenew'}) && return(['管理人以外は新規スレッドを投稿できません']); } #── 投稿元をチェック $CNF::post{'referer_check'}{'mode'} && !$::FLAG{'mobile'}{'mode'} && !$::FLAG{'incm'} && ($ENV{'HTTP_REFERER'} !~ /^\Q$CNF::place{'this'}{'url'}\E/) && push(@error, '投稿元が不正です。'); #── アクセス権チェック if ($CNF::permission{'pst'}{'mode'}) { require './cmd/prm.pl'; &PERMISSION::check('pst'); } #── プロキシ経由かチェック ($CNF::post{'no_proxy'}{'mode'} && !&CGI::check_proxy(&CGI::get_host(1))) && push(@error, 'プロキシサーバーを経由しての書き込みは' . '禁止されています。'); #── ここまででエラーがある場合は出力 @error && return(\@error); #── 投稿データチェック @error = @{&check_parameter}; $::FLAG{'check'} = 1; #── 二重投稿チェック my $o_identify; if (!$::FLAG{'master'} && !$::FORM{'preview'} && ($::FORM{'cmd'} ne 'mdt')) { my $result; ($o_identify, $result) = &identify; ($::FLAG{'debug'} == 2) && ($result = 2); if ($result == 0) { push(@error, '同一内容の再投稿は禁止されています。'); } elsif ($result == 1) { push(@error, "管理人($CNF::master{'name'})以外は" . "$CNF::post{'interval'}秒以内の再投稿は出来ません。"); } } return((@error ? \@error : 0), $o_identify); } __SUB__ check_parameter => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 投稿データチェック #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub check_parameter { # もろもろの事情により(?)SJISであることをそれほど意識せずに # 処理しています require './lib/htm.pl'; my @error; my %item = qw( name 名前 email メールアドレス subject 題名 body 本文 key パスワード web ホームページアドレス ); my $os; if ($CNF::post{'no_dependence'}{'mode'}) { if ($ENV{'HTTP_USER_AGENT'} =~ /Win/) { $os = 0;} elsif ($ENV{'HTTP_USER_AGENT'} =~ /Mac(?:intosh|_PowerPC)/) { $os = 1; } } my $item; foreach $item (keys %item) { #── 長さをチェック if ($::FORM{$item} =~ /^(?: | |\n)*$/s) { $CNF::post{$item}{'indispensable'} && push(@error, "$item{$item}を記入してください。"); } (length($::FORM{$item}) > $CNF::post{$item}{'max'}) && push(@error, ("$item{$item}が長すぎます。$CNF::post{$item}{'max'}" . "文字以内にしてください。")); #── 機種依存文字をチェック (defined $os) && &STRING::no_dependence(\$::FORM{$item}, $os); #── 絵文字等の存在をチェック ($::FLAG{'mobile'}{'mode'} || (index($::FORM{$item}, '#') != -1)) && (my $sharp = 1); #── 内容を修正 if ($item eq 'body') { ($::FORM{$item} =~ /[!-~]{3000}/) #とほほ修正 && push(@error, "半角文字列が長すぎます。"); $::FORM{$item} =~ s/^(?:(?: | )*\n)+//g; $::FORM{$item} =~ s/(?:(?: | )*\n)+$//; $::FORM{$item} =~ s/(?:(?: | )*\n){4,}/$1\n\n\n/g; #── 一連の処理前に携帯からの絵文字を#????#コードに変換 #── メールのオートリンク対策でsjis←→eusの変換が生じたため if ($sharp) { $CNF::post{'emoji'}{'mode'} ? &EMOJI::image2(\$::FORM{$item}) : &EMOJI::string(\$::FORM{$item}); } ($::FLAG{'master'} && $CNF::tag{'mode'} || !$::FLAG{'master'} && $CNF::tag{'mode'} == 2) ? &HTML::check(\$::FORM{$item}, $CNF::tag{'enable'}, $CNF::tag{'java'}{'mode'}, $CNF::tag{'style'}{'mode'}, $CNF::post{'url'}{'target'}, $CNF::post{'url'}{'check'}{'mode'}) : &HTML::auto_link(&HTML::escape(\$::FORM{$item}), $CNF::post{'url'}{'target'}, $CNF::post{'url'}{'check'}{'mode'}); if ($sharp) { &ETC::option_link(\$::FORM{$item}, $::FORM{'no'}); $CNF::post{'emoji'}{'mode'} ? &EMOJI::image(\$::FORM{$item}, $CNF::place{'this'}{'path'} . "?cmd=mji;id=$::FORM{'id'};name=") : &EMOJI::string(\$::FORM{$item}); } } else { $sharp && &EMOJI::string(\$::FORM{$item}); $::FORM{$item} =~ s/\n//g; $::FORM{$item} =~ s/^(?: | )+//; $::FORM{$item} =~ s/(?: | )+$/$1/; &HTML::escape(\$::FORM{$item}); } #── 内容をチェック foreach (@{$CNF::post{'disable'}{'word'}{'list'}}) { length($_) or next; if (index($::FORM{$item}, $_) != -1) { # 速度重視(手抜き) push(@error, "$item{$item}に禁止語句が含まれています。"); last; } } } &STRING::undef_table; &EMOJI::undef_table; my $param; foreach $param (grep(/^opt_/, keys %::FORM)) { if (!grep($param eq $_, @{$CNF::post{'option'}{'param'}{'list'}})) { push(@error, "オプションパラメーター($param)は" . "登録されていません。"); next; } $::FORM{$_} =~ s/\n//g; (length($::FORM{$_}) > 100) && push(@error, 'オプションパラメーターが長すぎます。'); &HTML::escape(\$::FORM{$_}); } #── メールアドレスをチェック length($::FORM{'email'}) && ($::FORM{'email'} !~ /^[!-?A-~]+@[!-?A-~]+\.[!-?A-~]+$/) && push(@error, 'メールアドレスが不正です。'); #── ホームページアドレスをチェック length($::FORM{'web'}) && ($::FORM{'web'} !~ /^s?https?:\/\/[!-~]+\.[!-~]+$/ || ($CNF::post{'url'}{'check'}{'mode'} && !&HTML::check_url($::FORM{'web'}))) && push(@error, 'ホームページアドレスが不正です。'); #── パスワードをチェック ($::FORM{'key'} =~ /[<>&"]/) && &::error(\('パスワードに「<, >, &, "」は' . '使えません。')); #── ジャンルアイコン if (($::FLAG{'mobile'}{'mode'} != 1) && ($::FLAG{'pda'} != 1)) { exists $CNF::view{'genre'}{'list'}{$::FORM{'genre'}} or delete $::FORM{'genre'}; $CNF::view{'genre'}{'mode'} && $CNF::view{'genre'}{'require'}{'mode'} && !length($::FORM{'genre'}) && push(@error, "「$CNF::view{'genre'}{'menu'}」を選択してください。"); } #── 本文色選択(携帯/PDAの場合はチェックしない) if (($::FLAG{'mobile'}{'mode'} != 1) && ($::FLAG{'pda'} != 1)) { $CNF::view{'body_color'}{'mode'} && $CNF::view{'body_color'}{'require'}{'mode'} && !length($::FORM{'body_color'}) && push(@error, "「本文色」を選択してください。"); } #── 投稿キー(とほほ追加) if(($CNF::post{'pstkey'}{'indispensable'} == 1 )&&($CNF::permission{'pst'}{'member'}{'mode'} == 0)&&($CNF::permission{'pst'}{'master'}{'mode'} == 0)&&($CNF::permission{'bse'}{'member'}{'mode'} == 0)&&($CNF::member{'mail'}{'mode'} == 0)&&($::FORM{'cmd'} ne 'mdt')){ open POST_TEMP, "post_temp" or die "とほほ改エラー: テンポラリーファイルをオープンできませんでした。","\n"; while(){ chop; $pstkey_v = $_;} close POST_TEMP; unlink "post_temp"; if (($::FORM{'pstkey'} ne "$pstkey_v")&&($::FORM{'pky'} ne "携帯")) { push(@error, "投稿キーが違います。"); } } #── 不正なパラメータを削除 ($CNF::mail{'inform'}{'mode'} && $::FORM{'email'}) or delete $::FORM{'inform_mail'}; ($CNF::mail{'owner'}{'mode'} && $::FORM{'email'}) or delete $::FORM{'owner_mail'}; $::FORM{'email'} or delete $::FORM{'mail_mode'}; #── 空白欄を補完 my %empty = ( 'name' => $CNF::post{'name'}{'complement'}, 'subject' => $CNF::post{'subject'}{'complement'}, 'body' => $CNF::post{'body'}{'complement'}, ); foreach (keys %item) { length($::FORM{$_}) or ($::FORM{$_} = $empty{$_}); } #── 投稿キー(とほほ追加)ここまで return(\@error); } __SUB__ identify => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 二重投稿防止 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub identify { require './lib/file/psi.pl'; my $digest = &COMMON::sha1(\"$::FORM{'subject'}\t$::FORM{'body'}"); my $o_identify = new FILE::POST_IDENTIFY($CNF::place{'data'}{'path'}); return($o_identify, $o_identify->update({digest => $digest, host => $::FORM{'host'}, time => $::FLAG{'time'}}, $CNF::post{'identify'}{'total'}, $CNF::post{'interval'})); } __SUB__ total => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ ツリー&記事数記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub total { require './lib/file/ttl.pl'; my $o_total = new FILE::TOTAL($CNF::place{'data'}{'path'}); return($o_total, $o_total->add($::FORM{'tree'} == $::FORM{'no'})); } __SUB__ tree => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ ツリー記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub tree { require './lib/file/tre.pl'; my($item, %value); my @param = qw(date follow genre name no subject time); foreach $item (keys %::FORM) { ($item =~ /^opt_\w+$/ || grep(($_ eq $item), @param)) && ($value{$item} = $::FORM{$item}); } $value{'file'} = $::FORM{'file'} ? @{$::FORM{'file'}} : 0; my $o_tree = new FILE::TREE($CNF::place{'data'}{'path'}); #sage add if ($::FORM{'sage'}) { return($o_tree, $o_tree->write(\%value, $::FORM{'tree'},0)); } else { return($o_tree, $o_tree->write(\%value, $::FORM{'tree'}, $CNF::view{'tree'}{'sort'}{'mode'})); } # return($o_tree, $o_tree->write(\%value, $::FORM{'tree'}, # $CNF::view{'tree'}{'sort'}{'mode'})); } __SUB__ message => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 記事記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub message { my @param = qw( agent body date email follow genre host host_ext ident inform_mail owner_mail mail_mode mobile name no sage subject time tree typewriter user_id web body_color ); my($item, %value); foreach $item (keys %::FORM) { ($item =~ /^opt_\w+$/ || grep(($_ eq $item), @param)) && ($value{$item} = $::FORM{$item}); } if ($::FORM{'file'}) { my(@file, $file); foreach $file (@{$::FORM{'file'}}) { my %file; foreach (keys %{$file}) { $file{$_} = ${$file}{$_};} $file{'size'} = &COMMON::size($file{'size'}); push(@file, \%file); } $value{'file'} = \@file; } $value{'key'} = length($::FORM{'key'}) ? &COMMON::make_pass($::FORM{'key'}) : ''; $::FORM{'key_val'} = $value{'key'}; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); return($o_message, $o_message->write(\%value)); } __SUB__ file => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 添付ファイル情報記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub file { require './lib/file/fle.pl'; my $o_file = new FILE::FILE($CNF::place{'data'}{'path'}); return($o_file, $o_file->write({no => $::FORM{'no'}, file => $::FORM{'file'}})); } __SUB__ frequency => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 添付ファイル情報記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub frequency { require './lib/file/frq.pl'; my $o_frequency = new FILE::FREQUENCY($CNF::place{'data'}{'path'}); $o_frequency->add($::FORM{'name'}, length($::FORM{'subject'} . $::FORM{'body'})); } __SUB__ keyword => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ キーワード記録 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub keyword { require './lib/file/kyw.pl'; my $str = "$::FORM{'subject'}\t$::FORM{'body'}"; my $o_keyword = new FILE::KEYWORD($CNF::place{'data'}{'path'}); $o_keyword->write($::FORM{'no'}, &STRING::keyword(\$str)); $o_keyword->complete(); } __SUB__ write => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 投稿処理 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub write { require './lib/htm.pl'; require './cmd/msg.pl'; require './lib/str.pl'; #── 投稿可能かどうかチェック $CNF::post{'stop'}{'mode'} && &::error(\$CNF::post{'stop'}{'caption'}); #── ロック開始 &::lock('msg') or &::error(\'混雑していて書き込めませんでした。'); #── 前準備 my $r_error = ¶meter; $r_error && &error($r_error); #── 各種チェック my($r_error, $o_identify) = ✓ $r_error && &error($r_error, $o_identify); #── プレビューなら表示して終了 if ($::FORM{'preview'}) { &preview; exit;} #── 書き込み my @total = &total; my @tree = &tree; my @message = &message; my @file = $::FORM{'file'} ? &file : (0, 1); $SIG{'INT'} = $SIG{'HUP'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'IGNORE'; if ($total[1] && $tree[1] && $message[1] && $file[1]) { $total[0]->complete(); $tree[0]->complete(); $message[0]->complete(); $file[0] && $file[0]->complete(); } else { $total[0]->incomplete(); $tree[0]->incomplete(); $message[0]->incomplete(); $file[0] && $file[0]->incomplete(); &::error(\'記事の書き込みに失敗しました。'); } $o_identify && $o_identify->complete; $CNF::rank{'frequency'}{'mode'} && &frequency; #── メール送信 if ($CNF::mail{'mode'} != 2) { $CNF::mail{'master'}{'mode'} && &master_mail; $CNF::mail{'owner'}{'mode'} && &owner_mail; $CNF::mail{'inform'}{'mode'} && $::FORM{'follow'} && &inform_mail; } #── 記事数がオーバーしたら古いツリーを過去ログ化 or 削除 if ($total[1] > $CNF::post{'total'}) { require './cmd/dlt.pl'; &DELETE::last_tree(3); } #── 添付ファイルの容量をオーバーしたら少し多めに古い添付ファイル削除 if ($file[0] && ($file[1] > $CNF::upload{'size'}{'total'})) { require './cmd/dlt.pl'; &DELETE::last_file(($file[1] - $CNF::upload{'size'}{'total'}) * 2); } #── キーワード記録 $CNF::post{'keyword'}{'mode'} && &keyword; #── ロック解除 &::unlock('msg'); #── クッキー my @value = qw(email key mail_mode name inform_mail owner_mail web sage); $CNF::view{'genre'}{'cookie'}{'mode'} && push(@value, 'genre'); $CNF::view{'body_color'}{'cookie'}{'mode'} && push(@value, 'body_color'); my %value; map($value{$_} = $::FORM{$_}, (@value, grep(/^opt_/, keys %::FORM))); #── ジャンプ &BASE::location("$CNF::place{'this'}{'url'}?cmd=one;no=$::FORM{'no'};" . "id=$::FORM{'id'}", {name => "$CNF::cookie{'name'}", value => \%value, expire => $CNF::cookie{'expire'}}); } __SUB__ preview => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ プレビュー #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub preview { do "$::FLAG{'template'}/psn.txt"; require './lib/htm.pl'; do "$::FLAG{'template'}/msg.txt"; #── 添付ファイル削除 foreach (@{$::FORM{'file'}}) { unlink("$CNF::place{'file'}{'path'}/${$_}{'name'}"); } #── ロック解除 &::unlock('msg'); #── パラメーターをセット $::FORM{'cmd'} = 'psn'; foreach (qw(email key mail_mode name inform_mail owner_mail web genre sage body_color)) { $::COOKIE{$_} = $::FORM{$_}; } my $body = $::FORM{'body'}; $::FORM{'file'} && map($_{'size'} = &COMMON::size($_{'size'}), @{$::FORM{'file'}}); #── プレビュー表示 &BASE::head('pst'); $::FORM{'cmd'}="one"; &MESSAGE::all(\%::FORM); #── パラメーターを修正 $::FORM{'body'} = $body; $CNF::post{'emoji'}{'mode'} && &EMOJI::cancel(\$::FORM{'body'}); &ETC::option_unlink(&HTML::auto_unlink(\$::FORM{'body'})); map(&HTML::escape(\$::FORM{$_}), keys %::FORM); #── 返信の場合 if ($::FORM{'follow'}) { require './lib/file/msg.pl'; require './cmd/msg.pl'; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); (my $r_MSG = $o_message->one($::FORM{'follow'})) or &::error(\'返信元の記事を読み込めませんでした。'); local *MSG = $r_MSG; #── 参照文 &MESSAGE::quot_color(\$MSG{'body'}); $MSG{'body'} =~ s/^/  /gm; $r_reference = &DESIGN::reference(\$MSG{'body'}); } #── 各種入力欄の設定 my $upload_input; $CNF::upload{'mode'} && map($upload_input .= ${&DESIGN::upload_input}, (0 .. ($CNF::upload{'enable'}{'number'} - 1))); $CNF::mail{'inform'}{'mode'} && (my $r_inform_mail_input = &DESIGN::inform_mail_input); $CNF::mail{'owner'}{'mode'} && (my $r_owner_mail_input = &DESIGN::owner_mail_input); $CNF::view{'genre'}{'mode'} && (my $r_genre_input = &DESIGN::genre_input); $CNF::view{'tree'}{'sort'}{'mode'} && $CNF::post{'sage'}{'mode'} && (my $r_sage_input = &DESIGN::sage_input); $CNF::view{'body_color'}{'mode'} && (my $r_body_color_input = &DESIGN::body_color_input); if($::FORM{'cmd'} ne "mdt"){&tohoho;} #とほほルーティンへ #── 入力欄表示(とほほ修正開始) &DESIGN::post($r_genre_input, \$::FORM{'subject'}, \$::FORM{'body'}, \$upload_input, $r_sage_input, $r_inform_mail_input, $r_owner_mail_input, $r_reference, $r_body_color_input, $r_postkey_input, $upfile_list, $upfile_size, $upfile_com, $upsize_com, $sub_com, $name_com, $email_com, $key_com, $body_com, $web_com, $gen_com); #とほほ修正終了 &BASE::foot('pst'); } __SUB__ attach => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 添付ファイル追加 #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub attach { do "$::FLAG{'template'}/psn.txt"; require './lib/htm.pl'; do "$::FLAG{'template'}/msg.txt"; #── 添付ファイル削除 foreach (@{$::FORM{'file'}}) { unlink("$CNF::place{'file'}{'path'}/${$_}{'name'}"); } #── ロック解除 &::unlock('msg'); #── パラメーターをセット $::FORM{'cmd'} = 'psn'; foreach (qw(email key mail_mode name inform_mail owner_mail web genre sage body_color)) { $::COOKIE{$_} = $::FORM{$_}; } my $body = $::FORM{'body'}; $::FORM{'file'} && map($_{'size'} = &COMMON::size($_{'size'}), @{$::FORM{'file'}}); #── プレビュー表示 #&BASE::head('pst'); &MESSAGE::all(\%::FORM); #── パラメーターを修正 $::FORM{'body'} = $body; $CNF::post{'emoji'}{'mode'} && &EMOJI::cancel(\$::FORM{'body'}); &ETC::option_unlink(&HTML::auto_unlink(\$::FORM{'body'})); map(&HTML::escape(\$::FORM{$_}), keys %::FORM); #── 返信の場合 if ($::FORM{'follow'}) { require './lib/file/msg.pl'; require './cmd/msg.pl'; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); (my $r_MSG = $o_message->one($::FORM{'follow'})) or &::error(\'返信元の記事を読み込めませんでした。'); local *MSG = $r_MSG; #── 参照文 &MESSAGE::quot_color(\$MSG{'body'}); $MSG{'body'} =~ s/^/  /gm; $r_reference = &DESIGN::reference(\$MSG{'body'}); } #── 各種入力欄の設定 my $upload_input; $CNF::upload{'mode'} && map($upload_input .= ${&DESIGN::upload_input}, (0 .. ($CNF::upload{'enable'}{'number'} - 1))); $CNF::mail{'inform'}{'mode'} && (my $r_inform_mail_input = &DESIGN::inform_mail_input); $CNF::mail{'owner'}{'mode'} && (my $r_owner_mail_input = &DESIGN::owner_mail_input); $CNF::view{'genre'}{'mode'} && (my $r_genre_input = &DESIGN::genre_input); $CNF::view{'tree'}{'sort'}{'mode'} && $CNF::post{'sage'}{'mode'} && (my $r_sage_input = &DESIGN::sage_input); $CNF::view{'body_color'}{'mode'} && (my $r_body_color_input = &DESIGN::body_color_input); if($::FORM{'cmd'} ne "mdt"){&tohoho;} #とほほルーティンへ #── 入力欄表示(とほほ修正開始) &DESIGN::post($r_genre_input, \$::FORM{'subject'}, \$::FORM{'body'}, \$upload_input, $r_sage_input, $r_inform_mail_input, $r_owner_mail_input, $r_reference, $r_body_color_input, $r_postkey_input, $upfile_list, $upfile_size, $upfile_com, $upsize_com, $sub_com, $name_com, $email_com, $key_com, $body_com, $web_com, $gen_com); #とほほ修正開始終了 &BASE::foot('pst'); } __SUB__ error => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ エラー #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub error { my $r_error = shift; my $o_identify = shift; do "$::FLAG{'template'}/psn.txt"; require './lib/htm.pl'; #── 書き換え中止 $o_identify && $o_identify->incomplete; #── ロック解除 &::unlock('msg'); #── 携帯の場合 $::FLAG{'mobile'}{'mode'} && &::error(\join("
\n", @{$r_error})); #── パラメーターをセット $::FORM{'cmd'} = 'psn'; if ($::FLAG{'check'}) { $CNF::post{'emoji'}{'mode'} && &EMOJI::cancel(\$::FORM{'body'}); &ETC::option_unlink(&HTML::auto_unlink(\$::FORM{'body'})); } map(&HTML::escape(\$::FORM{$_}), keys %::FORM); foreach (qw(email key mail_mode name inform_mail owner_mail web genre sage body_color)) { $::COOKIE{$_} = $::FORM{$_}; } delete $::FLAG{'check'}; #── 返信の場合 if ($::FORM{'follow'}) { require './lib/file/msg.pl'; require './cmd/msg.pl'; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); (my $r_MSG = $o_message->one($::FORM{'follow'})) or &::error(\join("
\n ", (@{$r_error}, '返信元の記事を読み込めませんでした。'))); local *MSG = $r_MSG; #── 参照文 &MESSAGE::quot_color(\$MSG{'body'}); $MSG{'body'} =~ s/^/  /gm; $r_reference = &DESIGN::reference(\$MSG{'body'}); } #── 各種入力欄の設定 my $upload_input; $CNF::upload{'mode'} && map($upload_input .= ${&DESIGN::upload_input}, (0 .. ($CNF::upload{'enable'}{'number'} - 1))); $CNF::mail{'inform'}{'mode'} && (my $r_inform_mail_input = &DESIGN::inform_mail_input); $CNF::mail{'owner'}{'mode'} && (my $r_owner_mail_input = &DESIGN::owner_mail_input); $CNF::view{'genre'}{'mode'} && (my $r_genre_input = &DESIGN::genre_input); $CNF::view{'tree'}{'sort'}{'mode'} && $CNF::post{'sage'}{'mode'} && (my $r_sage_input = &DESIGN::sage_input); $CNF::view{'body_color'}{'mode'} && (my $r_body_color_input = &DESIGN::body_color_input); if($::FORM{'cmd'} ne "mdt"){&tohoho;} #とほほルーティンへ #── 表示(とほほ修正開始) &BASE::head('pst'); map(&::error(\$_), @{$r_error}); print ${&DESIGN::line}; &DESIGN::post($r_genre_input, \$::FORM{'subject'}, \$::FORM{'body'}, \$upload_input, $r_sage_input, $r_inform_mail_input, $r_owner_mail_input, $r_reference, $r_body_color_input, $r_postkey_input, $upfile_list, $upfile_size, $upfile_com, $upsize_com, $sub_com, $name_com, $email_com, $key_com, $body_com, $web_com, $gen_com); #とほほ修正終了 &BASE::foot('pst'); exit; } __SUB__ tohoho => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ とほほ改パラメーター #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub tohoho { #ワンタイム投稿キー作成処理 if(($CNF::permission{'pst'}{'member'}{'mode'} == 0)&&($CNF::permission{'pst'}{'master'}{'mode'} == 0)&&($CNF::permission{'bse'}{'member'}{'mode'} == 0)&&($CNF::member{'mail'}{'mode'} == 0)){ if($CNF::post{'pstkey'}{'indispensable'} == 1 ){ $post_key1 = int(rand(9)); $post_key2 = int(rand(9)); $post_key3 = int(rand(9)); $post_key4 = int(rand(9)); $post_key = "$post_key1$post_key2$post_key3$post_key4"; open POST_TEMP, ">post_temp" or die "とほほ改エラー: テンポラリーファイルをオープンできませんでした"; print POST_TEMP "$post_key","\n"; close POST_TEMP; $post_keym1 = qq||; $post_keym2 = qq||; $post_keym3 = qq||; $post_keym4 = qq||; $r_postkey_input = qq| 投稿キー(必須)
$post_keym1$post_keym2$post_keym3$post_keym4
左の画像表\示されている番号を入力してください(スパム対策です) |; }} #入力条件表示設定 unless ( $CNF::upload{'mode'} == 0 ) { $upfile_list = "@{$CNF::upload{'enable'}{'ext'}}"; $upfile_size1 = int($CNF::upload{'size'}{'max'} / 1024); $upfile_size = "$upfile_size1 KB"; $upfile_com = "upload可能\ファイル: "; $upsize_com = "最大合計サイズ: "; } if ($CNF::post{'subject'}{'indispensable'} == 1) {$sub_com = "(必須)";} else{$sub_com = "(任意)";} if($CNF::post{'name'}{'indispensable'} == 1) {$name_com = "(必須)";} else{$name_com = "(任意)";} if($CNF::post{'email'}{'indispensable'} == 1) {$email_com = "(必須)";} else{$email_com = "(任意)";} if($CNF::post{'key'}{'indispensable'} == 1) {$key_com = "(必須)";} else{$key_com = "(任意)";} if($CNF::post{'body'}{'indispensable'} == 1) {$body_com = "(必須)";} else{$body_com = "(任意)";} if($CNF::post{'web'}{'indispensable'} == 1) {$web_com = "(必須)";} else{$web_com = "(任意)";} unless($CNF::view{'genre'}{'mode'} == 0){ if($CNF::view{'genre'}{'require'}{'mode'} == 1){ $gen_com = "(必須)";} else{$gen_com = "(任意)";}} } __SUB__ inform_mail => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ レスお知らせメール #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub inform_mail { require './lib/mil.pl'; my $o_message = new FILE::MESSAGE($CNF::place{'data'}{'path'}); my $r_MSG = $o_message->one($::FORM{'follow'}); $o_message->close; local *MSG = $r_MSG; $MSG{'inform_mail'} or return; my %to; $to{'name'} = $MSG{'name'}; $to{'address'} = $MSG{'email'}; my $body = &MAIL::mobile($to{'address'}) ? $CNF::mail{'inform'}{'body'}{'template'}{'mobile'} : $CNF::mail{'inform'}{'body'}{'template'}{'default'}; my %MSG = %::FORM; if ($MSG{'mail_mode'} == 1) { $MSG{'email'} = '[匿メール]';} elsif ($MSG{'mail_mode'} == 2) { $MSG{'email'} = '[非公開]';} $CNF::post{'emoji'}{'mode'} && &EMOJI::convert(\$MSG{'body'}, 1); &ETC::option_unlink(&HTML::auto_unlink(\$MSG{'body'})); map(&HTML::unescape(\$MSG{$_}), keys %MSG); $MSG{'page'} = $CNF::place{'this'}{'url'} . '?cmd=one&no=' . $MSG{'no'} . '&id=' . $::FORM{'id'}; $MSG{'key_org'} = $MSG{'key'}; my @param = qw( date email file follow genre no name page subject tree web body_color ); length($MSG{'genre'}) && ($MSG{'genre'} = "【$CNF::view{'genre'}{'list'}{$MSG{'genre'}}{'name'}" . "】"); map($body =~ s/\$$_/$MSG{$_}/g, (@param, grep(/^opt_/, keys %MSG))); my @param_body = qw( body ); map($body =~ s/\$$_/$MSG{$_}/g, (@param_body, grep(/^opt_/, keys %MSG))); my %r_from; $r_from{'name'} = $CNF::mail{'from'}{'name'}; $r_from{'address'} = $CNF::mail{'from'}{'address'}; &MAIL::send($CNF::mail{'mode'}, $CNF::place{'sendmail'}{'path'}, $CNF::place{'smtp'}{'path'}, [\%to], \%r_from, $CNF::mail{'inform'}{'subject'}, \$body); length($@) && &::error(\"INFORM_MAIL ERROR: $@"); } __SUB__ master_mail => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 管理人宛メール #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub master_mail { require './lib/mil.pl'; my %MSG = %::FORM; $CNF::post{'emoji'}{'mode'} && &EMOJI::convert(\$MSG{'body'}, 1); &ETC::option_unlink(&HTML::auto_unlink(\$MSG{'body'})); map(&HTML::unescape(\$MSG{$_}), keys %MSG); local *list = $r_list; my $subject = "[$CNF::mail{'master'}{'subject'}{'sub'}:$MSG{'no'}]" . $MSG{'subject'}; my @to = map({address => $_}, @{$CNF::mail{'master'}{'address'}}); $MSG{'email'} = $MSG{'email'} ? "<$MSG{'email'}>" : ''; length($MSG{'genre'}) && ($MSG{'genre'} = "【$CNF::view{'genre'}{'list'}{$MSG{'genre'}}{'name'}】"); $MSG{'page'} = $CNF::place{'this'}{'url'} . '?cmd=one&no=' . $MSG{'no'} . '&id=' . $::FORM{'id'}; if ($MSG{'inform_mail'}) { $MSG{'inform_text_mail'} = "投稿者がレスお知らせメールを希望に指定"; } elsif (!($CNF::mail{'inform'}{'mode'})) { $MSG{'inform_text_mail'} = "管理人がレスお知らせメールを未使用に設定"; } elsif (!($::FORM{'email'})) { $MSG{'inform_text_mail'} = "投稿者がメールアドレスを未入力" ; } else { $MSG{'inform_text_mail'} = "投稿者がレスお知らせメールを不要に指定"; } $MSG{'inform_mail'} = ($MSG{'inform_mail'}) ? "1" : "0"; $MSG{'key_org'} = $MSG{'key'}; foreach (@to) { my @to_addr = $_; my $mobilemail = &MAIL::mobile(${$_}{'address'}); my %from; $from{'name'} = $MSG{'name'}; $from{'address'} = $CNF::mail{'from'}{'address'}; my $body = $mobilemail ? $CNF::mail{'master'}{'body'}{'template'}{'mobile'} : $CNF::mail{'master'}{'body'}{'template'}{'default'}; my @option; push(@option, "X-Ident: $MSG{'ident'}"); push(@option, "X-Id: $::COOKIE{'user_id'}",'X-Host: ' . &CGI::get_host); push(@option, 'X-User-Agent: ' . ($ENV{'HTTP_USER_AGENT'} || 'unknown')); my $host = ($CNF::place{'this'}{'url'} =~ /^http:\/\/([^\/]+)/)[0]; push(@option, "Message-Id: <$::FORM{'id'}_$MSG{'no'}\@$host>"); $MSG{'follow'} && push(@option, "References: <$::FORM{'id'}_$MSG{'follow'}\@$host>"); if ($MSG{'file'} && !$mobilemail) { $body .= ' ' . '─' x 36 . "\n"; foreach (@{$MSG{'file'}}) { ${$_}{'size'} = &COMMON::size(${$_}{'size'}); $body .= " 添付ファイル: ${$_}{'name'} (${$_}{'size'})\n"; } } my @param = qw( agent date email file follow genre host host_ext inform_mail inform_text_mail mail_mode mobile name no page subject time tree web user_id key_org key_val ident body_color ); map($body =~ s/\$$_/$MSG{$_}/g, (@param, grep(/^opt_/, keys %MSG))); my @param_body = qw( body ); map($body =~ s/\$$_/$MSG{$_}/g, (@param_body, grep(/^opt_/, keys %MSG))); $MSG{'file'} && $CNF::mail{'master'}{'file'}{'mode'} && (my @file = map(${$_}{'name'}, @{$MSG{'file'}})); &MAIL::send($CNF::mail{'mode'}, $CNF::place{'sendmail'}{'path'}, $CNF::place{'smtp'}{'path'}, \@to_addr, \%from, $subject, \$body, \@option, \@file, $CNF::place{'file'}{'path'}); length($@) && &::error(\"MASTER_MAIL ERROR: $@"); } } __SUB__ owner_mail => <<'__SUB__', #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ 投稿者宛メール #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ sub owner_mail { require './lib/mil.pl'; my %MSG = %::FORM; $MSG{'owner_mail'} or return; my $subject = "[$CNF::mail{'owner'}{'subject'}{'sub'}:$MSG{'no'}]" . $MSG{'subject'}; my %to; $to{'name'} = $MSG{'name'}; $to{'address'} = $MSG{'email'}; my $body = &MAIL::mobile($to{'address'}) ? $CNF::mail{'owner'}{'body'}{'template'}{'mobile'} : $CNF::mail{'owner'}{'body'}{'template'}{'default'}; my @option; push(@option, "X-Ident: $MSG{'ident'}"); push(@option, "X-Id: $::COOKIE{'user_id'}", 'X-Host: ' . &CGI::get_host); push(@option, 'X-User-Agent: ' . ($ENV{'HTTP_USER_AGENT'} || 'unknown')); my $host = ($CNF::place{'this'}{'url'} =~ /^http:\/\/([^\/]+)/)[0]; push(@option, "Message-Id: <$::FORM{'id'}_$MSG{'no'}\@$host>"); $MSG{'follow'} && push(@option, "References: <$::FORM{'id'}_$MSG{'follow'}\@$host>"); if ($MSG{'mail_mode'} == 1) { $MSG{'email'} = '[匿メール]';} elsif ($MSG{'mail_mode'} == 2) { $MSG{'email'} = '[非公開]';} $CNF::post{'emoji'}{'mode'} && &EMOJI::convert(\$MSG{'body'}, 1); &ETC::option_unlink(&HTML::auto_unlink(\$MSG{'body'})); map(&HTML::unescape(\$MSG{$_}), keys %MSG); $MSG{'page'} = $CNF::place{'this'}{'url'} . '?cmd=one&no=' . $MSG{'no'} . '&id=' . $::FORM{'id'}; if ($MSG{'inform_mail'}) { $MSG{'inform_text_mail'} = "投稿者がレスお知らせメールを希望に指定"; } elsif (!($CNF::mail{'inform'}{'mode'})) { $MSG{'inform_text_mail'} = "管理人がレスお知らせメールを未使用に設定"; } elsif (!($::FORM{'email'})) { $MSG{'inform_text_mail'} = "投稿者がメールアドレスを未入力" ; } else { $MSG{'inform_text_mail'} = "投稿者がレスお知らせメールを不要に指定"; } $MSG{'inform_mail'} = ($MSG{'inform_mail'}) ? "1" : "0"; $MSG{'key_org'} = $MSG{'key'}; my @param = qw( agent date email file follow genre host host_ext inform_mail inform_text_mail mail_mode mobile name no page subject time tree web user_id key_org key_val ident body_color ); length($MSG{'genre'}) && ($MSG{'genre'} = "【$CNF::view{'genre'}{'list'}{$MSG{'genre'}}{'name'}" . "】"); map($body =~ s/\$$_/$MSG{$_}/g, (@param, grep(/^opt_/, keys %MSG))); my @param_body = qw( body ); map($body =~ s/\$$_/$MSG{$_}/g, (@param_body, grep(/^opt_/, keys %MSG))); my %r_from; $r_from{'name'} = $CNF::mail{'from'}{'name'}; $r_from{'address'} = $CNF::mail{'from'}{'address'}; &MAIL::send($CNF::mail{'mode'}, $CNF::place{'sendmail'}{'path'}, $CNF::place{'smtp'}{'path'}, [\%to], \%r_from, $subject, \$body, \@option); length($@) && &::error(\"OWNER_MAIL ERROR: $@"); } __SUB__ ); 1; # $Id: pst.pl,v 2.4 2003/08/25 12:00:00 N.HIRAI Exp $;