#! c:/perl/bin/perl
#
# 履歴記録CGI
#
# 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.14 2005/11/26 18:53:32 Hideki Kanayama Exp $
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.006";
my $lastupdatedyear = "2005";
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 "";
print "$histdata->{$_}[1]年";
print "$histdata->{$_}[2]月" if ($date_disp == 0 or $date_disp == 1);
print "$histdata->{$_}[3]日" if ($date_disp == 0);
print " \n";
print "";
print "$histdata->{$_}[11]";
print " \n";
print " \n";
}
print "
\n";
my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=gmtime($now);
$mon++;
$year += 1900 if ($year < 1900);
print "
\n";
print "";
print "\n";
print " \n";
print "
\n";
print "\n";
print "";
print "削除ページ \n";
print "";
print "管理用 \n";
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);
$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 "";
print "$refkey->[1]年";
print "$refkey->[2]月";
print "$refkey->[3]日";
print " \n";
print "";
print "$refkey->[11]";
print " \n";
print "";
print " [0] size=10>\n";
print " ";
print "";
print " [0] value=\"削除\">\n";
print " ";
print " \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 = $q->param('year');
my $month = $q->param('month');
my $day = $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/,/,/g;
$comment =~ s/\r\n/ /g;
$comment =~ s/\r/ /g;
$comment =~ s/\n/ /g;
$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 "$script Ver. $version
\n";
print "\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;
}
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表\記
$body_head
ページ下部
ページ下部に表\示させるものをHTML表\記
$body_tail
スタイルシート
有効
無効
$style_sheet
<head>内挿入文
有効
無効
HTML書式
ポップアップ広告やJavascript、<META>を挿入したい場合にここに記述する。
以下の記述が<head>〜</head>内に挿入される。
$head_insert
時間設定
GMTより 時間(日本:+9時間)
END
print " ";
print " ";
&htmltail;
}
sub setupwrite {
my %in = $q->Vars;
open (SETUP, "> $setupfile") or &error("${setupfile}が開けません。");
print SETUP <