#!/usr/local/bin/perl #┌───────────────────────────────── #│ [ WebPatio ] #│ regist.cgi - 2006/11/11 #│ Copyright (c) KentWeb #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── # 外部ファイル取り込み require './init.cgi'; require $jcode; &parse_form; &axscheck; if ($mode eq "todos") { ®ist; } elsif ($mode eq "del") { &delete; } elsif ($mode eq "mente") { &mente; } elsif ($mode eq "edit_log") { require $editlog; &edit_log; } &error("不明な処理です"); #------------------------------------------------- # 記事投稿処理 #------------------------------------------------- sub regist { local($sub,$key,$flg,$i,@top); # 権限チェック if ($authkey && $my_rank < 2) { &error("投稿の権限がありません$my_rank"); } # POST限定 if ($postonly && !$postflag) { &error("不正なアクセスです"); } # チェック if ($no_wd) { &no_wd; } if ($jp_wd) { &jp_wd; } if ($urlnum > 0) { &urlnum; } # コメント文字数チェック if (length($i_com) > $max_msg*2) { &error("文字数オーバーです。
全角$max_msg文字以内で記述してください"); } # 汚染チェック $in{'res'} =~ s/\D//g; # 投稿内容チェック if ($i_com eq "") { &error("コメントの内容がありません"); } if ($i_nam eq "") { if ($in_name) { &error("名前は記入必須です"); } else { $i_nam = '名無しのゴンベエ'; } } if ($in_mail && $in{'email'} eq "") { &error("E-mailは記入必須です"); } if ($in{'email'} && $in{'email'} =~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { &error("E-mailの入力内容が不正です"); } if ($i_sub eq "") { &error("タイトルは記入必須です"); } if ($i_sub =~ /^(\x81\x40|\s)+$/) { &error("タイトルは正しく記入してください"); } if ($i_nam =~ /^(\x81\x40|\s)+$/) { &error("名前は正しく記入してください"); } if ($i_com =~ /^(\x81\x40|\s|
)+$/) { &error("コメントは正しく記入してください"); } if ($in_pwd && $in{'pwd'} eq "") { &error("パスワードは入力必須です"); } if (length($in{'pwd'}) > 8) { &error("パスワードは8文字以内にして下さい"); } if ($in{'url'} eq "http://") { &error("記入できません"); } # トリップ $i_nam2 = &trip($i_nam); # パスワード暗号化 if ($in{'pwd'} eq "") { $pwd = ""; } else { $pwd = &encrypt($in{'pwd'}); } #▼ここから▼ # ファイルアップ local($upl_flg, %ex, %w ,%h); if ($in{'upfile1'} || $in{'upfile2'} || $in{'upfile3'}) { require $upload; ($ex{1},$w{1},$h{1},$ex{2},$w{2},$h{2},$ex{3},$w{3},$h{3}) = &upload($time); # 画像アップのときはフラグを立てる if ($ex{1} || $ex{2} || $ex{3}) { $upl_flg = $time; } } #▲ここまで追加▲ # 新規投稿(新規スレッド作成) if ($in{'res'} eq "") { # indexファイル local($i, $flg, $top, @new, @tmp, @top); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; # 連続投稿IPチェック local($no,$ho,$t) = split(/<>/, $top); if ($host eq $ho && $wait > time - $t) { close(DAT); &error("連続投稿はもうしばらく時間をおいて下さい"); } $new = $no + 1; # index展開 while() { local($sub,$key) = (split(/<>/))[1,6]; $i++; if ($sub eq $in{'sub'}) { $flg++; last; } elsif ($key == 2) { push(@top,$_); next; } if ($i >= $i_max) { push(@tmp,$_); } else { push(@new,$_); } } # スレッド名重複チェック if ($flg) { close(DAT); &error("「$in{'sub'}」は既存スレッドと重複しています。
別のスレッド名を指定してください"); } # ファイルアップ #local($upl_flg, %ex, %w ,%h); #if ($in{'upfile1'} || $in{'upfile2'} || $in{'upfile3'}) { #require $upload; #($ex{1},$w{1},$h{1},$ex{2},$w{2},$h{2},$ex{3},$w{3},$h{3}) = &upload($time); # 画像アップのときはフラグを立てる #if ($ex{1} || $ex{2} || $ex{3}) { $upl_flg = $time; } #} # 現行index更新 unshift(@new,"$new<>$i_sub<>0<>$i_nam2<>$date<>$i_nam2<>1<>$upl_flg<>\n"); unshift(@new,@top) if (@top > 0); unshift(@new,"$new<>$host<>$time<>\n"); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # 過去index更新 if (@tmp > 0) { $i = @tmp; open(DAT,"+< $pastfile") || &error("Open Error: $pastfile"); eval "flock(DAT, 2);"; while() { $i++; if ($i > $p_max) { local($delno) = split(/<>/); unlink("$logdir/$delno.cgi"); unlink("$logdir/$delno.dat"); next; } push(@tmp,$_); } seek(DAT, 0, 0); print DAT @tmp; truncate(DAT, tell(DAT)); close(DAT); } # スレッド更新 open(OUT,">$logdir/$new.cgi") || &error("Write Error: $new.cgi"); print OUT "$new<>$i_sub<>0<>1<>\n"; print OUT "0<>$in{'sub'}<>$i_nam2<>$in{'email'}<>$i_com<>$date<>$host<>$pwd<>$in{'url'}<>$in{'mvw'}<>$my_id<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>\n"; close(OUT); # 参照ファイル生成 open(NO,">$logdir/$new.dat") || &error("Write Error: $new.dat"); print NO "0:"; close(NO); # パーミッション変更 chmod(0666, "$logdir/$new.cgi"); chmod(0666, "$logdir/$new.dat"); &sendmail if ($mailing); # 返信投稿 } else { # 参照ファイル local($data); open(IN,"$logdir/$in{'res'}.dat"); $data = ; close(IN); ($count) = split(/:/, $data); # 連続投稿チェック local($top); open(IN,"$nowfile") || &error("Open Error: $nowfile"); $top = ; close(IN); local($no,$hos2,$tim2) = split(/<>/, $top); if ($host eq $hos2 && $wait > time - $tim2) { &error("連続投稿はもうしばらく時間をおいて下さい"); } # スレッド読み込み open(DAT,"+< $logdir/$in{'res'}.cgi") || &error("Open Error: $in{'res'}.cgi"); eval "flock(DAT, 2);"; local(@file) = ; # 先頭ファイルを抽出・分解 $top = shift(@file); local($no,$sub,$res,$key) = split(/<>/, $top); # ロックチェック if ($key eq '0' || $key eq '2') { close(DAT); &error("このスレッドはロック中のため返信できません"); } # 末尾ファイルを分解、重複チェック local($no2,$sb2,$na2,$em2,$co2) = split(/<>/, $file[$#file]); if ($i_nam2 eq $na2 && $i_com eq $co2) { &error("重複投稿は禁止です"); } # 採番 $newno = $no2 + 1; # 記事数チェック if ($m_max < $res+1) { &error("最大記事数をオーバーしたため投稿できません"); } elsif ($m_max == $res+1) { $maxflag = 1; } else { $maxflag = 0; } # ファイルアップ local($upl_flg, %ex, %w ,%h); if ($in{'upfile1'} || $in{'upfile2'} || $in{'upfile3'}) { require $upload; ($ex{1},$w{1},$h{1},$ex{2},$w{2},$h{2},$ex{3},$w{3},$h{3}) = &upload($time); } # スレッド更新 $res++; unshift(@file,"$no<>$sub<>$res<>1<>\n"); push(@file,"$newno<>$in{'sub'}<>$i_nam2<>$in{'email'}<>$i_com<>$date<>$host<>$pwd<>$in{'url'}<>$in{'mvw'}<>$my_id<>$time<>$ex{1},$w{1},$h{1}<>$ex{2},$w{2},$h{2}<>$ex{3},$w{3},$h{3}<>\n"); ## ←修正 seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); ## 規定記事数オーバのとき ## if ($maxflag) { # 過去ログindex読み込み open(BAK,"+< $pastfile") || &error("Open Error: $pastfile"); eval "flock(BAK, 2);"; local(@file) = ; # 現行ログindexから該当スレッド抜き出し local($top, @new); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$re,$nam,$d,$na2,$key,$upl) = split(/<>/); if ($in{'res'} == $no) { $re++; unshift(@file,"$no<>$sub<>$re<>$nam<>$date<>$na2<>1<>$upl<>\n"); next; } push(@new,"$_\n"); } # 現行ログindex更新 unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # 過去ログindex更新 seek(BAK, 0, 0); print BAK @file; truncate(BAK, tell(BAK)); close(BAK); ## ソートあり ## } elsif ($in{'sort'} == 1) { # indexファイル更新 local($flg, $top, @new, @top); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$re,$nam,$da,$na2,$key,$upl) = split(/<>/); if ($key == 2) { push(@top,"$_\n"); next; } if ($in{'res'} == $no) { $flg = 1; $new = "$in{'res'}<>$sub<>$res<>$nam<>$date<>$i_nam2<>1<>$upl<>\n"; next; } push(@new,"$_\n"); } if (!$flg) { &error("該当のスレッドがindexファイルに見当たりません"); } local($no2,$host2,$time2) = split(/<>/, $top); unshift(@new,$new); unshift(@new,@top) if (@top > 0); unshift(@new,"$no2<>$host<>$time<>\n"); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); ## ソートなし ## } else { # indexファイル更新 local($flg, $top, @new); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$re,$nam,$da,$na2,$key,$upl) = split(/<>/); if ($in{'res'} == $no) { $flg = 1; $_ = "$in{'res'}<>$sub<>$res<>$nam<>$date<>$i_nam2<>1<>$upl<>"; } push(@new,"$_\n"); } if (!$flg) { &error("該当のスレッドがindexファイルに見当たりません"); } local($no2,$host2,$time2) = split(/<>/, $top); unshift(@new,"$no2<>$host<>$time<>\n"); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); } # メール送信 &sendmail if ($mailing == 2); } # クッキーを格納 if ($in{'cook'} eq "on") { &set_cookie($i_nam,$in{'email'},$in{'pwd'},$in{'url'},$in{'mvw'}); } # 完了メッセージ &header; $md = 'view'; if ($in{'res'} eq "") { $no = $new; } else { $no = $in{'res'}; } print <

ご投稿ありがとうございました

EOM # 過去ログ繰り越しの場合 if ($maxflag) { print "ただし1スレッド当りの最大記事数を超えたため、
\n"; print "このスレッドは 過去ログ "; print "へ移動しました。\n"; $md = 'past'; } # 戻りフォーム print <<"EOM";

EOM exit; } #------------------------------------------------- # 記事削除 #------------------------------------------------- sub delete { # 汚染チェック $in{'f'} =~ s/\D//g; $in{'no'} =~ s/\D//g; # 削除処理 if ($in{'job'} eq "del") { if ($in{'pwd'} eq '') { &error("パスワードの入力モレです"); } # スレッドより削除記事抽出 local($flg,$top,$check,$last_nam,$last_dat,@new); open(DAT,"+< $logdir/$in{'f'}.cgi") || &error("Open Error: $in{'f'}.cgi"); eval "flock(DAT, 2);"; $top = ; while() { local($no,$sub,$nam,$eml,$com,$dat,$ho,$pw,$url,$mvw,$myid,$tim,$upl{1},$upl{2},$upl{3}) = split(/<>/); if ($in{'no'} == $no) { $flg = 1; # パス照合 $check = &decrypt($in{'pwd'}, $pw); # スレッドヘッダのレス個数を調整 local($num,$sub2,$res,$key) = split(/<>/, $top); $res--; $top = "$num<>$sub2<>$res<>$key<>\n"; # 画像削除 foreach $i (1 .. 3) { next if (!$upl{$i}); local($ex) = split(/,/, $upl{$i}); if (-e "$upldir/$tim-$i$ex") { unlink("$upldir/$tim-$i$ex"); } } # スキップ next; } push(@new,$_); # 最終記事の投稿者と時間を覚えておく $last_nam = $nam; $last_dat = $dat; } if (!$flg) { &error("該当記事が見当たりません"); } if (!$check) { &error("パスワードが違います"); } # スレッド更新 unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # index展開 @new = (); local($top, @sort, @top); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$res,$nam,$dat,$na2,$key,$upl) = split(/<>/); if ($key == 2) { push(@top,"$_\n"); next; } if ($in{'f'} == $no) { # indexのレス個数を調整し、最終投稿者と時間を置換 $res--; $na2 = $last_nam; $dat = $last_dat; $_ = "$no<>$sub<>$res<>$nam<>$dat<>$na2<>$key<>$upl<>"; } push(@new,"$_\n"); # ソート用配列 $dat =~ s/\D//g; push(@sort,$dat); } # 投稿順にソート @new = @new[sort {$sort[$b] <=> $sort[$a]} 0 .. $#sort]; # index更新 unshift(@new,@top) if (@top > 0); unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # 完了メッセージ &header; print "
\n"; print "記事は正常に削除されました。\n"; print "
\n"; print "
\n"; print "
\n"; exit; } # 該当ログチェック local($flg,$top,$no,$sub,$nam,$eml,$com,$dat,$ho,$pw); open(IN,"$logdir/$in{'f'}.cgi"); $top = ; while() { ($no,$sub,$nam,$eml,$com,$dat,$ho,$pw) = split(/<>/); last if ($in{'no'} == $no); } close(IN); if ($pw eq "") { &error("該当記事はパスワードが設定されていないため
削除することはできません"); } &header; print <<"EOM";
  記事削除フォーム 前画面に戻る

削除記事 記事: No.$in{'no'}
件名: $sub
名前: $nam
パスワード
EOM exit; } #------------------------------------------------- # メンテ処理 #------------------------------------------------- sub mente { # 汚染チェック $in{'f'} =~ s/\D//g; $in{'no'} =~ s/\D//g; # 記事修正 if ($in{'job'} eq "edit") { if ($in{'pwd'} eq '') { &error("パスワードの入力モレです"); } require $editlog; &edit_log("user"); # 削除処理 } elsif ($in{'job'} eq "del") { if ($in{'pwd'} eq '') { &error("パスワードの入力モレです"); } # スレッドより削除記事抽出 local($flg, $top, @new); open(DAT,"+< $logdir/$in{'f'}.cgi") || &error("Open Error: $in{'f'}.cgi"); eval "flock(DAT, 2);"; $top = ; while() { local($no,$sub,$nam,$eml,$com,$dat,$ho,$pw,$url,$mvw,$myid,$tim,$upl{1},$upl{2},$upl{3}) = split(/<>/); if ($in{'no'} == $no) { $flg = 1; # パス照合 $check = &decrypt($in{'pwd'}, $pw); # スレッドヘッダのレス個数を調整 ($num,$sub2,$res,$key) = split(/<>/, $top); $res--; $top = "$num<>$sub2<>$res<>$key<>\n"; # 添付削除 foreach $i (1 .. 3) { next if (!$upl{$i}); local($ex) = split(/,/, $upl{$i}); if (-e "$upldir/$tim-$i$ex") { unlink("$upldir/$tim-$i$ex"); } } # スキップ next; } push(@new,$_); # 最終記事の投稿者と時間を覚えておく $last_nam = $nam; $last_dat = $dat; } if (!$flg) { &error("該当記事が見当たりません"); } if (!$check) { &error("パスワードが違います"); } # スレッド更新 unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # index展開 @new = (); @sort = (); @top = (); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$res,$nam,$dat,$na2,$key,$upl) = split(/<>/); if ($key == 2) { push(@top,"$_\n"); next; } if ($in{'f'} == $no) { # indexのレス個数を調整し、最終投稿者と時間を置換 $res--; $na2 = $last_nam; $dat = $last_dat; $_ = "$no<>$sub<>$res<>$nam<>$dat<>$na2<>$key<>$upl<>"; } push(@new,"$_\n"); # ソート用配列 $dat =~ s/\D//g; push(@sort,$dat); } # 投稿順にソート @new = @new[sort {$sort[$b] <=> $sort[$a]} 0..$#sort]; # index更新 unshift(@new,@top) if (@top > 0); unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # 完了メッセージ &header; print "
\n"; print "記事は正常に削除されました。\n"; print "
\n"; print "
\n"; print "
\n"; exit; # ロック処理 } elsif ($in{'job'} eq "lock") { if ($in{'pwd'} eq '') { &error("パスワードの入力モレです"); } local($top); open(DAT,"+< $logdir/$in{'f'}.cgi") || &error("Open Error: $in{'f'}.cgi"); eval "flock(DAT, 2);"; local(@file) = ; $top = shift(@file); # パスワードチェック local($no,$sb,$na,$em,$com,$da,$ho,$pw) = split(/<>/, $file[0]); if (!&decrypt($in{'pwd'}, $pw)) { &error("パスワードが違います"); } # 更新 local($num,$sub,$res,$key) = split(/<>/, $top); if ($key == 1) { $key = 0; } elsif ($key == 0) { $key = 1; } unshift(@file,"$num<>$sub<>$res<>$key<>\n"); seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); # index展開 @new = (); open(DAT,"+< $nowfile") || &error("Open Error: $nowfile"); eval "flock(DAT, 2);"; $top = ; while() { s/\n//; local($no,$sub,$res,$nam,$da,$na2,$key2,$upl) = split(/<>/); if ($in{'f'} == $no) { $_ = "$no<>$sub<>$res<>$nam<>$da<>$na2<>$key<>$upl<>"; } push(@new,"$_\n"); } # index更新 unshift(@new,$top); seek(DAT, 0, 0); print DAT @new; truncate(DAT, tell(DAT)); close(DAT); # 完了メッセージ &header; print "
\n"; if ($key == 1) { print "スレッドはロック解除されました。\n"; } else { print "スレッドはロックされました。\n"; } print "
\n"; print "
\n"; print "
\n"; exit; } # 該当ログチェック $flg = 0; open(IN,"$logdir/$in{'f'}.cgi"); $top = ; while () { ($no,$sub,$name,$email,$com,$date,$host,$pw) = split(/<>/); last if ($in{'no'} == $no); } close(IN); if ($pw eq "") { &error("該当記事はパスワードが設定されていません"); } ($num,$sub2,$res,$key) = split(/<>/, $top); &header; print <<"EOM";
  メンテフォーム 前画面に戻る

対象スレッド 件名: $sub
名前: $name
処理選択
パスワード
EOM exit; } #------------------------------------------------- # クッキー発行 #------------------------------------------------- sub set_cookie { local(@cook) = @_; local($gmt, $cook, @t, @m, @w); @t = gmtime(time + 60*24*60*60); @m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); @w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); # 国際標準時を定義 $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", $w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]); # 保存データをURLエンコード foreach (@cook) { s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; $cook .= "$_<>"; } # 格納 print "Set-Cookie: WEB_PATIO=$cook; expires=$gmt\n"; } #------------------------------------------------- # メール送信 #------------------------------------------------- sub sendmail { local($msub, $mbody, $mcom, $email); # メールタイトルを定義 $msub = "$title: $i_sub"; # 本文の改行・タグを復元 $mcom = $i_com; $mcom =~ s/
/\n/g; $mcom =~ s/</</g; $mcom =~ s/>/>/g; $mcom =~ s/"/”/g; $mcom =~ s/&/&/g; $mbody = <= 0) { $flg = 1; last; } } if ($flg) { &error("禁止ワードが含まれています"); } } #------------------------------------------------- # 日本語チェック #------------------------------------------------- sub jp_wd { local($sub, $com, $mat1, $mat2, $code1, $code2); $sub = $i_sub; $com = $i_com; if ($sub) { ($mat1, $code1) = &jcode'getcode(*sub); } ($mat2, $code2) = &jcode'getcode(*com); if ($code1 ne 'sjis' && $code2 ne 'sjis') { &error("題名又はコメントに日本語が含まれていません"); } } #------------------------------------------------- # URL個数チェック #------------------------------------------------- sub urlnum { local($com) = $i_com; local($num) = ($com =~ s|(https?://)|$1|ig); if ($num > $urlnum) { &error("コメント中のURLアドレスは最大$urlnum個までです"); } }