#!/usr/local/bin/perl ## ErialBBS 4.38.5 - 99/10/13 by ENT (ErialArts) http://www.coma.ais.ne.jp/~e-utopia/erial/ ## ---------------------------------------------------------------------------- ## Based - Petit Board v4.02 by おいどん (99/01/03) ## E-MAIL: webmaster@kent-web.com WWW: http://www.kent-web.com/ ## ---------------------------------------------------------------------------- $| = 1; ### --- 個別設定 require './jcode.pl'; require './erialbbs_cfg.pl'; ## ---------------------------------------------------------------------------- ### --- メイン処理 --- ### foreach(@deniedaddrs){ if($ENV{'REMOTE_ADDR'} =~ /^$_/ && length($_) > 4 ){ die "Status: 204\n\n";} } $host = $ENV{'REMOTE_HOST'}; $host = $ENV{'REMOTE_ADDR'} unless($host); &form_decode; &get_cookie; ®ist if ($mode eq "msg"); ### --- 記事表示部 --- ### # フォーム長を調整 &get_bros; if($mode ne "regist"){ # ログを読み込み open(IN,"$logfile") || &error("ログファイル「$logfile」が開けません"); @lines = ; close(IN); } # 最終更新を抽出 if ($lines[0] =~ /<>/) { &error("ログが正しくありません。

\(Petit v2.5以前のログの場合は変換の必要があります\)"); } $lastkakiko = $lines[0]; $lastkakiko =~ s/(^[0-9]*,|\n)//g ; shift(@lines); # 親記事のみの配列データを作成 @new = (); foreach $line (@lines) { push(@new,$line) if($line =~ /^[0-9]*<><>/ ); } # レス記事はレス順につけるため配列を逆順にする @lines = reverse(@lines); # ヘッダを出力 &header; print "\n\n"; print "\n"; print "\t\n"; print "\t\n
$title2lastpost : $lastkakiko "; &counter if($countfile); print ", [$host]" if($ipview); print "
[戻る]"; print "[掲示板の使い方]"; print "[全文検索]"; print "[記事削除]"; print "[ログ解析]" if ($scriptplus); print "[管理用]"; print "
\n


\n\n\n"; if ($FORM{'pick'} eq "") { print <<"EOM"; $headcom
\n"; print "\t\n"; print "\t
おなまえ メール     Refresh
題  名   削除キー (英数字8以内)
記  事 EOM print '

'; if($tagkey == 0) { print 'タグ不可です'; } else { print 'タグ可です

'; } print <<"EOM";

URL
文字色 EOM print ' '."\n" if($dhtml); &irolist; print "\t
\n"; if($#CHARA > 1){ print "\tアイコン一覧  "."\n"; } if($#FSNAME > 1){ print "\tフォント"; unless($#GFILE > 1){ print "\t";} print ' 一覧\n"; } print "\t
 "; &navibar; print '
'."\n"; } print "
\n\n\n"; &navibar if($FORM{'pick'} ne ""); # 記事数を取得 $end_data = @new - 1; $page_end = $page + ($pagelog - 1); if($FORM{'pick'} ne ""){ $page = 0; $page_end = $end_data ; }elsif($page != 0){ &pager; } print "
\n"; if ($page_end > $end_data) { $page_end = $end_data; } for ($page .. $page_end) { if( $FORM{'pick'} ){ next unless( $new[$_] =~ /^$FORM{'pick'}<>/); } ($number,$k,$date,$name,$email,$subj,$comment,$url,$host,$pwd,$color,$font,$icon) = split(/<>/,$new[$_]); if($email) { $name = "$name"; } else { $name = "$name"; } $subj = "(無題)" unless($subj); if($url) { if($homeicon){ $url = "$homeicon"; } else {$url = "$url";} } # 自動リンク if ($autolink) { $comment = &auto_link($comment); } print "\n"; print "\t\n"; if ($dhtml){ print "\t\n"; } print "
\n"; print "\t[$number]$subj\n"; print "\t \From: $name\n"; print "\t \on $date   $url
"; print "\"$icon\"" if ($icon); print "\n\t
\n\t\t$comment\n\t
"; ## レスメッセージを表示 $flag = 0; foreach $line (@lines) { local($rnum,$rk,$rd,$rname,$rem,$rsub,$rcom,$rurl,$rho,$rp,$rc,$rfont) = split(/<>/,$line); if ($number eq "$rk") { if ($flag == 0) { print "\n\t

\n"; $flag=1; } if ($autolink) { $rcom = &auto_link($rcom); } # if ($rem){ $rname = "$rname"} #レスのemail print ' \n"; print "\t\t
\n"; print "\t$rname >$rcom\n"; print "\t\t($rd)
\n"; } } print "\t
レス欄生成▼
\n\n"; &reswindow; print "
\n\n\n"; } &pager; print <<"EOM";
$footcom
\- ErialBBS 4.38.5 \- , based on petit 4.02
EOM exit; ## 返信欄 sub reswindow{ # DHTMLモードのレス if ($dhtml || $FORM{'pick'} ne ""){ print "
\n"; print <<"EOM";
名前 EOM if($#FSNAME > 1){ print "\tフォント   \n"; } print <<"EOM"; \KEY
コメント

EOM &irolist; print "\t
\n
\n"; } else { # DHTMLぢゃないよ print <<"EOM";
お名前
\KEY
EOM } } ## AltaVista風改頁処理ルーチン by ENT sub pager{ if ( ($page - $pagelog) >= 0 || $page_end ne $end_data) { print "\n"; print "\t\n
Log Pager : "."\n\t"; $nowtab = int( $page / $pagelog ) + 1 ; #初めの記事を0として何枚目かを測定 for( $i = 1 ; $i <= 20; $i++){ if( $nowtab > 20 ){ $tab = $nowtab + $i - 10 ;} else{ $tab = $i; } if( $tab < 1 ){ &error("Pagerの致命的エラー"); } elsif($tab == $nowtab){ print "$nowtab\n\t"; }else{ $gopage = $pagelog * ( $tab - 1 ); # 何枚目の記事かを生成 if( $gopage > $end_data){ last; } # 最大記事数より多いNoで終了 else{ print "$tab\n\t"; } } } print "File\n\t" if ($nofile); print " - \t[ $pagelog件/page "; # ページ記事数切り替え $pagewid = $pagelog + 10; print "+10 "; $pagewid = $pagelog - 10; if($pagewid > 0){ print "-10"; } print ", max: $max件 ]
\n\n"; } } sub navibar{ print "\n\t\n"; print "\t\n"; print "\t\n
View Mode : Normal mode / "; if($readydhtml){ print "DynamicHTML mode"; } else { print 'DynamicHTML mode'; } print "/ Thread view"; print ' / レスの付いた記事は上に移動されます' if ($res_sort); print "
\n"; } ## -- color2を訊く sub colorsel{ &header; &get_cookie; print <<"EOM"; [▲やっぱやめた]
$title2
カラーコード設定フォーム
$FORM{'name'} > $FORM{'comment'}

このレスの色を何色にするか教えて下さい。次回からはcookieされ入力が省けます。
※16進コードでもカラー名でも(hotpink,whitesmokeなど)入力可能\です

 色一覧をみる
EOM print "\t\t\n;" if($dhtml); print "\t
\n\n
\n\n"; exit; } ## radio list color sub irolist{ print "\t\n"; for (1 .. $#COLORS - 1){ if( $COLORS[$_] eq ""){ print "
"; }else{ print "\t\n"; } } print ' "; } else { print '>'; } print '色一覧\n"; } ### --- ログ書き込み処理 --- ### sub regist { # 他サイトからのアクセスを排除 if ($base_url ne ".") { $ref_url = $ENV{'HTTP_REFERER'}; $ref_url =~ s/\?(.|\n)*//ig; $ref_url =~ s/\%7E/\~/ig; if ($ref_url !~ $base_url) { &error("不正なアクセスです。"); } } # 名前とコメントは必須 &error("名前が入力されていません。") unless($FORM{'name'}); &error("コメントが入力されていません。") unless($FORM{'comment'}); if ($FORM{'email'} && $FORM{'email'} !~ /(.*)\@(.*)\.(.*)/) { &error("Eメールの入力内容が正しくありません。"); } $FORM{'subj'} = "(無題)" unless($FORM{'subj'}); # colorは絶対必要 if ($color eq "" && $FORM{'color2'} ne "#" && $FORM{'color2'} ne "") { $color = $FORM{'color2'}; # col2の値 }elsif($color eq ""){ &colorsel; } # ホスト名を取得 $addr = $ENV{'REMOTE_ADDR'}; if ($host eq "" || $host eq "$addr") { ($p1,$p2,$p3,$p4) = split(/\./,$addr); $temp = pack("C4",$p1,$p2,$p3,$p4); $host = gethostbyaddr("$temp", 2); if ($host eq "") { $host = $addr; } } # ファイルロック if ($lockkey == 1) { &lock1; } elsif ($lockkey == 2) { &lock2; } # ログを開く open(IN,"$logfile") || &error("Can't open $logfile"); # 親記事番号を抽出 $oya = ; if ($oya =~ /<>/) { &error("ログが正しくありません。

\(Petit v2.5以前のログの場合は変換の必要があります\)<\/small>"); } $oya =~ s/(,.*|\n)//g ; # 親記事の場合、記事Noをカウントアップし、クッキーを発行 $oya++ if ($FORM{'resno'} eq ""); &set_cookie; # 削除キーを暗号化 if ($pwd) { $now = time; ($p1, $p2) = unpack("C2", $now); $temp = $now / (60*60*24*7) + $p1 + $p2 - 8; @saltset = ('a'..'z','A'..'Z','0'..'9','.','/'); $nsalt = $saltset[$temp % 64] . $saltset[$now % 64]; $ango = crypt($pwd, $nsalt); } # ログをフォーマット local($new_msg) = $oya; $new_msg = $FORM{'resno'} if( $FORM{'resno'} ); $new_msg .= "<>$FORM{'resno'}<>$date<>$name<>$email<>$subj<>$comment<>$url<>$host<>$ango<>$color<>$FORM{'font'}<>$FORM{'icon'}<>\n"; @lines = (); local(@res_data) = (); local(@past_res) = (); local(@past_data) = (); ## 自動ソート時は、レス記事投稿時は親記事はトップへ移動 if ($res_sort && $FORM{'resno'} ne "") { while ($line = ) { $flag = 0; local($num,$k,$d,$na,$em,$sub,$com,$u) = split(/<>/,$line); &error("二重投稿は禁止です") if ($name eq "$na" && $comment eq "$com"); # 親記事を抜き出す if ($k eq "" && $FORM{'resno'} eq "$num") { $new_line = "$line"; $flag = 1; } # 関連のレス記事を抜き出す elsif ($k eq "$FORM{'resno'}") { push(@res_data,$line); $flag = 1; } if ($flag == 0) { push(@lines,$line); } } unshift(@lines,@res_data); # 関連レス記事をトップへ unshift(@lines,$new_msg); # 新規メッセージをトップへ unshift(@lines,$new_line); # 親記事をトップへ ## 親記事の場合、最大記事数を超える記事をカット } elsif ($FORM{'resno'} eq "") { $i = 0; $stop = 0; while ($line = ) { local($num,$k,$d,$na,$em,$sub,$com,$u) = split(/<>/,$line); &error("二重投稿は禁止です") if ($name eq "$na" && $comment eq "$com"); if ($k eq "") { $i++; } if ($i > $max-1) { $stop = 1; unless ($nofile) { last; } else { if ($k eq "") { $kflag=1; push(@past_data,$line); } else { push(@past_res,$line); } } } if ($stop == 0) { push(@lines,$line); } } unshift(@lines,$new_msg); ## レス記事は記事数の調整はしない } else { while ($line = ) { $flag = 0; local($num,$k,$d,$na,$em,$sub,$com,$u) = split(/<>/,$line); &error("二重投稿は禁止です") if ($name eq "$na" && $comment eq "$com"); # 親記事を抜き出す if ($k eq "" && $FORM{'resno'} eq "$num") { $new_line = "$line"; $flag = 2; } if ($flag == 0) { push(@lines,$line); } elsif ($flag == 2) { push(@lines,$new_line); push(@lines,$new_msg); } } } close(IN); # 親記事NO&最終書き込みを付加 unshift (@lines,"$oya,$date $name\n"); # ログを更新 open(OUT,">$logfile") || &error("Can't write $logfile"); print OUT @lines; close(OUT); ## 過去記事生成 if ($kflag) { @past_res = reverse(@past_res); push(@past_data,@past_res); &pastlog; } # ロック解除 unlink($lockfile) if(-e $lockfile); # メール処理 &mailto if ($mailto ne "" && $FORM{'email'} ne "$mailto"); $comment = ""; # cookieは2つ取れないという、IEバグ対策 if ($FORM{'resno'} eq "") { #レス時の継承 $c_url = $url; $c_email = $FORM{'email'}; } $c_name = $FORM{'name'}; $c_pwd = $FORM{'pwd'}; if ($FORM{'color'}) { $c_color = $FORM{'color'}; } else { $c_color = $FORM{'color2'}; } } ### --- クッキーの発行 --- ### sub set_cookie { # レス時は以前の値を継承 if ($FORM{'resno'} ne "") { $email = $COOKIE{'email'}; $url = $COOKIE{'url'}; } ($secg,$ming,$hourg,$mdayg,$mong,$yearg) = gmtime(time + 60*24*60*60); $yearg += 1900; if ($secg < 10) { $secg = "0$secg"; } if ($ming < 10) { $ming = "0$ming"; } if ($hourg < 10) { $hourg = "0$hourg"; } if ($mdayg < 10) { $mdayg = "0$mdayg"; } $month = ('Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec')[$mong]; $youbi = ('Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday')[$wdayg]; $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT"; $cook = "name\:$name\,email\:$email\,url\:$url\,pwd\:$pwd\,color\:$color"; print "Set-Cookie: ERIALBBS=$cook; expires=$date_gmt\n"; } ### --- クッキーを取得 --- ### sub get_cookie{ local(@pairs) = split(/;/,$ENV{'HTTP_COOKIE'}); local(@pairs2) = (); foreach $pair (@pairs) { local($name, $value) = split(/=/, $pair); $name =~ s/ //g; if($name eq 'ERIALBBS'){ @pairs2 = split(/,/,$value); last; } } foreach $pair (@pairs2) { local($name, $value) = split(/:/, $pair); $COOKIE{$name} = $value; } $c_name = $COOKIE{'name'}; $c_email = $COOKIE{'email'}; $c_url = $COOKIE{'url'}; $c_pwd = $COOKIE{'pwd'}; $c_color = $COOKIE{'color'}; } ### --- フォームからのデータ処理 --- ### sub form_decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { &error("投稿量が大きすぎます。") if($ENV{'CONTENT_LENGTH'} > 51200); read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } local(@pairs) = split(/&/,$buffer); foreach $pair (@pairs) { local($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'sjis'); if ($tagkey == 1) { $value =~ s///g; $value =~ s/<>/<\;>\;/g; }else{ $value =~ s//>\;/g; } $FORM{$name} = $value; } $name = $FORM{'name'}; $comment = $FORM{'comment'}; $comment =~ s/\r\n/
/g; $comment =~ s/\r|\n/
/g; $email = $FORM{'email'}; $url = $FORM{'url'}; $url =~ s/^http\:\/\///; $mode = $FORM{'mode'}; $pwd = $FORM{'pwd'}; $color = $FORM{'color'}; $pagelog = $FORM{'pagelog'} if ( $FORM{'pagelog'} ne ""); $subj = $FORM{'subj'}; if ($FORM{'page'} eq '') { $page = 0; } else { $page = $FORM{'page'}; } &error("アイコンリストが不正です") if( $FORM{'icon'} =~ /(http:\/\/|\/|\.\.)/ ); # 日時の取得 $ENV{'TZ'} = "JST-9"; local(@timez) = localtime(time); for(0 .. 5){ $timez[$_] = '0'.$timez[$_] if( $timez[$_] < 10 ); } $timez[4]++; $date = "$timez[5]/$timez[4]/$timez[3] $timez[2]\:$timez[1]\:$timez[0]"; } ### --- ブラウザを判断しフォーム幅を調整 --- ### sub get_bros { if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE 3/i) { $nam_wid = 30; $subj_wid = 40; $com_wid = 65; $url_wid = 48; $nam_wid2 = 12; $rescom_wid = 40; } elsif ($ENV{'HTTP_USER_AGENT'} =~ /MSIE [4-9]/i) { $nam_wid = 30; $subj_wid = 40; $com_wid = 65; $url_wid = 78; $nam_wid2 = 12; $rescom_wid = 70; $readydhtml = 1; $dhtml = 'dhtml=1&' if ( $FORM{'dhtml'} == 1 ); } else { $nam_wid = 20; $subj_wid = 25; $com_wid = 56; $url_wid = 50; $nam_wid2 = 10; $rescom_wid = 40; } } ### --- カウンタ処理 --- ### sub counter { local($cnt); open(NO,"$countfile") || &error("Can't open $countfile"); $cnt = ; close(NO); # 掲示板の更新系処理以外であれば、カウントアップ if ($mode eq "") { $cnt++; # ログを更新 open(NO,">$countfile") || &error("Can't write $countfile"); eval 'flock(NO,2);'; print NO $cnt; eval 'flock(NO,8);'; close(NO); } # 桁数を調整 $cnt = "0$cnt" while(length($cnt) < $mini_fig); ## カウンタ表示 print ", Visitor $cnt"; } ## --- ロックファイル(symlink関数)--- ## sub lock1 { local($retry) = 5; while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } } ## --- ロックファイル(open関数) sub lock2 { local($flag) = 0; for (1 .. 5) { if(-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile"); close(LOCK); $flag = 1; last; } } if ($flag == 0) { &error("LOCK is BUSY"); } } ### --- メール送信 --- ### sub mailto { local($mail_subj) = "$title に投稿がありました。"; &jcode'convert(*mail_subj,'jis'); &jcode'convert(*name,'jis'); &jcode'convert(*comment,'jis'); &jcode'convert(*subj,'jis') unless($FORM{'resno'}); $comment =~ s/
/\n/g; $comment =~ s/\<\;//g; # メールアドレスがない場合はダミーメールに置き換え $email = 'nomail@xxx.xxx' if ($FORM{'email'} eq ""); open(MAIL,"| $sendmail $mailto") || &error("Can't post sendmail"); print MAIL "X-Mailer: ErialBBS MAILER\n"; print MAIL "To: $mailto\n"; print MAIL "From: $email\n"; print MAIL "Subject: $mail_subj\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "Content-type: text/plain\n\n"; print MAIL "$mail_subj\n"; print MAIL "--------------------------------------------------------\n"; print MAIL "TIME : $date\n"; print MAIL "NAME : $name"; print MAIL '  mailto:' . $FORM{'email'} if( $FORM{'email'} ); print MAIL "\n"; print MAIL "URL : http://$url\n" if ($url); if ($FORM{'resno'} ne "") { $subj = "(Res Message: $FORM{'resno'} )";} elsif ($FORM{'resno'} eq "" && $subj eq "") { $subj = "no title"; } print MAIL "TITLE: $subj\n\n"; print MAIL "$comment\n"; print MAIL "--------------------------------------------------------\n"; close(MAIL); } ### --- 自動リンク sub auto_link { local($temp) = "$_[0]"; &jcode'convert(*temp,'euc'); $temp =~ s/([^=^\"]|^)((http|ftp)\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#]+)/$1$2<\/a>/g; if( $temp !~ /\:[\w\.\-]+\@/ ){ $temp =~ s/([\w\.\-]+)\@([\w\.\-]+)/$1\@$2<\/a>/g; } &jcode'convert(*temp,'sjis'); return $temp; } ### --- HTMLのヘッダー --- ### sub header { print "Content-type: text/html\n\n"; print ''."\n\n\n"; print <<"EOM"; EOM print "\t\n" if($stylesheet); print "\t$title"; print ' (DHTML Mode)' if($dhtml); print "\n\n\n$body\n"; } ### --- エラー処理 --- ### sub error { unlink($lockfile) if(-e $lockfile); &header; print <<"EOM";


システムエラー発生!

$_[0]


Refresh
EOM exit; } ### --- 過去ログ生成 --- ### sub pastlog { $new_flag = 0; open(NO,"$nofile") || &error("「$nofile」読込失敗"); $nocount = ; close(NO); $pastfile = "$past_dir/$nocount\.html"; &new_log unless(-e $pastfile); if ($new_flag == 0) { open(PAST,"$pastfile") || &error("致命的エラー: 「$pastfile」読込失敗"); @past = ; close(PAST); # 規定の行数をオーバーすると、次ファイルを自動生成 $log_line = $log_line + 8; &next_log if ($#past > $log_line ); } open(POUT,">$pastfile") || &error("過去ログファイル「$pastfile」書込失敗"); foreach $line (@past) { print POUT $line; if ($line =~ //i) { # 保存記事を出力 foreach $pst_line (@past_data) { ($pnum,$pk,$pdt,$pname,$pemail,$psub,$pcom,$purl,$phost,$ppw,$pcol,$pfont) = split(/<>/, $pst_line); unless($psub) { $psub = "(無題)"; } if ($pemail) { $pname = "$pname"; } else { $pname = "$pname"; } if ($purl) { if($homeicon){ $purl = "[Go url]"; } else {$purl = "$purl";} } if ($pfont) { $pfont = " id=\"$pfont\"" ;} if ($autolink) { $pcom = &auto_link($pcom); } unless($pk){ print POUT "
[$pnum] $psub  \From: $pname \on $pdt $purl
$pcom
\n"; }else{ print POUT "
[Re:$pnum]    \From: $pname \on $pdt
$pcom
\n"; } } } } close(POUT); @past = (); } ## 過去ログ次ファイル生成ルーチン sub next_log { # 次ファイルのためのカウントアップ $nocount++; # カウントファイル更新 open(NO,">$nofile") || &error("「$nofile」書込失敗 - Permissionを確認して下さい"); print NO "$nocount"; close(NO); $pastfile = "$past_dir/$nocount\.html"; &new_log; } ## 新規過去ログファイル生成ルーチン sub new_log { $new_flag = 1; @past = (); $past[0] = "\n"; $past[1] = "\t"; $past[1] .= "" if($stylesheet); $past[2] = "\n\t$title - 過去ログ ($date以降)\n"; $past[3] = "
Make your own free website on Tripod.com
\n"; $past[4] = "($date 以降)\n"; $past[5] = "
\n"; $past[6] = "


\n"; # 新規過去ログファイルを生成更新 open(OUT,">$pastfile") || &error("新規過去ログ $pastfile 作成失敗 - DIRのPermissionを確認して下さい"); print OUT @past; close(OUT); chmod(0777,"$pastfile"); }