#!/usr/bin/perl # # #初期設定項目 # #文字コードライブラリー require './jcode.pl'; #管理者パスワード #管理画面に入るにはpasswordの所にここで設定したパスワードを入力して入る。 $admin = "0123"; #最大ログ保存数 $data_max = 50; #このスクリプトの場所、パーミッションは755 $this = "./guestbook.cgi"; #ログファイルの場所、パーミッションは666 $logfile = "./guestbook.dat"; #1ページのコメント表示数 $comsize = 5; #ロックファイル $lockdir = "./lockdir"; #メイン処理 &decode; if ($mode eq 'regist'){ ®ist; } elsif ($mode eq 'delete'){ &delete; } elsif ($mode eq 'res'){ &res;} &html; #html表示 sub html{ #ログファイル読み込み open(IN,"$logfile") || &error('エラー','ログファイルを開けません'); @log = ; close(IN); print "Content-type: text/html\n\n"; if ($edit eq 'on'){ print <<"HTML"; bbs 管理画面 HTML } else{ print <<"HTML"; GUESTBOOK
GUEST BOOK
title:
name:
mail:
url:
comment:
 
password:
HTML } #コメント処理 $start = $page +1; $end = $page + $comsize; $i= 0; foreach $in (@log){ $i++; if ($i < $start){ next;} elsif ($i > $end ){ next;} $in =~ s/\n//; ($num,$name,$email,$subject,$comment,$url,$password,$res,$jptime) = split(/\t/,$in); if ($edit eq 'on'){ $kanri = "

"; } if ($url ) {$url = "

http\://$url";} if ($email) {$name = "$name";} if ($res) { $res = "$res";} #コメント部分の表示 print <<"COMMENT"


No.$num$subject
$comment$url

by:$name
$jptime
$res$kanri
COMMENT } &next; print <<"END";
$back $next $rest $total


パスワード 削除番号
END exit; } #デコード処理 sub decode{ $method = $ENV{ 'REQUEST_METHOD' }; if( $method eq 'GET' ) { $input = $ENV{ 'QUERY_STRING' }; } else {read( STDIN,$input,$ENV{ 'CONTENT_LENGTH' } );} @in = split(/&/,$input); foreach (@in) { ($list, $value) = split(/=/); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value, 'sjis'); $form{$list} = $value; } $mode = $form{'mode'}; $page = $form{'page'}; $no = $form{'no'}; $name = &tag($form{'name'}); $email = $form{'email'}; $subject = &tag($form{'subject'}); $comment = &tag($form{'comment'}); $url = $form{'url'}; $password = $form{'password'}; $res = &tag($form{'res'}); } #ログファイルに書き込み sub regist{ if ($password eq "$admin"){ $edit = 'on'; &html;} else{ $edit = 'off';} if (!($comment && $password && $name )){ &error('エラー','コメントとパスワード、名前を記入してください。')} #urlからhttpを削除 $url =~ s/^http\:\/\///; #現在時間所得 &time; open(IN,"$logfile") || &error('エラー','ログファイルを開けません'); @log = ; close(IN); $top = $log[0]; ($top_no,$t_name,$t_email,$t_subject,$top_comment,$t_url, $top_password,$t_res,$top_time)= split(/\t/,$top); if ($top_comment eq $comment && $t_name eq $name ){ &error('エラー','二重投稿禁止')} $no = $log[0] + 1 ; #パスワード暗号化 $salt = pack( "CC",int( rand(26) + 65 ),int(rand(26) + 97 )); $password = crypt( $password,$salt); $newdata = "$no\t$name\t$email\t$subject\t$comment\t$url\t$password\t$res\t$jptime\n"; &lock; if ($lock_flg == 0){ &error('エラー','只今混み合ってます。しばらくおまちください')} open(OUT,">$logfile") || &error('エラー','ログファイルを開けません'); unshift (@log,"$newdata"); #ログ保存数を設定($# は変数のインデックスの最大値を求める記述) if ($#log > ($data_max -1)){ $#log = $data_max -1;} print OUT @log; close(OUT); &unlock; } #ログファイルから削除 sub delete{ if ($no eq '' || $password eq ''){ &error('エラー','削除番号とパスワードを記入してください。')} open(IN,"$logfile")|| &error('エラー','ログファイルを開けません'); $pass_match = 0; foreach () { ($log_no,$log_name,$log_email,$log_subject,$log_comment, $log_url,$log_password,$log_res,$log_jptime) = split(/\t/); if ($log_password eq crypt("$form{'password'}",$log_password)){ $pass_match = 1;} elsif ($password eq $admin ) { $pass_match = 1;} #削除ナンバー以外は保存 if (!($no == $log_no)){ push(@log,$_); } } if ($pass_match == 0){ &error('エラー','パスワードが違ってます。')} close(IN); &lock; if ($lock_flg == 0){ &error('エラー','ただいま混みあってます。')} open(OUT,">$logfile")|| &error('エラー','ログファイルを開けません'); print OUT @log; close(OUT); &unlock; } #レス追加 sub res{ open(IN,"$logfile"); foreach $_ () { ($log_no,$log_name,$log_email,$log_subject,$log_comment, $log_url,$log_password,$log_res,$log_jptime) = split(/\t/,$_); $newres = "$log_no\t$log_name\t$log_email\t$log_subject\t$log_comment\t$log_url\t$log_password\t$res\t$log_jptime"; #保存 if ($no == $log_no){ push(@log,$newres); } else { push(@log,$_); } } close(IN); &lock; if ($lock_flg == 0){ &error('エラー','ただいま混みあってます。')} open(OUT,">$logfile")|| &error('エラー','ログファイルを開けません'); print OUT @log; close(OUT); &unlock; } #nextページ処理サブルーチン sub next { $next_page = $page + $comsize; $back_page = $page - $comsize; $page_total = int( ($#log ) / $comsize )+1; $page_rest = ($page / $comsize)+1; $page_all = ($#log +1) - ($page + $comsize); if ($page_all > O){ $total = "あと$page_all件の書き込みがあります。\n";} if ($back_page >= 0){ $next = "前のページ\n"; } if ($next_page < $i){ $back = "次のページ\n"; } $rest = "$page_rest/$page_total\n"; } #タグの禁止と改行の変更サブルーチン sub tag { $_[0] =~ s/&/&/g; $_[0] =~ s/"/"/g; $_[0] =~ s//>/g; $_[0] =~ s/\r\n/
/g; $_[0] =~ s/\r/
/g; $_[0] =~ s/\n/
/g; return $_[0]; } #時間所得 sub time { ($sec,$min,$hour,$day,$mon,$year,$wday) = localtime(time); $nitiji = sprintf("%04d/%02d/%02d/",$year +1900,$mon +1,$day); $jikan = sprintf( "%02d:%02d",$hour,$min); $jptime = $nitiji.$jikan ; } #ファイルロック処理 sub lock{ $lock_flg = 0; foreach ( 1..5 ){ if(mkdir($lockdir,0755 )){ $lock_flg = 1; last; } else { sleep(1);} } if( !$lock_flg){ @stat_data = stat $lockdir; if(( time - $stat_data[9]) > 60 ){ rmdir $lockdir;} } return $lock_flg; } sub unlock{ rmdir($lockdir); $lock_flg = 0; } #エラーメッセージ表示 sub error { print "Content-type: text/html\n\n"; print <<"HTML"; $_[0]
$_[1] HTML exit; } __END__