#!/usr/bin/perl #┌───────────────────────────────── #│ Sun Board v4 #│ sunbbs.cgi - 2008/03/07 #│ Copyright (c) KentWeb #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── # 外部ファイル require './init.cgi'; require $jcode; &decode; if ($mode eq 'form') { &form; } elsif ($mode eq 'regist') { ®ist; } elsif ($mode eq 'admin') { &admin; } elsif ($mode eq 'mente') { &mente; } elsif ($mode eq 'edit') { &edit; } elsif ($mode eq 'userdel') { &userdel; } &error("不明な処理です"); #------------------------------------------------- # 投稿処理 #------------------------------------------------- sub regist { # チェック if ($no_wd) { &no_wd; } if ($jp_wd) { &jp_wd; } if ($urlnum > 0) { &urlnum; } # 投稿キーチェック if ($regist_key && !$whatsnew) { require $regkeypl; if ($in{'regikey'} !~ /^\d{4}$/) { &error("投稿キーが入力不備です。

投稿フォームに戻って再読込み後、指定の数字を入力してください"); } # 投稿キーチェック # -1 : キー不一致 # 0 : 制限時間オーバー # 1 : キー一致 local($chk) = ®istkey_chk($in{'regikey'}, $in{'str_crypt'}); if ($chk == 0) { &error("投稿キーが制限時間を超過しました。

投稿フォームに戻って再読込み後、指定の数字を再入力してください"); } elsif ($chk == -1) { &error("投稿キーが不正です。

投稿フォームに戻って再読込み後、指定の数字を入力してください"); } } # チェック if ($whatsnew) { if ($in{'pass'} ne $pass) { &error("パスワードが違います"); } } else { # ホスト名チェック &axscheck; if ($in{'name'} eq "") { &error("なまえの記入がありません"); } } if ($in{'comment'} eq "") { &error("コメントに記入がありません"); } if ($in{'email'} && $in{'email'} !~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { &error("Eメールの入力内容が不正です
"); } if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } if ($in{'url'} eq "http://") { $in{'url'} = ''; } open(DAT,"+< $logfile") || &error("Open Error: $logfile"); eval "flock(DAT, 2);"; my $top = ; # 二重投稿の禁止 local($num,$name,$com) = (split(/<>/, $top))[0,2,5]; if ($in{'name'} eq $name && $in{'comment'} eq $com) { close(DAT); &error("二重投稿は禁止です"); } # 記事Noカウント $no = $num + 1; # 削除キーを暗号化 my $pw; if ($in{'pwd'} ne "") { $pw = &encrypt($in{'pwd'}); } # 日付処理、タグ有効キー if ($whatsnew) { $date = $in{'date'}; } else { $date = &get_time; $in{'tag'} = 0; } # ログを更新 local($i, @file, @data); seek(DAT, 0, 0); while () { $i++; # 最大数以内 if ($i < $max) { push(@file,$_); # 最大数超 } else { unshift(@data,$_) if ($pastkey); } } # 現行ログ更新 unshift (@file,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pw<>$in{'tag'}<>\n"); seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); # 過去ログ更新 if ($pastkey && @data > 0) { &pastlog; } # HTMLファイルを生成 &html_regist("$htm_dir$htmfile", 1); &html_regist("$htm_dir$nexthtm", 2) if ($pagelog < @file); # クッキー発行 if (!$whatsnew) { &set_cookie($in{'name'},$in{'email'},$in{'url'},$in{'pwd'}); } # メール通知処理 if ($mailing && $in{'email'} ne $mailto) { &mail_to; } # HTMLファイルへ戻る &location; exit; } #------------------------------------------------- # HTML生成処理 #------------------------------------------------- sub html_regist { local($file, $page) = @_; open(WR,"+> $file") || &error("Write Error: $file"); print WR &header('HTML'); # リンク部 print WR "$point2"; print WR "Home\n"; if (!$whatsnew) { print WR "$point"; print WR "Post\n"; } print WR "$point"; print WR "Search\n"; # 過去ログ if ($pastkey) { print WR "$point"; print WR "Log\n"; } print WR "$point"; print WR "Admin\n

\n"; # タイトル部 if ($t_gif eq '') { print WR "$title\n"; } else { print WR "\"$title\"\n"; } # ひとことメッセージを表示 $message =~ s/\r\n/
/g; $message =~ s/\r/
/g; $message =~ s/\n/
/g; print WR "

$message


\n"; # 記事を展開 my ($next, $last); if ($page == 2) { $next = $pagelog+1; $last = $max; } else { $next = 0; $last = $pagelog; } my $i = 0; open(IN,"$logfile") || &error("Open Error: $logfile"); while ( my $data = ) { $i++; if ($i < $next) { next; } if ($i > $last) { last; } print WR &log_view($data, $page); } close(IN); if (!$whatsnew) { print WR "\n"; } # 次/前ページのリンクを生成 if (@file > $pagelog && $page == 1) { print WR "\n"; } elsif (@file > $pagelog && $page == 2) { print WR "\n"; } print WR "
"; print WR "
"; print WR "
\n"; # 削除フォーム if (!$whatsnew) { print WR "\n"; print WR "
\n"; print WR "
\n"; print WR "記事No \n"; print WR "削除キー \n"; print WR "\n"; print WR "

\n"; } # 著作権を表示(削除不可) print WR "
\n"; print WR "- SunBoard -\n"; print WR "
\n\n\n"; close(WR); } #------------------------------------------------- # 表示部戻り #------------------------------------------------- sub location { # 投稿確認画面の表示 if ($msg_check) { print &header; print qq|

\n|; print qq|

処理は正常に完了しました

\n|; print qq|
\n|; print qq|\n|; print qq|
\n|; print qq|\n|; exit; } # IISサーバ対応 if ($ENV{PERLXS} eq "PerlIS") { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $htm_url$htmfile\n\n"; } #------------------------------------------------- # 記事削除処理 #------------------------------------------------- sub userdel { # フォームチェック if ($in{'no'} eq "") { &error("記事NOが入力されていません"); } if ($in{'pwd'} eq "") { &error("削除キーが入力されていません"); } # ログファイルを開く local($i, $k, $flag, @file); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); eval "flock(DAT, 2);"; while () { $i++; my ($num,$date,$name,$email,$sub,$com,$url,$host,$pwd) = split(/<>/); if ($in{'no'} == $num) { $k = $i; $flag = 1; if ($pwd eq '') { $flag = -1; last; } elsif (&decrypt($in{'pwd'}, $pwd) != 1) { $flag = -2; last; } next; } push(@file,$_); } if (!$flag || $flag == -2) { close(DAT); &error("認証できません"); } elsif ($flag == -1) { close(DAT); &error("削除キーが設定されていません"); } # ログ更新 seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); # HTMLファイルを生成 if ($k > $pagelog) { &html_regist($nexthtm, 2); } elsif ($k <= $pagelog) { &html_regist("$htm_dir$htmfile", 1); &html_regist("$htm_dir$nexthtm", 2) if ($pagelog < @file); } # 初期画面に戻る &location; exit; } #------------------------------------------------- # 管理用初期画面 #------------------------------------------------- sub admin { # ログイン画面 if ($in{'pass'} eq '') { print &header; print qq|\n|; print qq|\n|; print qq|
入室画面
\n|; print qq|

管理用パスワードを入力して下さい

\n|; print qq|
\n|; if ($whatsnew) { print qq|書込\n|; print qq|ログ
\n|; } else { print qq|\n|; } print qq|\n|; print qq|
\n|; print qq|\n|; exit; # パスワードチェック } elsif ($in{'pass'} ne $pass) { &error("パスワードが違います"); } # 修正 if ($in{'ope'} eq 'mente' && $in{'no'}) { &mente; # 削除 } elsif ($in{'ope'} eq 'del' && $in{'no'}) { local($i, $k, @file); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); eval "flock(DAT, 2);"; while () { my ($no) = split(/<>/); $i++; if ($in{'no'} == $no) { $k = $i; next; } push(@file,$_); } seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); if ($k > $pagelog) { &html_regist($nexthtm, 2); } elsif ($k <= $pagelog) { &html_regist("$htm_dir$htmfile", 1); &html_regist("$htm_dir$nexthtm", 2) if ($pagelog < @file); } } # 管理画面 print &header; print <<"EOM"; [戻る]
管理画面
処理:
EOM # ログ表示 open(IN,"$logfile") || &error("Open Error: $logfile"); while () { my ($no,$date,$name,$email,$sub,$com,$url,$host) = split(/<>/); $name = "$name" if ($email); $com =~ s/
//g; $com =~ s//>/g; if (length($com) > 60) { $com = substr($com,0,58) . "..."; } print qq|

\n|; print qq|[$no] $sub 投稿者:$name 日付:$date ホスト:$host\n|; print qq|
$com\n|; } close(IN); print <
EOM exit; } #------------------------------------------------- # 記事編集 #------------------------------------------------- sub mente { if ($in{'num'}) { # タグキー if (!$whatsnew) { $in{'tag'} = 0; } local($i, $k, @file); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); eval "flock(DAT, 2);"; while () { $i++; my ($no,$date,$name,$email,$sub,$com,$url,$host,$pwd,$tag) = split(/<>/); if ($in{'num'} == $no) { $k = $i; $_ = "$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>$in{'tag'}<>\n"; } push(@file,$_); } seek(DAT, 0, 0); print DAT @file; truncate(DAT, tell(DAT)); close(DAT); if ($k <= $pagelog) { &html_regist("$htm_dir$htmfile", 1); } elsif ($k > $pagelog) { &html_regist("$htm_dir$nexthtm", 2); } &admin; } print &header; print <<"EOM"; [戻る]
管理画面
EOM my ($no,$date,$name,$email,$sub,$com,$url,$ho,$pw,$tag); # ログ展開 open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$date,$name,$email,$sub,$com,$url,$ho,$pw,$tag) = split(/<>/); last if ($in{'no'} == $no); } close(IN); $com =~ s/
/\n/g; if (!$whatsnew) { print "
"; print "\n"; print ""; print "\n"; } print ""; print "\n"; print "\n"; print "\n"; if ($whatsnew) { if ($tag == 1) { $chk="checked"; } else { $chk=""; } print ""; print "\n"; } print "
おなまえ
E-mail
タイトル\n"; print ""; print "
コメント
\n"; print "
URL"; print "
タグ有効 "; print "(コメント内でタグを有効にする場合はチェック)
\n\n\n"; exit; } #------------------------------------------------- # 過去ログ生成 #------------------------------------------------- sub pastlog { my $past_flag; # 過去NOを開く open(NO,"+< $nofile") || &error("Open Error: $nofile"); eval "flock(NO, 2);"; my $count = ; $count = sprintf("%04d", $count); # 過去ログのファイル名を定義 my $pastfile = "$pastdir$count.dat"; # 過去ログを開く open(LOG,"+< $pastfile") || &error("Open Error: $pastfile"); eval "flock(LOG, 2);"; my @past = ; # 規定の行数をオーバーすると次ファイルを自動生成 if ($#past > $log_line - 2) { $past_flag = 1; # カウントファイル更新 $count = sprintf("%04d", $count+1); seek(NO, 0, 0); print NO $count; truncate(NO, tell(NO)); # 過去ログ名再定義 $pastfile = "$pastdir$count.dat"; @past = (); # 前番を閉じる close(LOG); # 新番をオープン open(LOG,"+> $pastfile") || &error("Write Error: $pastfile"); eval "flock(LOG, 2);"; } close(NO); my @temp; foreach (@data) { my ($pno,$pdate,$pname,$pmail,$psub,$pcom,$purl,$pho,$ppw,$ptag) = split(/<>/); if ($pmail) { $pname = "$pname"; } if ($purl) { if ($purl !~ m|https?://|i) { $purl = "http://$purl"; } $purl = "<URL>"; } if ($whatsnew) { $pcom = &tagview($pcom) if ($ptag == 1); push(@temp,"
[$pno] $psub Date:$pdate $purl
$pcom
\n"); } else { push(@temp,"
[$pno] $psub 投稿者:$pname 投稿日:$pdate $purl
$pcom
\n"); } } # 過去ログ更新 unshift(@past,@temp); seek(LOG, 0, 0); print LOG @past; truncate(LOG, tell(LOG)); close(LOG); if ($past_flag) { chmod(0666,$pastfile); } } #------------------------------------------------- # メール送信 #------------------------------------------------- sub mail_to { # メールタイトルを定義 my $msub = &base64("[$title : $no] $in{'sub'}"); my $com = $in{'comment'}; $com =~ s/
/\n/ig; $com =~ s/&/&/g; $com =~ s/"/"/g; $com =~ s/</</g; $com =~ s/>/>/g; # メール本文を定義 my $mbody = <= 0) { $flg = 1; last; } } if ($flg) { &error("禁止ワードが含まれています"); } } #------------------------------------------------- # 日本語チェック #------------------------------------------------- sub jp_wd { if ($in{'comment'} !~ /[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/) { &error("コメントに日本語が含まれていません"); } } #------------------------------------------------- # URL個数チェック #------------------------------------------------- sub urlnum { local($com) = $in{'comment'}; local($num) = ($com =~ s|(https?://)|$1|ig); if ($num > $urlnum) { &error("コメント中のURLアドレスは最大$urlnum個までです"); } } #------------------------------------------------- # 時間取得 #------------------------------------------------- sub get_time { $ENV{'TZ'} = "JST-9"; my ($min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[1..6]; my @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); # 日時のフォーマット if ($whatsnew) { sprintf("%04d-%02d-%02d (%s)", $year+1900,$mon+1,$mday,$week[$wday]); } else { sprintf("%04d/%02d/%02d(%s) %02d:%02d", $year+1900,$mon+1,$mday,$week[$wday],$hour,$min); } }