#!/usr/local/bin/perl #このスクリプトはじゃわ@中澤重人さん の # FlasH BBS Pro 1.41 をベースに、 #水無月ばけら が改造を施したものです。 $max_tree = 10; # リストに表示するツリーの数 $jcode = '../jcode.pl'; $retry = 3; # [ メイン処理 ] &check_code; if ($ENV{'REQUEST_METHOD'} eq "POST") { 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; if ($name eq 'tree_del') { $tree_del[$value] = 1; $del_flag = 1; } elsif ($name eq 'del') { $del[$value] = 1; $del_flag = 1; } elsif ($name eq 'edit_no') { $edit_no = $value; $edit_flag = 1; } elsif ($name eq 'edit_tn') { $edit_tn = $value; $edit_flag = 1; } else { $FORM{$name} = &change_code($value); } } $ID = $FORM{'id'}; if ($ID eq 'html'){ $password = ""; }else{ $ID = 'flashbbs'; $password = ""; } if ($password ne $FORM{'pass'}) { &password_check; } $log_dir = '../bbs_log/'; $logfile = "$log_dir$ID.log"; if ($FORM{'mode'} eq 'download') { &download; } if ($FORM{'mode'} eq 'repair') { &repair; } if ($FORM{'mode'} eq 'regist') { ®ist; } if ($del_flag) { &delete; } if ($edit_flag) { &edit; } else { &ichiran; } exit; # [ パスワードのチェック ] sub password_check { &html_header("アクセス制限"); print<<"_EOF_";

id:

pass:

_EOF_ &html_footer; exit; } # [ 一覧表示 ] # sub ichiran { &read_all; &html_header("一覧表\示"); $size = (stat($logfile))[7]; $tree = $FORM{'tree'}; if ($tree > @logs) { $tree = 0; } if (!$tree) { $tree = 0; } $tree = int($tree/$max_tree)*$max_tree; print<<"_EOF_";

ログファイルの容量は、約 $size バイト になっています。現在、編集しています。



_EOF_ $end_tree = $tree + $max_tree; if ($end_tree > @logs) { $end_tree = @logs; } for ($i=$tree;$i<$end_tree;$i++) { @datas = ÷_log($logs[$i]); $kiji = @datas; $tn = (÷_data($logs[$i]))[0]; print "

ツリー No.$i

"; print "

(記事数 $kiji) [ツリー削除]
"; foreach (@datas) { local($no,$res,$lx,$tn,$title,$name,$email,$date,$act) = ÷_data($_); print "削"; for ($s=0; $s<$lx; $s++) { print " "; } print "[$no]$title : $name ($date)
"; } print '


'; } print<<"_EOF_";
_EOF_ &html_footer; } # [ 削除処理 ] # sub delete { &read_all; foreach $data (@logs) { if (!$tree_del[(÷_data($data))[0]]) { @kiji_datas = ÷_log($data); $tree_data = '';$flag = 0; foreach $data (@kiji_datas) { if ($del[(÷_data($data))[0]]) { local($no,$res,$lx,$tn,$temp,$temp,$temp,$date,$act,$file_pwd,$rhost,$ipad,$temp) = ÷_data($data); $data = "$no<>$res<>$lx<>$tn<>[管理者削除]<>管理者<><>null<>9<>Null<><><>この記事は削除されました。"; } if ($flag) { $tree_data .= "<#>"; } else { $flag = 1; } $tree_data .= $data; } push (@new,"$tree_data\n"); } } &write_file($count,$last_nj,@new); } # [ 編集処理 ] # sub edit { &read_all; &html_header("編集"); $kiji_data = &search_no2data($edit_no,÷_log(&search_no2data($edit_tn,@logs))); local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$tm_pwd,$rhost,$ipad,$comment) = ÷_data($kiji_data); $kiji_size = length($kiji_data); $comment_size = length($comment); $comment =~ s/
/\n/g; print<<"_EOF_";

編集項目を全て編集した後、[内容更新]を押して下さい。

タイトル:
ハンドル:
Eメール:

記事情報: 記事番号=$no, 親記事番号=$res, 記事モード=$act

投稿者情報: 登録日時=$date, リモートホスト=$rhost, IPアドレス=$ipad

記事サイズ=約 $kiji_size bytes, コメントサイズ=約 $comment_size bytes

_EOF_ &html_footer; } # [ 登録処理 ] # sub regist { &read_all; local($title,$name,$email,$comment) = ($FORM{'title'},$FORM{'name'},$FORM{'email'},$FORM{'comment'}); $title =~ s/\r\n//g; $title =~ s/\r|\n//g; $name =~ s/\r\n//g; $name =~ s/\r|\n//g; $email =~ s/\r\n//g; $email =~ s/\r|\n//g; $comment =~ s/\r\n/
/g; $comment =~ s/\r|\n/
/g; if (length($title) > 80) { &error(1,"タイトルの記入漏れ、又は文字数制限を過えています。"); } elsif (!$title) { $title = "無題"; } if ((!$name) || (length($name) > 42)) { &error(1,"名前の記入漏れ、又は文字数制限を過えています。"); } if ((($email !~ /(.*)\@(.*)\.(.*)/) && ($email)) || (length($email) > 120)) { &error(1,"メールアドレスの間違い、又は文字数制限を過えています。"); } if (!$comment) { &error(1,"メッセージの記入漏れです。"); } foreach $data (@logs) { if ($FORM{'tn'} == (÷_data($data))[0]) { @kiji_datas = ÷_log($data); $tree_data = '';$flag = 0; foreach $data (@kiji_datas) { if ($FORM{'no'} == (÷_data($data))[0]) { local($no,$res,$lx,$tn,$temp,$temp,$temp,$date,$act,$file_pwd,$rhost,$ipad,$temp) = ÷_data($data); $data = "$no<>$res<>$lx<>$tn<>$title<>$name<>$email<>$date<>0<>$file_pwd<>$rhost<>$ipad<>$comment"; } if ($flag) { $tree_data .= "<#>"; } else { $flag = 1; } $tree_data .= $data; } push (@new,"$tree_data\n"); } else { push (@new,$data); } } &write_file($count,$last_nj,@new); } # [ ダウンロード ] # sub download { print "Content-type: application/octet-stream\n\n"; open(LOG,$logfile) or &error('読み込みエラー','ログの読み込みが出来ません。管理者に連絡してください。'); print ; close(LOG); exit; } # [ 最適化処理 ] # sub repair { foreach $tree (@logs) { @datas = ÷_log($tree); foreach (@datas) { local($no) = ÷_data($_); $line = substr("0000",length($line)).$line; push(@num,"$no=$line"); $line++; } } @num = sort(@num); for($i=0;$i<@num;$i++) { ($no,$line) = (split(/=/,$num[$i])); $num = $i + 1; $num3[$no] = $num; $num = substr("0000",length($num)).$num; push(@num2,"$line=$num"); } @num2 = sort(@num2); $line = 0; foreach $tree (@logs) { @datas = ÷_log($tree); $flag = 0; $tree_data = ''; foreach (@datas) { local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$file_pwd,$rhost,$ipad,$comment) = ÷_data($_); ($temp,$no) = (split(/=/,$num2[$line++])); if ($res ne 'root') { $res = $num3[$res]; } $tn = $num3[$tn]; $kiji_data = "$no<>$res<>$lx<>$tn<>$title<>$name<>$email<>$date<>0<>$file_pwd<>$rhost<>$ipad<>$comment"; if ($flag){ $tree_data = "$tree_data<#>$kiji_data"; } else { $tree_data = $kiji_data; $flag = 1; } } push(@new,"$tree_data\n"); } &write_file($line,$last_nj,@new); &read_all; } # [ ヘッダー部分表示 ] # sub html_header { local($sub_title) = $_[0]; print "Content-type: text/html; charset=$charset_code\n\n"; print<<"_EOF_"; FlasH BBS Pro Editor [$sub_title]

FlasH BBS Pro Editor

$sub_title

_EOF_ } # [ 著作権等の表示(必ずこのまま表示すること) ] # sub html_footer { print<<"_EOF_";

FlasH BBS Pro Editor v1.40 [Shigeto Nakazawa]

_EOF_ } # [ データ処理関連汎用サブ ] # sub divide_log { local($data) = $_[0]; chop($data); return split(/<#>/,$data); } sub divide_data { return split(/<>/,$_[0]); } sub search_no2data { local($no,@datas) = @_; local($data); foreach $data (@datas) { if ($no == (÷_data($data))[0]) { return $data; } } return 0; } # [ 文字コード関連 ] # sub check_code { if (!(-r $jcode)) { &error(1,"jcode.pl がありません"); } require $jcode; local($text) = ord(substr("中澤",0,1)); if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "EUC-JP"; } elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "Shift_JIS"; } else { &error(1,"サポートしてない文字コードです"); } } sub change_code { local($text)=$_[0]; &jcode'convert(*text,$mojicode); if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); } if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); } $text =~ s//>/g; return $text; } # [ 自動リンク処理(独自方式 v1.9 LE)] # sub auto_link { local($text) = $_[0]; &jcode'convert(*text,'euc'); $text =~ s/(http:\/\/[\w\.\~\-\/\?\&\+\=\:\@\%]+)/$1<\/A>/ig; $text =~ s/(ftp:\/\/[\w\.\~\-\/]+)/$1<\/A>/ig; $text =~ s/([\w\.\-]+)\@([\w\.\-]+)/$1\@$2<\/A>/ig; &jcode'convert(*text,$mojicode); return $text; } # [ 記録ファイルの処理 ] # sub write_file { my($count,$this_nj,@lines) = @_; #プロセスID からテンポラリファイル名を生成 $pros = $$; $pros = time unless $pros; $tmp_file = "$ID$pros.tmp"; #他のテンポラリファイルを検索 opendir(DIR,$log_dir) or &error('システムエラー','作業ディレクトリのオープンに失敗しました。管理者が何かを忘れている可能性があります。'); @list = readdir(DIR); closedir(DIR); unless (@list) { &error('システムエラー','作業ディレクトリが完全に空です。'); } @lists = grep(/$ID.*\.tmp/,@list); #テンポラリファイルがある場合 my($retry_counter) = $retry; while (@lists) { if (--$retry_counter <= 0) { #しびれを切らした foreach (@lists) { #テンポラリファイルを抹殺 unlink("$log_dir$_") if (-e "$log_dir$_"); } &error('ビジー','ただ今混雑しています。時間をおいて再度実行してください。'); } sleep(1); opendir(DIR,"$log_dir"); @list = readdir(DIR); closedir(DIR); @lists = grep(/$ID.*\.tmp/,@list); } #テンポラリファイルに書き込む open(WRITE,">$log_dir$tmp_file") or &error('書き込みエラー','記録ファイルの書き込みが出来ません。管理者に連絡してください。'); print WRITE "$count\n"; print WRITE "$this_nj\n"; print WRITE @lines; close(WRITE); #もう一度他のテンポラリファイルを検索 opendir(DIR,$log_dir); @list = readdir(DIR); closedir(DIR); @lists = grep(/$ID.*\.tmp/,@list); @lists = grep(!/$tmp_file/,@lists);#自分自身は除外 if (@lists) { #他で書き込み中であれば書き込みを中止して終了 unlink("$log_dir$tmp_file") if (-e "$log_dir$tmp_file"); &error('書き込みの競合','同時に複数の書き込みが行われようとしたため、処理を中止しました。すこし時間をおいてから、再度ご利用下さい。'); } rename("$log_dir$tmp_file",$logfile) or &error('書き込みの競合','書き込みに失敗しました。再度実行してください。'); chmod 0666, $logfile; } # [ エラー処理 ] # sub error { ($err,$err_msg) = @_; if ($err) { print "Content-type: text/html; charset=$charset_code\n\n"; print ''; } print<<"_EOF_";

エラー:$err_msg

_EOF_ exit; } sub read_all{ open(LOG,$logfile) or &error('読み込みエラー','ログの読み込みが出来ません。管理者に連絡してください。'); $count = ; chop($count); $last_nj = ; chop($last_nj); @logs = ; close(LOG); }