#!/usr/local/bin/perl #---------------------------# # 100の質問回答&表示CGI Ver.0.12 # Script by みさお(http://www.nmt.ne.jp/~misao/) # 2002/4/7作成 2004/3/6最終更新 #---------------------------# #------------初期設定----------------- # 日本語コードjcode.plを呼び出す require 'jcode.pl'; #データファイル名 $questionfile = "100ques.dat"; #質問ファイル $answerfile = "100ans.dat"; #回答ファイル #管理用パスワード $password = "master"; #管理人名 $kanri = "管理人"; #管理人連絡先 $email = "xxx\@xxx.ne.jp"; #ページタイトル $title = "ネットサーファーへの50の質問"; #HOME $home = "index.html"; #BODYタグ $body = ''; $qnum = 50; #質問数 $def=10; #一覧ページに表示する回答者数 $color1 = "#f0f0ff"; #質問の背景色 $color2 = "#ffffff"; #答えの背景色 $howtotaghtml = "howtotag.html"; #タグの使い方説明ページ #CGIスクリプト名 $cgi = "100qa.cgi"; #ロックディレクトリ $lockdir = "100qadir"; #--------初期設定は以上。htmlのわかる人はファイル中程をご覧下さい。 #回答送信後表示されるページおよび回答一覧表示ページに書き加えることができます。 #ファイルの下の方にはスタイルシートを記述する部分があります。 #------------ &decode; &lock_check; &file_lock; &check_input; &questionwrite; &rewrite_datafile; &delete_datafile; &write_datafile; &form_view; &henkou_ok; &thanks_view; &list_view; &answer_view; &ans_view; &ichiran; &rewriteform_view; &question_admin; &unlock; exit; #------------- sub decode{ if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($vn, $value) = split(/=/, $pair); $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; } $flag=0;$adminflag=0; } sub lock_check{ if(-C "$lockdir">0.0004){ &unlock; } } sub file_lock{ $lockflag=0; if (mkdir($lockdir, 0755)) {return;} for ($i = 0; $i <= 5; $i++) { if (mkdir($lockdir, 0755)) { $lockflag=1; last; } else { sleep(1); } } if ($lockflag==0) { if(-e "$lockdir"){ &error(0,"他の方が使用中です。もう少し待ってからお願いします。

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

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

CGIの入っているディレクトリがディレクトリの作成を許可するパーミッションでは
ないのが原因だと思います。ディレクトリのパーミッションを変更してください。"); } } $SIG{'TERM'} = $SIG{'PIPE'} = $SIG{'HUP'} = "sigexit"; sub sigexit { rmdir($lockdir); exit(1); } } sub check_input{ ($FORM{'mode'} eq "touroku") || return; ($FORM{'name'}) || &error(0,"お名前の入力をお願いします。"); ($FORM{'pass'}) || &error(0,"パスワードの入力をお願いします。訂正・削除の際に必要です。"); &getdata_a; &get_username; @answers = split(/\t/,$datas[$#datas]); (($answers[0] eq $FORM{'name'}) && ($username eq $answers[1]) && &solve_pass($FORM{'pass'},$answers[3])) && &error(0,"同じ内容が既に送信されています。"); $pass = &crypt_pass($FORM{'pass'}); $line = "$FORM{'name'}\t$username\t$^T\t$pass"; for($i=0;$i<$qnum;$i++){ $FORM{"q_$i"} = &tagok($FORM{"q_$i"}); $line .="\t$FORM{\"q_$i\"}"; } $line .= "\n"; push(@datas,$line); $flag=1; } sub questionwrite{ ($FORM{'mode'} eq "questionwrite") || return; ($FORM{'pass'} eq $password) || &error(0,"管理用パスワードが違います。"); for($i=0;$i<$qnum;$i++){ $FORM{"$i"} = &tagok($FORM{"$i"}); push(@req,"$FORM{\"$i\"}\n"); } @questions=@req; open (LINES,">$questionfile") || &error(1, "質問ファイルが開けないので、記録できません。"); eval 'flock(LINES,2);'; seek (LINES,0,0); print LINES (@questions); eval 'flock(LINES,8);'; close (LINES); $adminflag=1; } sub rewrite_datafile{ (($FORM{'mode'} eq "henkou")||($FORM{'mode'} eq "delete")) || return; ($FORM{'who'} eq "") && &error(1,"誰の回答を訂正/削除しますか?指定がありません。"); &getdata_a; for ($k=0;$k$answerfile") || &error(1, "記録ファイルが開けないので、記録できません。"); eval 'flock(LINES,2);'; seek (LINES,0,0); print LINES (@datas); eval 'flock(LINES,8);'; close (LINES); } sub form_view{ ($FORM{'mode'} eq "form") || return; &getdata_q; &html_header; print <<"_HTML_";

$title


あなたのお名前:

▼パス可。空欄のままだとパスということになります。

*タグはFONTタグ、強調タグ(B)、打ち消しタグ(S)のみOKです。改行は反映されます。
タグの使い方はコチラ
_HTML_ for($i=0;$i\n"; print "\n"; } print <<"_HTML_";
$j. $questions[$i]
訂正/削除用パスワード

お疲れさまでした〜。
_HTML_ &html_footer; } sub henkou_ok{ (($FORM{'mode'} eq "henkou") || ($FORM{'mode'} eq "delete") || ($FORM{'mode'} eq "del") || ($FORM{'mode'} eq "questionwrite")) || return; &html_header; print "

"; (($FORM{'mode'} eq "henkou") && ($flag==1))&& print "変更完了。"; (($FORM{'mode'} eq "delete") && ($flag==1))&& print "削除完了。"; (($FORM{'mode'} eq "del") && ($flag==1))&& print "削除完了。"; (($FORM{'mode'} eq "questionwrite") && ($adminflag==1)) && print "質問編集完了。"; print "

\n"; &html_footer; } sub thanks_view{ ($FORM{'mode'} eq "touroku") || return; &getdata_q; &html_header; #_HTML_と_HTML_の間の行に、HTML言語で記述した内容が、回答送信後に表示されます。 print <<"_HTML_";

回答ありがとう!

お疲れさまでした〜。大変だったでしょ(^^;)

皆様の回答一覧は↓からどうぞ♪
_HTML_ &list; &html_footer; } sub list_view{ (!$FORM{'mode'} || $FORM{'mode'} eq "list") || return; &getdata_a; &getdata_q; &html_header; #_HTML_と_HTML_の間の行に、HTML言語で記述した内容が表示されます。 print <<"_HTML_";

$title


*回答はパス可です。回答は後から訂正や削除ができます。

  • 質問に答えるとき→回答フォーム

  • 10人ごとの回答一覧→回答一覧
    (ちょっと重いです。)

  • この画面に戻るときは、一番下↓の「個別回答リスト」から。
    _HTML_ &list; &html_footer; } sub list{ $num = scalar(@datas); print "

    皆様の回答リスト

    *それぞれクリックしてください。
    \n"; print "*ご自分の回答を訂正/削除したい場合は、回答者ごとの回答リストから、ご自分の回答を選んでください。
    \n"; print "*現在回答者は$num人です。

    \n"; ($FORM{'pass'} eq $password) && print "*管理者パスワードを使えば、それぞれの回答ページからも訂正/削除ができます。

    \n"; print ""; print "\n"; print "
    回答者ごと質問ごと
      \n"; if ($FORM{'pass'} eq $password || $FORM{'pass'} eq $password){ print "
      \n"; print "\n"; print "\n"; } $i=0; foreach (@datas){ @answerdatas = split("\t",$_); $date = &gettime($answerdatas[2]); print "
    • "; ($FORM{'pass'} eq $password) && print "\n"; print "$answerdatas[0]さんの回答"; ($FORM{'pass'} eq $password) && print "($answerdatas[1])"; print "・・・・・$date
      \n"; $i++; } ($FORM{'pass'} eq $password) && print "\n
    • \n"; print "
      \n"; $i=0; for($i=0;$i$questions[$i]
      \n"; } print "
    \n"; } sub answer_view{ ($FORM{'mode'} eq "answer_view") || return; ($FORM{'who'} eq "") && &error(1,"誰の回答を見たいのか、指定してください。"); &getdata_a; &getdata_q; &html_header; @answerdatas = split("\t",$datas[$FORM{'who'}]); print "

    $answerdatas[0]さんの回答

    \n"; $date = &gettime($answerdatas[2]); print "*→をクリックしたら、その質問の回答一覧が表\示されます。

    \n"; print "回答日時:$date
    "; print "\n"; for($i=0;$i\n"; chomp $answerdatas[$k]; ($answerdatas[$k] eq "") && ($answerdatas[$k]="パス"); print "\n"; } print <<"_HTML_";
    $j. $questions[$i]"; print "  
      $answerdatas[$k]

    訂正/削除用パスワード→
    _HTML_ &html_footer; } sub ans_view{ ($FORM{'mode'} eq "ans") || return; ($FORM{'q'} eq "" || $FORM{'q'} >= $qnum || $FORM{'q'}<0 || $FORM{'q'} =~ /[^0-9]/) && &error(0,"どの質問についてなのか、指定されていません。
    あるいは指定された質問番号が不正です。"); &getdata_a; &getdata_q; $question = $questions[$FORM{'q'}]; &html_header; print "$title\n

    "; print $FORM{'q'}+1; print ". $question

    \n"; print "現在、回答者は";print scalar(@datas);print "人です。

    \n"; print "
    \n"; $i=0; foreach (@datas){ @answers = split(/\t/,$_); $j = $FORM{'q'}+4; print "
  • $answers[0]さんの回答\n"; ($answers[$j] eq "") && ($answers[$j]="パス"); print "
    $answers[$j]

    \n"; $i++; } print "

  • \n"; &html_footer; } sub ichiran{ ($FORM{'mode'} eq "ichiran") || return; &getdata_a; &getdata_q; $start=$FORM{'start'}; ($FORM{'start'} eq "") && ($start = 1); $end = $start+$def-1; ($end>scalar(@datas)) && ($end = scalar(@datas)); &html_header; print "

    $title回答一覧

    \n"; print "($start〜$end人目まで。";print scalar(@datas);print "人中)

    \n"; print "\n"; print "\n"; for ($i=$start-1;$i<$end;$i++){ @answers = split(/\t/,$datas[$i]); print "\n"; } print "\n"; for ($i=0;$i<$qnum;$i++){ $j=$i+1;$l=$i+4; print "\n"; for ($k=$start-1;$k<$end;$k++){ @answers = split(/\t/,$datas[$k]); chomp $answers[$l]; ($answers[$l] eq "") && ($answers[$l]="パス"); print "\n"; } print "\n"; } print "
    No.↓質問/回答者→$answers[0]さん
    $j$questions[$i]$answers[$l]

    \n"; print ""; if ($start>1){ $start = $start-$def;($start<1) && ($start=1); print "\n"; } if ($end
    \n"; print "\n"; print "\n"; print "\n"; print "\n"; } print "
    \n"; print "\n"; print "\n"; print "\n"; print "
    \n"; &html_footer; } sub rewriteform_view{ ($FORM{'mode'} eq "rewrite") || return; ($FORM{'who'} eq "") && &error(1,"誰の回答の訂正をしますか?指定がありません。"); &getdata_a; @answers = split(/\t/,$datas[$FORM{'who'}]); ($FORM{'name'} eq $answers[0]) || &error(1,"名前が違います!"); ((&solve_pass($FORM{'pass'},$answers[3])) || ($FORM{'pass'} eq $password)) || &error(0,"パスワードが違います。"); &getdata_q; $date = &gettime($answers[2]); (($FORM{'pass'} eq $password)) && ($userdata = $answers[1]); &html_header; print <<"_HTML_";

    $answers[0]さんの回答

    $userdata

    訂正は▽

    *タグはFONTタグ、強調タグ(B)、打ち消しタグ(S)のみOKです。改行は反映されます。
    タグの使い方はコチラ

    回答日時:$date

    _HTML_ for($i=0;$i\n"; $answers[$k] =~ s/
    /\n/g; print "\n"; } print "
    $j. $questions[$i]
    \n"; print "
    \n"; print "
    \n"; &html_footer; } sub question_admin{ ($FORM{'mode'} eq "questionadmin") || return; ($FORM{'pass'} eq $password) || &error(0,"管理用パスワードが違います。"); &getdata_q; &html_header; print <<"_HTML_";

    質問編集

    *タグはFONTタグ、強調タグ(B)、打ち消しタグ(S)のみOKです。改行は反映されます。
    タグの使い方はコチラ
    _HTML_ for ($i=0;$i<$qnum;$i++){ chomp $questions[$i]; $j=$i+1; $questions[$i] =~ s/
    /\n/g; print "\n"; } print "
    $j
    \n"; print "\n"; print "
    \n"; &html_footer; } sub unlock{ return rmdir($lockdir); } sub html_header{ print "Content-type: text/html\n\n"; print <<"_HTML_"; $title $body [HOME]
    _HTML_ } sub html_footer{ print <<"_HTML_";

    もどる | 回答フォーム | 個別回答リスト | 回答一覧

    100の質問回答&表\示CGI Ver.0.11 _HTML_ } sub getdata_a{ open (IN,"$answerfile") || &error(1, "回答記録ファイルが開けません。"); @datas = ; close (IN); } sub getdata_q{ open (IN,"$questionfile") || &error(1, "質問ファイルが開けません。"); @questions = ; close (IN); } sub get_username{ $username = $ENV{'REMOTE_USER'}; $host = $ENV{'REMOTE_HOST'}; $add = $ENV{'REMOTE_ADDR'}; ($host eq "" ) && ($host = $add); ($host eq $add) && ($host = ((gethostbyaddr(pack('C4',split(/\./,$add)),2))[0])) || ($host=$add); $username = "$host"; } sub tagok{ #タグを戻す。 local($comment) =@_; $comment =~ s/<b>(.*)<\/b>/$1<\/b>/gi; $comment =~ s/<s>(.*)<\/s>/$1<\/s>/gi; $comment =~ s/<font(.*)>(.*)<\/font>/$2<\/font>/gi; return $comment; } #Password sub crypt_pass{ local($pass) = @_; srand(); $xx = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . "abcdefghijklmnopqrstuvwxyz" . "0123456789./"; $salt = substr($xx, int(rand(64)), 1); $salt .= substr($xx, int(rand(64)), 1); $pass = crypt($pass,$salt); return $pass; } sub solve_pass{ local($pass,$pwd) = @_; #&solve_pass($入力されたパス,$保存されたパス) $salt = substr($pwd,0,2); ($pwd eq crypt($pass,$salt)) && return 1 || return 0; } #秒数を年月日に変換 sub gettime{ local($time) = @_; ($sec,$min,$hour,$dy,$mon,$year,$wday,$yday,$isdst) = gmtime($time+60*60*9); @week = ('日','月','火','水','木','金','土'); $time = sprintf("%04d年%01d月%01d日\($week[$wday]\)%02d:%02d",$year+1900,$mon+1,$dy,$hour,$min); return $time; } sub error{ local ($id,$msg) = @_; $title = "お知らせ"; $fmsg[0] = "Backを押して戻ってください"; $fmsg[1] = "$kanriに連絡してください"; &html_header; print "

    $msg

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