bbs.cgi再開発プロジェクト 3
■ このスレッドは過去ログ倉庫に格納されています
で、perl全然知らないんだけど>>122 を元に if (open(OUT, "+>>$DATAFILE")) { @logdat = <OUT>; if (scalar @logdat > 999) { print OUT "$outdat\n"; print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { print OUT "$outdat\n"; close(OUT); } } print $outdatやclose(OUT)が複数箇所で出て非常によろしくないけど とりあえずwindows上では動作した。 で、そのchmodがうまく効いてくれないのが問題じゃなかったっけ? 1000レスを大幅にオーバーしちゃうのは。 だから、chmod完了待ちの間に大量のwriteリクエストが来ちゃうことが問題なの。 writeがあまり来なくなる(一段落する)と、chmodが完了するから大丈夫。 ↑で動作したと書いたけど、 競合状態(複数プロセス)でどうなるかはテストしてない。 FreeBSD上でどうなるかも。 あ、違う。 すみません。私がアホでした。 さらに if (1000over) { そのままclose(); } を入れないと意味無いんだった。 まとめ。 ・chmodによるロックは高負荷時に効かなくなる。 対策案 まともな対処 ・トランザクション処理をするDBDなどで1000ロック処理をする 分かりやすい対処 ・ファイルシステムでロックファイルを使う 提案 ・泥臭い処理を書くとバグるから、出来るだけCPANの.pm(Perl Module)を流用しよう >>249 if (open(OUT, "+>>$DATAFILE")) { ってのがあるんだ。 入れてみよう。 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; if(scalar @logdat > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } >>256 版を全サーバに入れました live5 を除く live8/9 は root★さんのもじもじが必要 if(scalar @logdat > 1000) { close(OUT); } この文も入れたほうがいいかと、、 $lognum = @logdat を入れなくて大丈夫? if (scalar @logdat > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } こうか? #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; $lognum = @logdat; if($lognum > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); close(OUT); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } こうかな? #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } elsif($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } $lognum が宣言してない変数なら、 $lognum = @logdat; ↓ my $lognum = @logdat; でたぶんいいかと。 こうだった #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); close(OUT); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } たまに「このスレッドは1000を超えました〜」が書き込まれないような気はしますが、 1000を超えて書き込まれることはなくなるはずです。 ……いいんだろうか。 if($lognum > 999) ↓ elsif($lognum > 999) はなおしてもらわんと結局意味がないような、、 >>267 あー、DispErrorはexitしちゃうんで……。 さらに修正 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } またまた修正 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } >>268 あ、DispErrorでexitするから結局elsifにしなくてもいい、ってことね、、 何か気味悪いなw print OUT "$outdat\n"; を1000over判定の後にして$lognumを++する方が。 もし書き込めなかったら狂っちゃうけど chmod問題の原因はそっちっぽいから。 >>270 1000以上でも書き込みするような気がするけど? 狼で1000いったスレに 1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 が書きこまれないです。 1000で止まってますけど あ、@logdatをhtml/*.html作成とかで使ってるのかな。 >>271 そうです。だから実はcloseも要らないです。 ……まあたしかに行儀は悪いですが。 chmod(0555, $DATAFILE); したファイルには書けないんだから 次のbbs.cgiは早めに判定した方がいいなぁ 512 超え判定と同時にやるのがいいのだろうか? どやってやるの? これはbbs.cgiのかなり前半 my $datsizeis =(stat("$DATAFILE"))[7]; unless( $datsizeis <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } >>272 あ、それ思った。 if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } あと、各所で1001が消えてるみたいだけど、気にしない方向で。 変更 if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } >>277 それって unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でよいような気がする。。あとで$datsizeisを別に使うならまだしも。 で、ファイルのパーミッションを取得するのは (stat("$DATAFILE"))[2] だそうです。 >>277 if (!-w $DATFILE) { DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } とか? >>281 あっ、そっちのほうがスマートだね、、じゃあ、 unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } こうだとよいのかな?(下はどうでもいいけど、、) 入れてこますか unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でも 二回実行するより stat とったほうがいいのかな? http://www.kaimei.org/note/book_out/eff_perl.html ここの56項にstatよりファイルテスト演算子のほうが 効率がいいと書いてあるぽ。2回だとどうかしらんけど、、 unless (-w $DATAFILE) { DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless (-s _ <= 512000) { DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でどうでしょ。 書き込み可能かの判定はaccess()でも出来るけど サイズの判定はstat()じゃないと駄目なので、結局stat()は呼ばれる。 と思うのでstat()1回に一票。 つまり if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } これは保険で unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } が通常のルートですなぁ メッセージ変えておこうかな、 >>286 だと2回目の判定で前回のデータから読み込むんだね、、 statじゃなくてもそれが一番よさげ。 >>290-291 ( ・∀・)つ〃∩ヘェーヘェーヘェー if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } 『1001』が書き込まれてないスレって、パーミションが 落ちてないような気がするけど大丈夫かな? 圧縮の時にパーミション見てたりしていない? >>293 ニュー速の1001がいないスレにテスト書き込みしてみたけど、 「ERROR:このスレッドには書き込めません。」でした。 パーミションはちゃんと落ちてる模様。 >>294 パーミッションじゃなく1000overではじかれてるんじゃない? 1001の書き込みとchmodはセットでしょ? 大丈夫なの? >>292 のメッセージ入りバージョンなら、外から判別できるみたいよ。 なにやら1001ストッパーがかかっているスレッドはsubject.txtに記録されているレス数が微妙に少ないような。 print OUT "1001<><>Over 1000 Thread<>このスレッド〜 のところに $lognum++ が必要な気がする……。 >>295 分かりづらくてすまん。>>296 の言うとおり、 >>292 のメッセージが入っているという前提でした。。 >>297 狼をしばらく見てたけど、どうやら subject.txtに1001と書いてある→1001ストッパーがいない subject.txtに1002と書いてある→1001ストッパーがいて、普通通り止まっている になってるみたいです。 >>299 あ、多くなるんですか……。なんだろう。 1001がないスレをJaneで取得するとDATサイズエラー警告が出る。 試しに狼の1000超えスレッド15本を見ると、 subject.txtは1002、datは1001、1001ストッパーあり:8スレッド subject.txtは1001、datは1001、1001ストッパーあり:3スレッド subject.txtは1001、datは1000、1001ストッパーなし:4スレッド でした。subject.txtの勝率2割。 Live2chだと実害はありませんが、 「新着あり」→「レス取得」→「新着あり」の永久コンボです。 そろそろ雑質スレや専用ブラウザスレが騒がしくなってきました。 >>301 どっちかと言うとJaneの不具合だから、こっち。 2ちゃんねる用ブラウザ「OpenJane」Part74 http://pc2.2ch.net/test/read.cgi/software/1075644934/ 漏れもJane使いで同じ症状が出てるんだけどな。 ここのやりとりを起き抜けでぼおっと読みました。 作戦の趣旨は理解できたです。 あとは、超高負荷になった時にどうなるかということで。 >306 live8に入れないと分からない 1.( 1001 < $lognum) && ($lognum < 2000)の範囲内 2.datファイルが壊れる 3.鯖が落ちる のどれか もう仕事人さんがlive8に入れてありました。(Perl版) さきほど私がperlccにかけて、バイナリ版にしました。 入れてあるから、1000までしかいかないんではないかと。 ■2/29■ハロー!モーニング。スペシャル■Part3■ http://live8.2ch.net/test/read.cgi/dancesite/1078018021/ 924もパーミッションで止めるようにできるね(もうやってるのかな そもそも高速処理が要求されるのに 高コストなライトパーミッションクローズでとめられるのかというと・・・ キャッシュがされないDNSのようなしくみがあればいいんですが。 >>310 訂正。 >>191 の案1で1000を越えていたときのみキャッシュするようにする。 たとえばこのスレを例にとり、 1076666901.oparete..qb3.tts.2ch.netなるホストの逆引きで 1000を越えているいないでキャッシュの許可権限を動的に変換できないかということ。 >>279 のどこが悪いんだ? ここじゃなくて他のところが悪いの? >>313 >>279 だと、 確実に書き込みは止まると思うけど、 高負荷だと「このスレッドは1000を超えました」を誰も通らないことになると思う。 …つか、実際になってるか。 >>313 >>279 多分、 if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } の部分を誰も通ってないのではないかと。。 今、live8/livecxのチェックを番組を未ながらやってるです。 この内容じゃ、速いの当たり前か。 subject.txtに書かれるレス数と実際のレス数が違うのなんでだろ〜 (1) bbs.cgi の序盤 unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } (2) bbs.cgi の中盤の最後 (datへの追記) if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } (3) bbs.cgi の終盤の始め #================================================== # ファイル操作(subject.txt & subback.html) #================================================== { #サブジェクトパスを作成 my $rnd = int(rand(99999)); my $subject = $PATH . "subject.txt"; my $subtemp = $PATH . $rnd . $FORM{'time'} . ".tmp"; my $keyfile = $FORM{'key'} . ".dat"; use vars qw($FILENUM); use vars qw($SUBLINE); use vars qw(@newsub); #サブジェクトファイルを読み込む unless(-e "$subject"){ makesub(); } open(SUBR,"<$subject");#SUBJECTを開く my @SUBJECTLIST = <SUBR>;#内容を全て読み込む close(SUBR);#閉じる $FILENUM = @SUBJECTLIST; MakeWorkFile($FORM{'key'}); if($FORM{'subject'} ne ""){ #subjectがあれば新規スレッド my $subtm = "$keyfile<>$FORM{'subject'} (1)\n"; @newsub = ($subtm, @SUBJECTLIST); ++$FILENUM; }else{ my (@tempsub, $transub, $frontsub, $rearsub); if($FORM{'mail'} =~ /sage/){ $transub = join('<<>>', @SUBJECTLIST);#一本につなげる ($frontsub, $rearsub) = split(/$keyfile<>/, $transub);#keyでぶったぎる @tempsub = split(/<<>>/, $rearsub);#後半ぶつ切り $transub = shift(@tempsub);#タイトルを取り出す $transub = $keyfile . "<>" . $SUBLINE;#タイトル入れ替え @newsub = (split(/<<>>/, $frontsub), $transub, @tempsub); }else{ $transub = $keyfile . "<>" . $SUBLINE; @newsub = ($transub, grep(!/^$FORM{'key'}/, @SUBJECTLIST)); } } if(@newsub){ #SUBJECTに書き込む open(SUBT, ">$subtemp"); #flock(SUBT, 2); foreach(@newsub){ print SUBT $_; } #flock(SUBT,8); close(SUBT); my $resuc = 0; until($resuc){ $resuc = rename($subtemp, $subject); } }else{ @newsub = @SUBJECTLIST; } } 関連するサブルーチンに makesub(); MakeWorkFile($FORM{'key'}); この二つがある #================================================== # subject.txtの補完 #================================================== sub makesub{ my $bbs = $FORM{'bbs'}; my $path = "../"."$bbs"; #$where{$bbs}; my $datpath = $path."/dat"; open(DIR, "ls $datpath/|") || print HTM " cant' ls."; my @dir = <DIR>; close(DIR); my %time; my @pagefile; foreach(@dir){ chop(); my $mtime; my $pagemax; my $mt = "$mtime"."$_"; ($mtime) = (stat("$datpath/$_"))[10]; $time{"$mt"} = $_; ++$pagemax; } my @mtime = keys(%time); my @sorting = sort by_number @mtime; my $filenum; foreach(@sorting){ push(@pagefile,$time{"$_"}); #print $time{"$_"}; ++$filenum; } #@pagefile = reverse(@pagefile); my $num; my $subject; while($filenum>=$num){ my $showpage = @pagefile[$num]; if($showpage eq ""){ } open(IN, "$datpath/$showpage")||die ""; my $resnum = 1; my $rr = 0; while(<IN>){ $resnum++; if($rr == 0){ $_ =~ s/\n//gi; $_ =~ s/\r//gi; my ($name,$mail,$time,$message,$subject); ($name,$mail,$time,$message,$subject) = split(/,/,$_); $rr = 1; } } close(IN); open(OUT,">$path/subject.txt"); print OUT $showpage .","; print OUT "$subject($resnum)\n"; ++$num; close(OUT); } } #================================================== # ファイル操作(HTML作成用作業ファイル更新) #================================================== #HTML用DATを作成 #MakeWorkFile(KEY-NUMBER) sub MakeWorkFile{ my $key = @_[0]; my $workfile = $TEMPPATH . $key . ".html"; my $dattemp = $DATPATH . $key . ".dat"; my (@messx,@content,@logdat); my ($lognum,$mailto,$time,$brmax,$topnum,$firstlog,$name,$mail,$subject,$message); open(RDAT,"<$dattemp"); @logdat=<RDAT>;#ログを配列に読み込む close(RDAT); #ログのカキコ数を取得 $lognum = @logdat; if(-w $dattemp && $lognum > 999){ #open(OVER, ">>$dattemp"); #print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; #close(OVER); #chmod(0555, $dattemp); $lognum++; if(-w $dattemp){ my $datdat = $DATPATH . $key; my $tmpdat = $DATPATH . $key . ".tmp"; my $success; open(COPY, "cp $dattemp $datdat |"); close(COPY); $success = 0; until($success){ $success = rename($datdat, $dattemp); } chmod(0555, $dattemp); unlink($tmpdat); } } #1つ目の要素を読み込む $firstlog = $logdat[0]; #改行カット chomp($firstlog); #1つ目の要素を加工する ($name,$mail,$time,$message,$subject) = split(/<>/,$firstlog); $SUBLINE = $subject . " (" . $lognum . ")\n"; open(SHTM,">$workfile");#ログテンポラリを開く #flock(SHTM,2); #サブジェクトテーブルを吐き出す(ここは必ず1行にまとめること(処理効率)) #----------------------------------------------------------------------- print SHTM <<EOF; <TABLE border=1 cellspacing=7 cellpadding=3 width=95% bgcolor="$SETTING{"BBS_THREAD_COLOR"}" align=center><TR><TD><DL><a name="\$ANCOR"></a><DIV ALIGN="right"><a href ="#menu">■</a><a href="#\$FRONT">▲</a><a href="#\$NEXT">▼</a></DIV><B>【\$ANCOR:$lognum】<FONT size=5 color="$SETTING{'BBS_SUBJECT_COLOR'}">$subject</FONT></B> EOF #----------------------------------------------------------------------- #1つ目のメールへのリンクを作成 if($ENV{'SERVER_NAME'} =~ /bbspink\.com/i) {#if(bbspink) unless($message =~ /2ch\.net/ || $message =~ /bbspink\.com/){ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/pinktower\.com\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; }else{ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; } } else {#if(!bbspink) unless($message =~ /2ch\.net/ || $message =~ /bbspink\.com/){ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/ime\.st\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; }else{ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; } }### if($mail ne ""){ $mailto = "<a href=\"mailto:$mail \"><b>$name </b></a>"; }else{ $mailto = "<font color=$SETTING{'BBS_NAME_COLOR'}><b>$name </b></font>"; } #1つ目の要素を吐き出す print SHTM "<dt>1 名前:$mailto $time<dd>$message <br><br><br>"; #ログ数から、表示コンテンツをチェック if($lognum > $SETTING{"BBS_CONTENTS_NUMBER"}){ #ケツの要素を0〜9番までコンテンツに格納 @content[0..$SETTING{"BBS_CONTENTS_NUMBER"}-1] = @logdat[@logdat-$SETTING{"BBS_CONTENTS_NUMBER"}..@logdat-1]; $topnum=@logdat-($SETTING{"BBS_CONTENTS_NUMBER"}-1); }else{ #アタマの要素を1〜10番までコンテンツに格納 @content[0..($SETTING{"BBS_CONTENTS_NUMBER"}-1)] = @logdat[1..$SETTING{"BBS_CONTENTS_NUMBER"}]; $topnum=2; } foreach(@content){ chomp($_);#改行をカット #要素を加工する ($name,$mail,$time,$message,$subject) = split(/<>/,$_); unless($_){ $topnum++; next; } #要素のメールへのリンクを作成 if($ENV{'SERVER_NAME'} =~ /bbspink\.com/i) {#if(bbspink) #if(bbspink) unless($message =~ /2ch\.net/ || $message =~ /bbspink\.com/){ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/pinktower\.com\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; }else{ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; } }else {#if(!bbspink) unless($message =~ /2ch\.net/ || $message =~ /bbspink\.com/){ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/ime\.st\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; }else{ $message =~ s/(https?|ftp|gopher|telnet|whois|news)\:\/\/([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/<a href=\"http\:\/\/$2\" target=\"_blank\">$1\:\/\/$2<\/a>/ig; } } ## if($mail ne ""){ $mailto = "<a href=\"mailto:$mail \"><b>$name </b></a>"; }else{ $mailto = "<font color=$SETTING{'BBS_NAME_COLOR'}><b>$name </b></font>"; } print SHTM "<dt>$topnum 名前:$mailto :$time<dd>"; my @messx = split(/<br>/,$message);#メッセージを行でカット my $messy = @messx;#行数を計算 if($messy > $SETTING{"BBS_LINE_NUMBER"}){ my $messz = join('<br>',@messx[0 .. $SETTING{'BBS_LINE_NUMBER'}-1]); print SHTM "$messz <br>"; print SHTM "<font color=\"$SETTING{'BBS_NAME_COLOR'}\">(省略されました・・全てを読むには<a href=\"../test/read.cgi/$FORM{'bbs'}/$key/$topnum\" target=\"_blank\">ここ</a>を押してください)</font><br>"; }else{ my $messz = join('<br>',@messx[0 .. $messy-1]); print SHTM "$messz <br>"; } $topnum++; print SHTM "<br>\n"; } #----------------------------------------------------------------------- #flock(SHTM,8); close(SHTM); #パーミッション調整 umask(0); chmod(0666,$workfile); } >>325 -w $DATAFILE or ( -s $DATAFILE <= 512 * 1024) or DispError("ERROR!","ERROR:このスレッドには書き込めません。"); エラーの単純化っでどうかしら?理由はどうあれ書き込めないのですから(^-^) chmodはされているのにOver1000がprintされていない、、、? そういえば、gethostbyaddr を二回やってるのはどうなんだろう。。。 >>331 追記および訂正。 our $Log_line = 1; # グローバル扱いで。以後レス数はこれを参照するとか。 if (open(OUT, "+>>$DATAFILE")) { $Log_line = join '', <OUT> =~ tr/\n/\n/ } -w $DATAFILE or ( -s $DATAFILE <= 512 * 1024) or ($Log_line > 1000) or DispError("ERROR!","ERROR:このスレッドには書き込めません。"); if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } print OUT "$outdat\n"; ++$lognum; if($lognum > 1000) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } >>334 条件が無茶苦茶ですね。ごめんなさい。 (-w $DATAFILE and ( -s $DATAFILE <= 512 * 1024) and ($Log_line < 1001)) or DispError("ERROR!","ERROR:このスレッドには書き込めません。"); >>335 むしろそうするくらいなら、 ++$lognum; を削除 だけで済むような。 質問。subject.txtに記録されるレス数は >>326 の $lognum ですか? >>339 うん。今そのことについて議論してるところかと。 >340 漏れも多分そうだと思って一応++$lognum;は残しておいてもた if($lognum > 1010) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } にしてみた。 というか、datの書き込みのあとには、 #パーミッション調整 umask(0); chmod(0666, $DATAFILE); がきてますよー。 if($lognum > 1000) { ++$lognum; #←これもいるかも print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } ただ、>>344 みたいなアプローチがどのぐらい効果あるかだけど、、、。 それで、1001ストッパーが書かれるような気は、あんまりしないかも。 ちょっとお出かけ。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる