#! /usr/bin/perl # # 履歴記録CGI # # 1.010 : 8/14/07 : タグ処理を修正 # 1.009 : 5/10/07 : 0から始まる日付を修正。時刻を修正。 # 1.008 : 5/5/07 : 1970年以前を指定できないように修正。 # 1.007 : 6/13/06 : タグの処理を修正 # 1.006 : 11/27/05 : 削除方法を修正 # 1.005 : 11/26/05 : 管理人パスワードで削除できないバグを修正 # 1.004 : 10/2/05 : methodをpostに修正 # 1.003 : 10/1/05 : 更新時間表示を修正 # 1.002 : 9/4/05 : 表示に日、月の表示非表示オプションを追加 # 1.001 : 8/28/05 : ロックを修正 # 1.0 : 8/26/05 : Created # # $Id: historys.cgi,v 1.21 2007/08/14 06:34:50 Hideki Kanayama Exp $ # Copyright(c) 2005-2007, Hideki Kanayama, All rights reserved. use strict; use CGI qw(:cgi-lib); use CGI::Carp qw(fatalsToBrowser); use File::Basename; use Time::Local; our ($datafile, $title, $bgimage_en, $bgimage_file, $bgcolor, $order, $body_width, $body_head, $body_tail, $user_mode, $style_sheet_en, $style_sheet, $head_insert_en, $head_insert, $offset, $backlink_en, $backlink, $backlink_name, $deltitle, $date_disp, ); my $adminpwd = "adminpwd.dat"; my $setupfile = "hist_setup.pl"; my $version = "1.010"; my $lastupdatedyear = "2007"; my $script = basename($0); my $charset = "Shift_JIS"; # Language 0:Japanese 1:English my $lang = 0; ### デフォルト設定 ### # data file $datafile = 'history.dat'; # Title $title = 'ヒストリー'; # Delete page title $deltitle = 'ヒストリー削除'; # Background $bgimage_en = 0; $bgimage_file = ''; $bgcolor = "#ffffff"; # Back link $backlink_en = 1; $backlink = '..'; $backlink_name = '戻る'; # Body width $body_width = '80'; # Display order 0:From new, 1:From old $order = 0; # Date display 0:年月日 1:年月のみ 2:年のみ $date_disp = 0; # body_head $body_head = "

$title

"; # body_tail $body_tail = ' '; # mode 0:admin only, 1:user mode $user_mode = 0; # Style Sheet $style_sheet_en = 0; $style_sheet = ' '; # Head insert $head_insert_en = 0; $head_insert = ' '; # Offset from GMT, Japan:+9 $offset = 9; ####################### require $setupfile if (-e "$setupfile"); my $LOCK_EX = 2; my $now = time + $offset*3600; my $q = new CGI; my $cgierror = $q->cgi_error; &error($cgierror) if ($cgierror); my $mode = $q->param('mode'); if (! -e "$adminpwd"){ if ($mode eq 'wradminpwd'){ &wradminpwd; } else { &setadminpwd; } } if ($mode eq 'write'){ &histwrite; } elsif ($mode eq 'delpage'){ &delpage; } elsif ($mode eq 'delete'){ &histdelete; } elsif ($mode eq 'setup'){ &setup; } elsif ($mode eq 'setupwrite'){ &setupwrite; } else { &display; } sub display { my $histdata = &getdata; my @regtime = keys %{$histdata}; @regtime = sort {$a <=> $b} @regtime; @regtime = reverse @regtime if ($order == 0); &htmlhead($title); print "$body_head\n"; my ($d_dev,$d_ino,$d_mode,$d_nlink,$d_uid,$d_gid,$d_rdev,$d_size,$d_atime,$d_mtime,$d_ctime,$d_blksize,$d_blocks)=stat("$datafile"); my ($ssec,$smin,$shour,$sday,$smon,$syear,$swday,$syday,$sisdst)=gmtime($d_mtime+$offset*3600); $syear += 1900 if ($syear < 1900); $smon++; print "

\n"; print "$backlink_name
\n" if ($backlink_en); print "${syear}年${smon}月${sday}日更新\n"; print "

\n"; print "\n"; # ($id,$dyear,$dmonth,$dday,$dhour,$dmin,$dtime,$dnow,$dpwd,$host,$ip,$dcomment); foreach (@regtime){ print "\n"; print "\n"; print "\n"; print "\n"; } print "
"; print "$histdata->{$_}[1]年"; print "$histdata->{$_}[2]月" if ($date_disp == 0 or $date_disp == 1); print "$histdata->{$_}[3]日" if ($date_disp == 0); print ""; print "$histdata->{$_}[11]"; print "

\n"; my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=gmtime($now); $mon++; $year += 1900 if ($year < 1900); print "\n"; print "\n"; print "
"; print "
\n"; print "年"; print "月"; print "
\n"; print "内容

\n"; print "パスワード
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
"; print "削除ページ"; print "管理用
\n"; print "$body_tail\n"; &htmltail; } sub delpage { my $histdata = &getdeldata; my @regtime = @{$histdata}; @regtime = sort {$a->[6] <=> $b->[6] or $a->[0] <=> $b->[0]} @regtime; @regtime = reverse @regtime if ($order == 0); &htmlhead($deltitle); print "

$deltitle

\n"; my ($d_dev,$d_ino,$d_mode,$d_nlink,$d_uid,$d_gid,$d_rdev,$d_size,$d_atime,$d_mtime,$d_ctime,$d_blksize,$d_blocks)=stat("$datafile"); my ($ssec,$smin,$shour,$sday,$smon,$syear,$swday,$syday,$sisdst)=gmtime($d_mtime+$offset*3600); $syear += 1900 if ($syear < 1900); $smon++; print "
\n"; print "${title}へ
\n"; print "

\n"; print "

\n"; print "\n"; # ($id,$dyear,$dmonth,$dday,$dhour,$dmin,$dtime,$dnow,$dpwd,$host,$ip,$dcomment); foreach my $refkey (@regtime){ print "\n"; print "\n"; print "\n"; print ""; print ""; print "\n"; } print "
"; print "$refkey->[1]年"; print "$refkey->[2]月"; print "$refkey->[3]日"; print ""; print "$refkey->[11]"; print ""; print "[0] size=10>\n"; print ""; print "[0] value=\"削除\">\n"; print "

\n"; print "削除したい行のテキストボックスににパスワードを入れて削除ボタンをクリックしてください。"; print "\n"; print "

\n"; &htmltail; } sub histdelete { my ($fid,$fyear,$fmonth,$fday,$fhour,$fmin,$ftime,$fnow,$fpwd,$fhost,$fip,$fcomment); my @tmparray = (); open (DATAFILE, "+< $datafile") or &error("${datafile}が開けません。"); flock DATAFILE, $LOCK_EX; while (){ chomp; ($fid,$fyear,$fmonth,$fday,$fhour,$fmin,$ftime,$fnow,$fpwd,$fhost,$fip,$fcomment) = split /,/; my $subname = 'sub_' . $fid; my $pwdname = 'pwd_' . $fid; my $inpwd = $q->param($pwdname); if (!$q->param($subname)) { push @tmparray, "$fid,$fyear,$fmonth,$fday,$fhour,$fmin,$ftime,$now,$fpwd,$fhost,$fip,$fcomment\n"; } elsif (! &checkcrypt($inpwd,$fpwd)) { close(DATAFILE); &error('パスワードが違います。'); } } truncate DATAFILE, 0; seek DATAFILE, 0, 0; print DATAFILE @tmparray; close(DATAFILE); print "Location: $script\n\n"; } sub histwrite { my $year = sprintf("%d",$q->param('year')); my $month = sprintf("%d",$q->param('month')); my $day = sprintf("%d",$q->param('day')); my $hour = 0; my $min = 0; my $comment = $q->param('comment'); my $pwd = $q->param('pwd'); my $id; my $regtime; my $host; my $ip; my $encpwd; # $comment =~ s//>/g; $comment =~ s/,/,/g; $comment =~ s/\r\n/
/g; $comment =~ s/\r/
/g; $comment =~ s/\n/
/g; $comment =~ s/<( *\/? *t)/<$1/ig; # Do not allow table tag $comment =~ s/<( *plaintext)/<$1/ig; $comment =~ s/<( *script)/<$1/ig; $comment =~ s/<( *input)/<$1/ig; $comment =~ s/<( *pre)/<$1/ig; $host = $ENV{'REMOTE_HOST'}; $ip = $ENV{'REMOTE_ADDR'}; my $monthn1 = $month-1; &monthdaycheck($year,$monthn1,$day); $regtime = timegm(0,$min,$hour,$day,$monthn1,$year); $encpwd = &makecrypt($pwd); &error('管理人オンリーモードなので管理人しか書き込めません。') if ($user_mode == 0 and !&checkadmin($pwd)); &error('パスワードが違います。') if ($user_mode == 1 and !&checkcrypt($pwd,$encpwd)); if (open DATA, "< $datafile"){ while (){ my @dummy; ($id,@dummy) = split /,/; } close DATA; $id++; } else { $id = 1; } open (FILE, ">> $datafile") or &error("${datafile}が開けません。"); # ($id,$dyear,$dmonth,$dday,$dhour,$dmin,$dtime,$dnow,$dpwd,$host,$ip,$dcomment); flock FILE, $LOCK_EX; print FILE "$id,$year,$month,$day,$hour,$min,$regtime,$now,$encpwd,$host,$ip,$comment\n"; close(FILE); print "Location: $script\n\n"; } sub getdata { my %histdata; my @dataarray; my $id; my $host; my $ip; my $id; if (open DATA, "< $datafile"){ while (){ chomp; # ($id,$dyear,$dmonth,$dday,$dhour,$dmin,$dtime,$dnow,$dpwd,$host,$ip,$dcomment); @dataarray = split /,/; next if ($dataarray[11] eq ''); my $key = "$dataarray[6]"; my @dummy; (@dummy) = gmtime($key) unless ($date_disp == 0); if ($date_disp == 1) { $key = timegm(0,0,0,1,$dummy[4],$dummy[5]); } elsif ($date_disp == 2){ $key = timegm(0,0,0,1,0,$dummy[5]); } if (exists $histdata{$key}){ $histdata{$key} = [ @dataarray[0 .. $#dataarray-1], $histdata{$key}->[$#dataarray] . "
" . $dataarray[11], ]; } else { $histdata{$key} = [@dataarray]; } } close DATA; return (\%histdata); } } sub getdeldata { my @histdata; my @dataarray; if (open DATA, "< $datafile"){ @histdata = (); while (){ chomp; # ($id,$dyear,$dmonth,$dday,$dhour,$dmin,$dtime,$dnow,$dpwd,$host,$ip,$dcomment); @dataarray = split /,/; next if ($dataarray[11] eq ''); push(@histdata, [@dataarray]); } close DATA; return (\@histdata); } } sub htmlhead { my $title = shift; my $bgimage; if ($bgimage_en == 1){ $bgimage = "background=\"$bgimage_file\""; } else { $bgimage = "bgcolor=\"$bgcolor\""; } # print "Content-type:text/html\n\n"; print $q->header(-charset=>"$charset"); print "\n"; print "\n"; print "$title\n"; if ($head_insert_en == 1){ print "$head_insert\n"; } if ($style_sheet_en == 1){ print "\n"; } print "\n"; print "\n"; print "
\n"; } sub htmltail { my $mysite = ('http://www.hidekik.com/','http://www.hidekik.com/en/')[$lang]; print "
historys.cgi Ver. $version
\n"; print "
Copyright(C) 2005-$lastupdatedyear, hidekik.com
\n"; print "
\n"; exit; } 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 checkcrypt { my ($pwd,$encpwd)=@_; return(crypt($pwd,$encpwd) eq "$encpwd" or &checkadmin($pwd)); } sub checkadmin { my $pwd = shift; if (open(FILE,"< $adminpwd")){ my $filepwd = ; close(FILE); my $inpwd = crypt($pwd,$filepwd); return ("$inpwd" eq "$filepwd"); } else { &error('パスワードファイルが存在しません'); } } sub setadminpwd { &htmlhead('管理者用パスワードを入力してください'); print "
\n"; if ($mode eq 'setup'){ print "
管理者用パスワードを入力してください。
\n"; print "\n"; print "\n"; print "\n"; } else { print "
管理者用パスワードを設定してください。
\n"; print "\n"; print "\n"; print "\n"; } &htmltail; } sub wradminpwd { my $plain = $q->param('pwd'); my $passwd = &makecrypt($plain); if (open(FILE,"> $adminpwd")){ print FILE "$passwd"; close(FILE); } else { &error('パスワードファイル作成に失敗しました'); } print "Location: $script\n\n"; } sub error { my ($msg) = shift; &htmlhead($msg); print "
$msg
\n"; &htmltail; exit; } sub monthdaycheck { my ($year,$month,$day) = @_; my @monthdays = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); my $md = $monthdays[$month]; ++$md unless $month != 1 or $year % 4 or !($year % 400); $month++; &error("日付が適切ではありません。${month}月${day}日") if $day > $md or $day < 1; &error("1970年以前は指定できません。") if ($year < 1970); } sub setup { my $inpwd = $q->param('pwd'); &setadminpwd if ($inpwd eq ''); &error('管理用パスワードが違います。') unless &checkadmin($inpwd); &htmlhead('管理用セットアップ'); my %check; $check{bgimage}[$bgimage_en] = "checked"; $check{backlink}[$backlink_en] = "checked"; $check{order}[$order] = "checked"; $check{date_disp}[$date_disp] = "checked"; $check{user_mode}[$user_mode] = "checked"; $check{style_sheet}[$style_sheet_en] = "checked"; $check{head_insert}[$head_insert_en] = "checked"; print "\n"; print "\n"; print "\n"; print <
  • 数字やカラー指定は必ず半角で指定してください。全角やブランクだとCGIが起動しなくなります。万一間違って全角で書いてしまった場合は、${setupfile}をエディタで開きその場所を半角に正しく修正してください。それで直ります。
データファイル タイトル 削除ページタイトル バックグランド 画像を使う カラー設定にする
画像を使う場合の画像ファイル
カラー設定の場合のカラー番号(白:#ffffff 又は white) トップへのリンク 表\示 非表\示
リンク名
URL
表\示幅 ブラウザ全体の% 表\示する順序 新しい順 古い順 年月日表\示 年月日 年月のみ 年のみ 管理人モード 管理人オンリーモード ユーザーモード
管理人オンリーでは管理人しか書き込めません。ユーザーモードでは誰でも書き込めます。 ページ上部 ページ上部に表\示させるものをHTML表\記

ページ下部 ページ下部に表\示させるものをHTML表\記

スタイルシート 有効 無効

<head>内挿入文 有効 無効
HTML書式
ポップアップ広告やJavascript、<META>を挿入したい場合にここに記述する。
以下の記述が<head>〜</head>内に挿入される。

時間設定 GMTより時間(日本:+9時間) END print ""; print ""; &htmltail; } sub setupwrite { my %in = $q->Vars; open (SETUP, "> $setupfile") or &error("${setupfile}が開けません。"); print SETUP <