#!/usr/local/bin/perl # ###################################################################### ### ### ### CGI投票システム T-Vote Ver.7.01 ### [1/1] 本体 (tvote.cgi) ### (c) 1996-1999 Takahiro Nishida ### http://www.mytools.net/ ### ### ###################################################################### # ### 変数設定部 (詳細は上記ページをご覧下さい) ###################### $ext = "cgi"; $basedir = "."; $method = "post"; $code = "sjis"; $password = "TVoteV7"; $admin_email = "your\@mail.address"; ### 変数設定部 (ここまで)########################################### require "./jcode.pl"; $verno = '7.01'; $lockfile="$basedir/lockdir/tv7.lock"; print "Content-type: text/html\n\n"; &main; ##### メイン関数 sub main{ &lock; &check_input; &open_datafile; &exec_admin; &check_right; &add_point; &add_datas; &show_html; &update_datafile; &unlock; } ##### 入力のチェック sub check_input{ 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); $FORM{$vn} = &decode($value); } $event = $FORM{'event'}; $item = $FORM{'item2'} || $FORM{'item1'}; $show = $FORM{'show'}; $com = $FORM{'com'}; $pwd = $FORM{'pwd'}; $sid = $FORM{'sid'}; $add = $FORM{'add'}; $act = $FORM{'act'}; ($event =~ /^\w+$/) || &error(4); $user_ip = $ENV{'REMOTE_ADDR'}; $user_host = $ENV{'REMOTE_HOST'} || $user_ip; $time_sec = time(); $new_sid = $time_sec; # 拡大表示の対象(初期値) $insert_point = 0; } ##### データファイルのオープン sub open_datafile{ $datafile = "$basedir/$event.txt"; $tpfile = "$basedir/$event.html"; $logfile = "$basedir/$event.log"; $comfile = "$basedir/$event.com"; $rightfile = "$basedir/$event.rgt"; $admtpfile = "$basedir/tvadmin.tp"; $acomfile = "$basedir/allcom_$event.html"; &openfile($tpfile, *tps); &openfile($datafile, *datas, 1); &openfile($rightfile, *rights, 1); unless($act){ &openfile($logfile, *logs, 1); &openfile($comfile, *coms, 1); } else{ &openfile($admtpfile, *atps); } ### Ver.6 → Ver.7 バージョンアップ用 unless($datas[0] =~ /^\d+\t\d+\t\d+\t/){ unshift(@datas, "1\t20\t0\t10\t10\t-1\t5\t#FFFFFF\t#000000\t#FFCCCC\t#DD0000\t400\t\n"); $upf_data = 1; } ### コンフィグ行の取得 $configline = shift(@datas); ($inew, $icom, $ircom, $ilog, $ishow, $iltime, $ilnum, $nback, $nfont, $eback, $efont, $igraph) = split("\t", $configline); } ########## 管理関数 ここから ########## ##### 管理モードの実行 sub exec_admin{ ($pwd eq $password) || return; ($act) || &error(5, "作業が選択されていません。"); if($FORM{'admitem'}){ $mode = "admitem"; ($act =~ /^d/) && &fix_data; } elsif($FORM{'admcfg'}){ $mode = "admcfg"; ($act eq "fix") && &fix_config; } ($admmsg) || ($admmsg = "$event の管理用フォームを開きました。"); } ##### 項目の修正 sub fix_data{ local($an, $ai, $vn, $i, $bitem, $bvalue); $an = $FORM{'an'}; $ai = $FORM{'ai'}; $vn = $FORM{'vn'}; ($act eq 'ddel') || ($vn =~ /^\d+$/) || (&error(5, "票数が不正です。")); # 新規だったら入力項目を有効に ($act eq 'dnew') && (($ai = $an) || &error(5, "新規項目が記述されていません。")); # 重複チェック push(@datas, "$ai\t-1"); # ダミー行 for (0..$#datas){ ($bitem, $bvalue) = split("\t", $datas[$_]); if($bitem eq $ai){ $i = $_; last; } } # 削除 if($act eq 'ddel' || $act eq 'dfix'){ ($i < $#datas) || &error(5, "指定された項目は存在しません。"); splice(@datas, $i, 1); $admmsg = "$event の項目 $ai を削除しました。"; } # 追加 if($act eq 'dfix' || $act eq 'dnew'){ for (0..$#datas){ ($bitem, $bvalue) = split("\t", $datas[$_]); if($bvalue < $vn){ splice(@datas, $_, 0, "$ai\t$vn\t\n"); last; } } $admmsg = "$event の項目 $ai を $vn 票に修正しました。"; } pop(@datas); # 新規のチェック if($act eq 'dnew'){ ($i == $#datas) || &error(5, "指定された項目は既に存在しています。$i, $#datas"); $admmsg = "$event の項目 $ai を $vn 票で新規追加しました。"; } $upf_data = 1; } ##### 設定の変更 sub fix_config{ # 制限時間のみあらかじめ値を取得 $piltime = $iltime; ### 入力の受け取り $inew = $FORM{'fnew'}; $icom = $FORM{'fcom'}; $ircom = $FORM{'frcom'}; $ilog = $FORM{'flog'}; $ishow = $FORM{'fshow'}; $iltime = $FORM{'fltime'}; $ilnum = $FORM{'flnum'}; $nback = $FORM{'fnback'}; $nfont = $FORM{'fnfont'}; $eback = $FORM{'feback'}; $efont = $FORM{'fefont'}; $igraph = $FORM{'fgraph'}; ### 妥当性チェック ($inew =~ /^[01]$/) || &error(5, "【項目追加】 の値が不正です。($inew)"); ($icom =~ /^\d+$/) || &error(5, "【コメント表\示】 の値が不正です。($icom)"); ($ircom =~ /^\d+$/) || &error(5, "【コメント保存】 の値が不正です。($ircom)"); ($ilog =~ /^\d+$/) || &error(5, "【ログ表\示】 の値が不正です。($ilog)"); ($ishow > 0) || &error(5, "【初期表\示】 の値が不正です。($ishow)"); ($iltime =~ /^-?\d+(\.\d+)?$/) || &error(5, "【投票制限】 の値が不正です。($iltime)"); ($ilnum =~ /^\d+$/) || &error(5, "【投票制限】 の値が不正です。($ilnum)"); ($igraph =~ /^\d+$/) || &error(5, "【グラフ】 の値が不正です。($igraph)"); ### 標準の配色に戻す if($FORM{'initcolor'}){ $nback = "#FFFFFF"; $nfont = "#000000"; $eback = "#FFCCCC"; $efont = "#DD0000"; } ### コメント全保存ファイルのクリア ($FORM{'clearallcom'}) && &updatefile($acomfile); ### 制限時間が変わっていたら権利ファイルを初期化 ($piltime == $iltime) || ($rights[0] = 0); $configline = "$inew\t$icom\t$ircom\t$ilog\t$ishow\t$iltime\t$ilnum\t$nback\t$nfont\t$eback\t$efont\t$igraph\t\n"; $upf_data = 1; $admmsg = "$event の設定を変更しました。($piltime, $iltime)"; } ########## 管理関数 ここまで ########## ##### 権利のチェック sub check_right{ ### 無制限なら無視 ($iltime < 0) && return; chop($rights[0]); # 改行を切り落とす # 初期化(一番近い0時) $rtime = ($rights[0]) || ($time_sec - ($time_sec + 32400) % 86400); # 一生でないなら時間のチェック if(($iltime > 0) && ($rtime < $time_sec)){ while($rtime < $time_sec){ $rtime += 3600 * $iltime; } $rights[0] = $rtime . "\n"; $#rights = 0; $upf_right = 1; } # 投票済み項目 foreach (@rights){ (/$user_ip\t/) && push(@uright, $_); } # 残り権利数 $vrlest = $ilnum - @uright; # 投票があった場合、権利のチェック if($item && $add){ (--$vrlest >= 0) || &error(6); push(@rights, "$user_ip\t$item\t\n"); push(@uright, "$user_ip\t$item\t\n"); $rights[0] = $rtime . "\n"; $upf_right = 1; } } ##### 票数を加える sub add_point{ ($item && $add) || return; local($i, $bitem, $bvalue, $value_of_point); $value_of_point = (split("\t",$datas[0]))[1]; $i = 0; push(@datas, "$item\t0\t\n"); # ダミー行 foreach (@datas){ ($bitem, $bvalue) = split("\t"); if($value_of_point > $bvalue){ $insert_point = $i; # 票の変わり目の場所と票数を記録 $value_of_point = $bvalue; } if($bitem eq $item){ splice(@datas, $i, 1); $bvalue++; ($bvalue < $value_of_point) && ($insert_point = $i); # 追いつかなかったら同じ場所 splice(@datas, $insert_point, 0, "$bitem\t$bvalue\t\n"); last; } $i++; } # 新しい項目だった場合 if($i == $#datas){ ($inew) || &error(7); $flag_new = 1; } else{ pop(@datas); # ダミー行の削除 } $upf_data = 1; } ##### 票数以外のデータの書換 sub add_datas{ ($item && $add) || return; local($date, $newline, $bnew); $date = &get_time($time_sec); ### ログ ($flag_new) && ($bnew .= "[NEW]"); $newline = "
  • $date $item ($user_host) $bnew \n"; unshift(@logs, $newline); (@logs <= $ilog) || ($#logs = $ilog - 1); $upf_log = 1; ### コメント if($icom && $com){ $newline = "
  • $date $item ($user_host)
    ...$com\n"; ($coms[0] =~ /--$sid--/) && &error(9); # 連続コメント防止 unshift(@coms, $newline); (@coms <= $icom) || ($#coms = $icom - 1); $upf_com = 1; # 全コメント保存の場合(ちょっと処理が汚い。。。) ($ircom) && &updatefile($acomfile, "", $newline, 1); } } ##### ファイルの更新 sub update_datafile{ unshift(@datas, $configline); # コンフィグ行を戻す ($upf_data) && &updatefile($datafile, *datas); ($upf_log) && &updatefile($logfile, *logs); ($upf_com) && &updatefile($comfile, *coms); ($upf_right) && &updatefile($rightfile, *rights); } #################### HTML表示関数 ここから #################### ##### メイン sub show_html{ local($htmlbuf); ### 選択項目(管理でも使用する) foreach (@datas){ ($bitem, $bvalue) = split("\t"); $bsel = ($bitem eq $item) ? "SELECTED" : ""; $html_select_options .= "