#! c:/perl/bin/perl # # attlist.cgi # # Ver3.014 : 10/4/05 : cyrptを修正 # Ver3.013 : 10/2/05 : Copyrightにリンクを追加 # Ver3.012 : 9/3/05 : jcode.plを削除 # Ver3.011 : 7/25/05 # 選択項目から初期状態をなくすオプション追加 # Ver3.01 : 8/28/03 # セットアップで間違った戻りURLを指定した場合のエラー処理を追加 # Ver3.0 : 4/28/03 # attendlist.plとwrattend.plを一つに統合 # パスワード機能追加 # attendhyperの機能(参加者カウント)も追加 # # $Id: attlist.cgi,v 1.9 2005/10/04 06:23:03 Hideki Kanayama Exp $ $version = "3.014"; $lastmodifiedyear = "2005"; $admindat = "adminpwd.dat"; $setupfile = "attend_setup.pl"; $thisfile = $0; $thisfile =~ s/^.+[\/\\]([^\\\/]+)$/$1/; $lang = 0; ########## 環境設定 ここから ########################### $cgibin = "../cgi-bin"; $script = "$cgibin/$thisfile"; $event = "../attendlist"; $datafile = "$event/attend.dat"; $eventhtml = "$event/event.shtml"; $attendees = "$event/attendees.lst"; #表示テーブルのカラム数 $table_colms = 2; #参加者設定の初期登録可能人数 $default_max = 30; #管理用リンク表示 1:有効 0:無効 $setup_en = 1; #変更日表示 1:有効 0:無効 $update_en = 0; #パスワード保護 1:有効 0:無効 $password_en = 0; #参加人数 1:有効 0:無効 $family_en = 0; #初期状態 1:あり 0:なし $init_state_en = 0; #時間設定 $offset = 9; #トップからのSSI表示による更新時間のための予備のアップデートファイル # 1: on, 0: off $update1_file_en = 0; $update2_file_en = 0; $update1_file = "$event/update1.log"; $update2_file = "$event/update2.log"; ########## 環境設定 ここまで ########################### if ($ENV{"REQUEST_METHOD"} eq "GET"){ $data=$ENV{"QUERY_STRING"}; $method = 'GET'; } elsif ($ENV{"REQUEST_METHOD"} eq "POST"){ read(STDIN,$data,$ENV{"CONTENT_LENGTH"}); $method = 'POST' } @tmparry=split(/&/,$data); foreach $string (@tmparry){ ($key,$value)=split(/=/,$string); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s//>/g; if ($value =~ /\r\n/) { $value =~ s/\r\n/
/g; } if ($value =~ /\n/) { $value =~ s/\n/
/g; } if ($value =~ /\r/) { $value =~ s/\r/
/g; } if ($value =~ /,/) { $value =~ s/,/,/g; } $all{"$key"}=$value; } if ($all{id} eq ''){ $id = 1; } else { $id = $all{id}; } $idsetupfile = "$id-$setupfile"; if (-e "$idsetupfile") { require "$idsetupfile"; } $tmpfile = "$event/tmp.$$"; if (! -e "$admindat"){ if ($all{mode} ne 'adminpwd'){ &setadminpwd; } else { &wradminpwd; print "Location: $eventhtml\n\n"; } } open(ADMIN,"< $admindat"); $adminpwd = ; close(ADMIN); if ($all{mode} eq 'atwrite'){ &atwrite; } elsif ($all{mode} eq 'setup'){ &setup; } elsif ($all{mode} eq 'wrsetup'){ &wrsetup; } elsif ($all{mode} eq 'wrattendees'){ &wrattendees; } else { &display; } ###################### 書き込み ############################ sub atwrite { if ($all{name} eq ""){ &error('名前は必ず入れてください'); } ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=gmtime(time + 3600 * $offset); $update = sprintf("%s_%s_%s_%02s_%02s",$year+1900,$mon+1,$mday,$hour,$min); $datafile = &datafilegen; $attendeefile = &attendeefilegen; open(ATTENDEE,"< $attendeefile") || &error("$attendeefileが開けません"); @attendees = ; close(ATTENDEE); if (open(ATTEND,"< $datafile")) { foreach (){ chop; ($key,$name,$value,$family,$moddate,$pwd)=split(/,/); if ($key == 0){ $date = $moddate;; $lastname = $name; } else { $name[$key] = "$name"; $status[$key] = "$value"; $family[$key] = "$family"; $eachpwd[$key] = "$pwd"; $eachmod[$key] = "$moddate"; } } close(ATTEND); } open(WRDAT,">$tmpfile"); print WRDAT "0,$all{name},$update,\n"; $endatt = $#attendees + 1; for ($i=1;$i<=$endatt;$i=$i+1){ $pwdi = "pwd_$i"; $attendees[$i-1] =~ s/[\n\r]*$//; # instead of a chop if ($all{$i} ne $status[$i]) { $eachmod[$i] = "$update"; if ($password_en == 1 && !("$eachpwd[$i]" eq '' || &checkcrypt("$all{$pwdi}","$adminpwd") || &checkcrypt("$all{$pwdi}","$eachpwd[$i]"))) { close(WRDAT); unlink("$tmpfile"); &error("$name[$i]のパスワードが違います。"); } } if ($password_en == 1 && ("$all{$pwdi}" ne '' && "$eachpwd[$i]" eq '')){ $eachpwd[$i] = &makecrypt("$all{$pwdi}"); } print WRDAT "$i,$attendees[$i-1],$all{$i},$all{\"family_$i\"},$eachmod[$i],$eachpwd[$i]\n"; } close(WRDAT); rename("$tmpfile","$datafile"); chmod(0666,"$datafile"); if ($update1_file_en == 1){ open(UPDATE,">$update1_file"); print UPDATE "dummy file1\n"; close(UPDATE); chmod(0666,"$update1_file"); } if ($update2_file_en == 1){ open(UPDATE,">$update2_file"); print UPDATE "dummy file2\n"; close(UPDATE); chmod(0666,"$update2_file"); } print "Location: $eventhtml#$id\n\n"; } ###################### 表示 ############################ sub display { print "Content-Type: text/html\n\n"; $datafile = &datafilegen; if (open(ATTEND,"< $datafile")) { foreach (){ chop; ($key,$name,$value,$family,$moddate,$pwd)=split(/,/); if ($key == 0){ $date = $value;; $lastname = $name; } else { $name[$key] = "$name"; $status[$key] = "$value"; $family[$key] = "$family"; $eachpwd[$key] = "$pwd"; $eachmod[$key] = "$moddate"; } } close(ATTEND); } $attendees = &attendeefilegen; if (open(ATTENDEE,"< $attendees")){ @attendees_list = ; } #print ""; #print ""; print "\n"; print "
\n"; print "\n"; print "\n"; if ($date =~ /(\d+)_(\d+)_(\d+)_(\d+)_(\d+)/) { $modyear = $1; $modmon = $2; $modday = $3; $modhour = $4; $modmin = $5; $date = sprintf("%s年%s月%s日%s時%s分",$1,$2,$3,$4,$5); } else { $date = " "; } print "

最終更新者は "; print "$lastname"; print "、最終更新日は "; print "$dateです"; print <更新者のお名前:

 ←決定ボタンはここ FINISH_1 $select_items = 4 + $init_state_en + $update_en + $family_en + $password_en; $cols = $table_colms * $select_items; print "\n"; print "\n"; for ($i=1;$i<=$table_colms;$i=$i+1){ print "\n"; print "\n"; print "\n"; print "\n"; print "\n" if ($init_state_en == 1); print "\n" if ($family_en == 1); print "\n" if ($update_en == 1); print "\n" if ($password_en == 1); } print "\n"; $i = 1; while ($#attendees_list >= 0){ print "\n"; for ($j=1;$j<=$table_colms;$j=$j+1){ if ($#attendees_list < 0) { for ($h=0;$h<$select_items;$h=$h+1){ print "\n"; } last; } $person = $attendees_list[0]; $chkatt=""; $chkabt=""; $chktbd=""; $chkdef=""; if ("$status[$i]" eq attend){ $chkatt="CHECKED"; $chkabt=""; $chktbd=""; $chkdef=""; if ($family[$i] < 1){ $family[$i]=1; }; } elsif ($status[$i] eq absent){ $chkat=""; $chkabt="CHECKED"; $chktbd=""; $chkdef=""; $family[$i]=0; } elsif ($status[$i] eq tbd){ $chkatt=""; $chkabt=""; $chktbd="CHECKED"; $chkdef=""; $family[$i]=0; } elsif ($status[$i] eq default){ $chkatt=""; $chkabt=""; $chktbd=""; $chkdef="CHECKED"; $family[$i]=0; } else { $chkatt=""; $chkabt=""; $chktbd=""; $chkdef=""; $family[$i]=0; } print "\n"; if ($chkatt eq CHECKED){ print "\n"; if ($chkabt eq CHECKED){ print "\n"; if ($chktbd eq CHECKED){ print "\n"; if ($init_state_en == 1){ if ($chkdef eq CHECKED){ print "\n"; } if ($family_en == 1){ print "\n"; } if ($update_en == 1){ print "\n"; } if ($password_en == 1){ print "\n"; } else { print "\n"; } $totalattend = $totalattend + $family[$i]; shift(@attendees_list); $i = $i + 1; } print "\n"; } if ($family_en == 1){ $rightcolspan = $update_en + $family_en + $password_en; $leftcolspan = $cols - $rightcolspan; print ""; print ""; print ""; print "\n"; } print "
名前出席欠席未定初期
状態
参加
人数
更新日パスワード
 "; chomp($person); print "$person"; print ""; } else { print ""; } print ""; } else { print ""; } print ""; } else { print ""; } print ""; } else { print ""; } print ""; print ""; print ""; if ($eachmod[$i] =~ /(\d+)_(\d+)_(\d+)_(\d+)_(\d+)/) { $modyear = $1; $modmon = $2; $modday = $3; $modhour = $4; $modmin = $5; print "$2/$3/$1"; } else { print " "; } print ""; print ""; print "
"; print "参加合計"; print "$totalattend 人
\n"; if ($password_en == 1){ print "パスワードをブランクで登録すると誰でも変更できるようになります。ブランク以外の時だけ保護されます。
\n"; } if ($setup_en == 1){ print "管理用
\n"; } print "

"; $year = $lastmodifiedyear; if ($year > 1997){ $year = "1997-$year"; } $mysite = ('http://www.hidekik.com/','http://www.hidekik.com/en/')[$lang]; print "$thisfile Ver. $version
Copyright(C) $year, hidekik.com
\n"; #print ""; #print ""; } ###################### セットアップ ############################ sub setup { if ($all{pwd} eq ''){ &enterpwd; } if (! &checkcrypt($all{pwd},$adminpwd)){ &error('パスワードが違います。'); } print "Content-type:text/html\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "セットアップ\n"; print "\n"; print "\n"; print "

Setup for ID=$id

\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; $table_colms_check[$table_colms] = "checked"; $setup_check[$setup_en] = "checked"; $update_check[$update_en] = "checked"; $password_check[$password_en] = "checked"; $family_check[$family_en] = "checked"; $update1_file_check[$update1_file_en] = "checked"; $update2_file_check[$update2_file_en] = "checked"; $init_state_check[$init_state_en] = "checked"; print <
  • ディレクトリ、ファイルの設定は、$eventから見た相対パス、又は絶対パスで指定してください。CGIと同じディレクトリの場合、.(半角ドット)でOKです。バックグランドファイルやロゴファイルはhttp://からのリンクの指定も可能\\です。
  • 管理人パスワードを変更するには、$admindatを削除して、$scriptを実行しなおしてパスワードを再入力してください。
  • これらの設定は$idsetupfileに保存されます。また、$idsetupfileをエディタ等で変更してもこの設定ページに反映されます。
  • $scriptがバージョンアップされた場合、単純に$scriptだけを置き換えるだけで設定はそのまま使えます。
  • $admindatと$idsetupfileのファイル名はこの設定ページでは変更できません。変更したい場合は$scriptの中で変更してください。
  • 管理用リンクを非表\\示にしている場合にこのページにアクセスするには、$script?mode=setup&id=$idを実行するとアクセスできます。
  • 数字やカラー指定は必ず半角で指定してください。全角やブランクだとCGIが起動しなくなります。万一間違って全角で書いてしまった場合は、$idsetupfileをエディタで開きその場所を半角に正しく修正してください。それで直ります。
CGIディレクトリ CGIを置くディレクトリ(データと同じでも可)
データディレクトリ CGIと同じでも可
データファイル ファイル名は<dir>/<id>-<filename>に自動的に変換されます
CGIを呼び出す.shtmlファイル
出席者登録ファイル ファイル名は<dir>/<id>-<filename>に自動的に変換されます
参加者設定の初期登録可能\\人数
表\\示テーブルのカラム数
管理用リンク表\\示 表\\示 非表\\示
初期状態項目 あり なし
変更時間表\\示 表\\示 非表\\示
参加人数 有効 無効
パスワード保護 有効 無効
時間設定 GMTより時間(日本:+9時間)
予\\備のアップデートファイル 使用 非使用 ファイル名
使用 非使用 ファイル名
END_SETUP print ""; print "
\n"; # 参加者設定 $attendees = &attendeefilegen; if (open(ATTENDEE,"< $attendees")){ @attendees_list = ; } print "

参加者設定


\n"; print "
    \n"; print "
  • 出欠表\\に表\\示する人の名前を各テキストフォームに一人ずつ入力してください。
  • \n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; $i = 1; while (@attendees_list){ $_=shift(@attendees_list); print "\n"; print "\n"; $i = $i + 1; if ($table_colms == 2){ $_=shift(@attendees_list); print "\n"; $i = $i + 1; } print "\n"; } $extra_attendees = 3; if ($i < $default_max - $extra_attendees){ $extra_max = $default_max; } else { $extra_max = $i + $extra_attendees; } for ($j=$i;$j<=$extra_max;$j=$j+1){ print "\n"; print "\n"; $i = $i + 1; if ($table_colms == 2){ $_=shift(@attendees_list); print "\n"; $i = $i + 1; $j = $j + 1; } } print "\n"; print "
\n"; print ""; print "
\n"; print "\n"; } ###################### セットアップ作成 ############################ sub wrsetup { if (! &checkcrypt($all{pwd},$adminpwd)){ &error('パスワードが違います。'); } if (! -e "$all{eventhtml}"){ &error("CGIを呼び出す.shtmlファイル名が正しくありません。
ここをクリックしてセットアップから入力しなおしてください。"); } open(SETUP,"> $idsetupfile") || &error('セットアップファイルが作成できません。
CGIを置いてあるディレクトリが書き込み可能\\か確認してください。'); print SETUP < $attendees") || error('$attendeesを作成できません。'); for ($i=1;$i<=$default_max+3;$i=$i+1){ $attname = attname . $i; if ($all{$attname} ne ''){ print FILE "$all{$attname}\n"; } } close(FILE); print "Location: $eventhtml#$id\n\n"; } ###################### クリプト ############################ sub makecrypt { my $plain = shift; my $salt = join "", ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]; my $result = crypt($plain,$salt) or crypt($plain,'$1$'.$salt.'$'); return $result; } sub setadminpwd { print "Content-type:text/html\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "管理者用パスワード設定\n"; print "\n"; print ""; print "
"; print "
管理者用パスワードを設定してください。
"; print ""; print ""; print ""; print "
"; print ""; exit; } sub wradminpwd { $passwd = &makecrypt($all{pwd}); if (open(FILE,"> $admindat")) { print FILE "$passwd"; close(FILE); } else { print "Content-type:text/html\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "パスワードファイル作成に失敗しました\n"; print "\n"; print "\n"; print "パスワードファイル作成に失敗しました。$scriptがあるディレクトリのパーミッションが書き込み可能\\になっているか確認してください。"; print "\n"; exit; } } sub checkcrypt { my ($pwd,$encpwd)=@_; return(crypt($pwd,$encpwd) eq "$encpwd"); } ################ セットアップ用パスワード入力 ####################### sub enterpwd { print "Content-type:text/html\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "管理者用パスワード入力\n"; print "\n"; print "\n"; print "
\n"; print "
管理者用パスワードを入力してください。
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "\n"; exit; } sub error { print "Content-Type: text/html\n\n"; print ""; print ""; print "\n"; print "\n"; print ""; print ""; print "
$_[0]
\n"; print ""; print ""; exit; } sub attendeefilegen { $origfile = $attendees; if ($origfile =~ /[\\\/]/){ $origfile =~ /^(.*)[\\\/]([^\\\/]+)$/; $attendeedir = $1; $attendees = $2; } else { $attendeedir = "."; $attendees = "$origfile"; } $attendees = "$attendeedir/${id}-$attendees"; return ($attendees); } sub datafilegen { $origfile = $datafile; if ($origfile =~ /[\\\/]/){ $origfile =~ /^(.*)[\\\/]([^\\\/]+)$/; $datadir = $1; $datafile = $2; } else { $datadir = "."; $datafile = "$origfile"; } $datafile = "$datadir/${id}-$datafile"; return ($datafile); }