#!/usr/local/bin/perl #上記はperlのパス。サーバー管理者の指示に従う。 use strict; #---------------------# #席替えCGI Ver.0.21用BBSCGI 最終更新2005/7/16 #---------------------# #-----設定-----# require '../jcode.pl'; #jcode.plを呼び出す my $datafile = "bbs.dat"; #BBSデータファイル名 my $listfile = "list.dat"; #生徒リストファイル名 my $password = "master"; #管理用パスワード my $title = "席替え結果BBS"; #BBSタイトル my $cgi = "sekigaebbs.cgi"; #CGIファイル名 my $stylesheet = "style.css"; #スタイルシートファイル my $deletedays = 10; #(日) ここで設定した日数より古いログは削除 my $body = ""; #BODYタグ my $home = ' Home - 席替え占い '; #HOME等へのリンク(HTMLタグで)。'は使わないこと my $sonotacolor = "white"; #生徒リストファイルで設定された席以外の席の色 my $kiji = 10; #1ページあたりの記事数 my $honnin = "あなた"; #生徒リストファイルで設定された名前のうち、記事を書き込んだ人の名前と置き換える名前 my $lockdir = "lockbbs"; #ロックディレクトリ名 my $method = "post"; #---------設定は以上-------------------------------- my $total = 40; #生徒数 my (%FORM); &decode; &lock_check; &file_lock; &writedata; &kansou; &delete; &enterpass; &view; &adminview; &unlock; exit; #------------------------------------------- sub decode{ my $buffer; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } my @pairs = split(/&/, $buffer); foreach (@pairs) { my ($vn, $value) = split(/=/, $_); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/&/&/g; $value =~ s//>/g; $value =~ s/\t//g; $value =~ s/\cM//g; $value =~ s/\r\n/\n/g; $value =~ s/\r/\n/g; $value =~ s/\n/
/g; &jcode'convert(*value, "sjis"); $value; $FORM{$vn} = $value; } } sub lock_check{ if(-C "$lockdir">0.0004){ &unlock; } return; } sub file_lock{ my $lockflag=0; if (mkdir($lockdir, 0755)) {return;} for (my $i = 0; $i <= 5; $i++) { if (mkdir($lockdir, 0755)) { $lockflag=1; last; } else { sleep(1); } } if ($lockflag==0) { if(-e "$lockdir"){ &error(1,"他の方が使用中です。もう少し待ってからお願いします。

いつまでもこのメッセージが表\示されるようなら、
何らかのアクシデントで、ロックがかかったままの状態になっていると思われます。
管理者に連絡してください。

"); } else {&error(1,"ロックディレクトリを作成できません。

CGIの入っているディレクトリがディレクトリの作成を許可するパーミッションでは
ないのが原因だと思います。ディレクトリのパーミッションを変更してください。"); } } $SIG{'TERM'} = $SIG{'PIPE'} = $SIG{'HUP'} = "sigexit"; sub sigexit { rmdir($lockdir); exit(1); } } sub writedata{ ($FORM{'mode'} eq "write") || return; ($FORM{'name'}) || &error(0,"お名前を入力してください。"); ($FORM{'com'}) || &error(0,"感想を入力してください。"); ($FORM{'seats'}) || &error(1,"席替え結果が送信されていません。"); my ($username,$host) = &get_username; $FORM{'com'} = &tagok($FORM{'com'}); my @datas = &open_file($datafile,"席替えBBSログファイル"); my @newdatas; my $no=0; foreach (@datas){ my @dat = split(/\t/,$_); chomp @dat; ($^T-$dat[$#dat] > $deletedays*60*60*24) && next; push (@newdatas,$_); $no=$dat[0]; } $no++; push (@newdatas,"$no\t$FORM{'name'}\t$FORM{'com'}\t$FORM{'seats'}\t$username\t$host\t$^T\n"); &write_file(\@newdatas,$datafile,"席替えBBSログファイル"); } sub kansou{ ($FORM{'mode'} eq "kansou") || return; ($FORM{'name'}) || &error(0,"お名前を入力してください。"); ($FORM{'com'}) || &error(0,"感想を入力してください。"); ($FORM{'no'} eq "") && &error(1,"感想をどの記事につけるか、指定されていません。"); my ($username,$host) = &get_username; $FORM{'com'} = &tagok($FORM{'com'}); my @datas = &open_file($datafile,"席替えBBSログファイル"); my @newdatas; for(my $i=0;$i<=$#datas;$i++){ chomp $datas[$i]; my @dat = split(/\t/,$datas[$i]); if ($FORM{'no'}==$dat[0]){ @dat = (@dat,$FORM{'name'},$FORM{'com'},$username,$host,$^T); $datas[$i] = join("\t",@dat); } ($^T-$dat[$#dat] > $deletedays*60*60*24) && next; push (@newdatas,"$datas[$i]\n"); } &write_file(\@newdatas,$datafile,"席替えBBSログファイル"); } sub delete{ ($FORM{'mode'} eq "del") || return; ($FORM{'pass'} eq $password) || &error(0,"管理用パスワードが違います。"); ($FORM{'no'}) || &error(1,"削除する記事の指定がありません。"); my @datas = &open_file($datafile,"席替えBBSログファイル"); my @newdatas; chomp @datas; foreach (@datas){ my @dat = split(/\t/,$_); if ($dat[0]==$FORM{'no'}){ ($FORM{"del_0"} eq "on") && next; chomp @dat; my @ndat = @dat[0..6]; for (my $j=7;$j<=$#dat;$j+=5){ ($FORM{"del_$j"} eq "on") || push(@ndat,@dat[$j..$j+5]); } $_ = join("\t",@ndat); } push (@newdatas,"$_\n"); } &write_file(\@newdatas,$datafile,"席替えBBSログファイル"); $FORM{'mode'} = ""; } sub enterpass{ ($FORM{'mode'} eq "admin") || return; ($FORM{'pass'}) && return; &html_header("管理者用画面"); print <<"_HTML_";

_HTML_ &html_footer; } sub view{ ($FORM{'mode'} eq "admin") && return; my @datas = &open_file($datafile,"席替え結果BBSログファイル"); &html_header($title); my ($start,$end); print "*$deletedays日より古いログは自動的に削除されます。
\n"; $start = $FORM{'start'};($FORM{'start'} eq "") && ($start = $#datas); $end = $start-$kiji+1; ($end<0) && ($end=0); (scalar(@datas)==0) && print "まだログがありません。
\n"; for(my $i=$start;$i>=$end;$i--){ chomp $datas[$i]; my @dat = split(/\t/,$datas[$i]); print "
\n"; print "\n"; print "
\n"; my @seats = split(/,/,$dat[3]); &zaseki(\@seats,$dat[1]); print "
お名前
$dat[1]さん
\n"; print "
コメント
\n$dat[2]
\n"; print "
".&gettime($dat[6])."
感想:\n"; for(my $j=7;$j<=$#dat;$j+=5){ my $k = $j+1; print "
  • $dat[$k]($dat[$j],"; $k+=3; print &gettime2($dat[$k]); print ")\n"; } print "
    \n"; print "
    なまえ:\n"; print "感想:
  • \n"; } &nextpage($start,$end,$#datas); &html_footer; } sub adminview{ ($FORM{'mode'} eq "admin") || return; ($FORM{'pass'}) || return; ($FORM{'pass'} eq $password) || &error(0,"パスワードが違います。"); my @datas = &open_file($datafile,"席替え結果BBSログファイル"); &html_header("$title(管理者モード)"); print <<"_HTML_"; *$deletedays日より古いログは自動的に削除されます。
    _HTML_ my ($start,$end); $start = $FORM{'start'};($FORM{'start'} eq "") && ($start = $#datas); $end = $start-$kiji+1; ($end<0) && ($end=0); for(my $i=$start;$i>=$end;$i--){ chomp $datas[$i]; my @dat = split(/\t/,$datas[$i]); #my ($no,$name,$com,$seats,$username,$host,$time) = split(/\t/,$datas[$i]); print "

    \n"; print "\n"; print "\n"; print "\n"; print "
    \n"; print "\n"; print "\n"; print "
    \n"; my @seats = split(/,/,$dat[3]); &zaseki(\@seats,$dat[1]); print "
    お名前
    $dat[1]さん
    \n"; print "
    コメント
    \n$dat[2]
    \n"; print "
    ユーザー名:$dat[4]
    \nホスト:$dat[5]
    \n".&gettime($dat[6])."
    感想:\n"; for(my $j=7;$j<=$#dat;$j+=5){ my $k = $j+1; print "
  • $dat[$k]($dat[$j],"; $k++; print "$dat[$k],"; $k++; print "$dat[$k],"; $k++; print &gettime2($dat[$k]); print ")\n"; } print "
    \n"; print "
  • \n"; } &nextpage($start,$end,$#datas,$FORM{'mode'}); &html_footer; } sub nextpage{ my ($start,$end,$datano,$mode) = @_; print "
    "; if ($start<$datano){ $start = $start+$kiji; print "
    \n"; print "\n"; print "\n"; print "\n"; print "
    \n"; print "
    "; } if ($end>0){ $end--; print "
    \n"; print "\n"; print "\n"; print "\n"; print "
    \n"; } print "
    \n"; } #座席表示 sub zaseki{ my ($dat,$anata) = @_; my @list = &open_file($listfile,"生徒リストファイル"); chomp @list; my %color; foreach (@list){ my ($name,$color) = split(/\t/,$_); ($color) || ($color = $sonotacolor); $color{$name} = $color; } print "\n"; print "\n"; print "\n"; for(my $i=0;$i<=3;$i++){ my $name; ($$dat[$i] eq $honnin) ? ($name = $anata):($name = $$dat[$i]); print ""; } print "\n"; for (my $i=4;$i<40;$i++){ ($i%6==4) && print ""; my $name; ($$dat[$i] eq $honnin) ? ($name = $anata):($name = $$dat[$i]); print ""; ($i%6==3) && print "\n"; } print "
    黒板

    $name

    $name
    \n"; } #htmlヘッダー sub html_header{ my ($title) = @_; print "Content-type: text/html\n\n"; print <<"_HTML_"; $title $body

    $home

    $title

    _HTML_ } #htmlフッタ sub html_footer{ print <<"_HTML_"; [更新]

    管理者用

    _HTML_ } #秒数を年月日に変換 sub gettime{ my($time) = @_; my ($sec,$min,$hour,$dy,$mon,$year,$wday,$yday,$isdst) = gmtime($time+60*60*9); my @week = ('日','月','火','水','木','金','土'); $time = sprintf("%04d年%01d月%01d日\($week[$wday]\)%02d:%02d",$year+1900,$mon+1,$dy,$hour,$min); return $time; } #秒数を年月日に変換 sub gettime2{ my($time) = @_; my ($sec,$min,$hour,$dy,$mon,$year,$wday,$yday,$isdst) = gmtime($time+60*60*9); my @week = ('日','月','火','水','木','金','土'); $time = sprintf("%1d月%01d日\($week[$wday]\)",$mon+1,$dy,$hour,$min); return $time; } #ユーザーの情報取得 sub get_username{ my ($username,$host,$add); $username = $ENV{'REMOTE_USER'}; $host = $ENV{'REMOTE_HOST'}; $add = $ENV{'REMOTE_ADDR'}; if ($host eq "" ){$host = $add;} if ($host eq $add) { $host = ((gethostbyaddr(pack('C4',split(/\./,$add)),2))[0]);} if ($host eq ""){$host=$add;} if ($username eq ""){$username = $host;} return $username,$host; } sub write_file{ my ($datas,$file,$filename) = @_; open (LINES,">$file") || &error(1, "$filenameが開けないので、記録できません。"); eval 'flock(LINES,2);'; seek (LINES,0,0); print LINES (@$datas); eval 'flock(LINES,8);'; close (LINES); } sub tsuika_file{ my ($data,$file,$filename)=@_; open (LINES,">>$file") || &error(1, "$filenameが開けないので、記録できません。"); eval 'flock(LINES,2);'; seek (LINES,0,0); print LINES ($data); eval 'flock(LINES,8);'; close (LINES); } sub open_file{ my ($file,$filename) = @_; open (IN,"$file") || &error(1, "$filenameが開けません。"); my @datas = ; close (IN); return @datas; } sub unlock{ return rmdir($lockdir); } sub tagok{ #タグを戻す。 my ($comment) =@_; study $comment; $comment =~ s/<b>(.*?)<\/b>/$1<\/b>/gi; $comment =~ s/<i>(.*?)<\/i>/$1<\/i>/gi; $comment =~ s/<s>(.*?)<\/s>/$1<\/s>/gi; $comment =~ s/<sup>(.*?)<\/sup>/$1<\/sup>/gi; $comment =~ s/<font(.*?)>(.*?)<\/font>/$2<\/font>/gi; $comment =~ s/<a href=(.*?)>(.*?)<\/a>/$2<\/a>/gi; return $comment; } #エラーメッセージ #----------&error($id, "$msg")の形で渡される。$idは数字、$msgはメッセージ sub error{ my ($id,$msg) = @_; my @fmsg; $fmsg[0] = "Backを押して戻ってください"; $fmsg[1] = "管理者に連絡してください"; &unlock; &html_header("お知らせ"); print "

    $msg

    \n"; print "$fmsg[$id]\n"; &html_footer; exit; }