#!/usr/local/bin/perl
################################################################################
# 清き一票！（管理者用）
# Ver 2.1
# Copyright(C) futomi 2001 - 2004
# http://www.futomi.com/
###############################################################################
use strict;
require './config.cgi';
require './jcode.pl';
use CGI;
my $q = new CGI;


#このCGIのURLを取得する
my $ThisCgiUrl = $q->url();
my $AbsoluteUrl = $q->url(-absolute=>1);

#設定
my $ADMINPASSWORD = &config::ADMINPASSWORD;
my $GRAPHIMAGEURL = &config::GRAPHIMAGEURL;
my $CONFIRMFLAG = &config::CONFIRMFLAG;
my $MultiAnsFlag = &config::MultiAnsFlag;
my $ExpireDate = &config::ExpireDate;
my $ExpireErrMsg = &config::ExpireErrMsg;
my $ResultPrintFlag = &config::ResultPrintFlag;
my $REDIRECTFLAG = &config::REDIRECTFLAG;
my $REDIRECTURL = &config::REDIRECTURL;
my $GRAPHMAXLENGTH = &config::GRAPHMAXLENGTH;
my $GRAPHLINECOLOR1 = &config::GRAPHLINECOLOR1;
my $GRAPHLINECOLOR2 = &config::GRAPHLINECOLOR2;
my $MAXLISTNUM = &config::MAXLISTNUM;
my $HANDLEMAXLENGTH = &config::HANDLEMAXLENGTH;
my $COMMENTMAXLENGTH = &config::COMMENTMAXLENGTH;
my $CHECKHANDLE = &config::CHECKHANDLE;
my $CHECKCOMMENT = &config::CHECKCOMMENT;
my $LOGDIR = &config::LOGDIR;
my $NameAttribute = &config::NameAttribute;



######################################################################
#メインルーチン
######################################################################

#デモモード設定
# 0:デモモード解除
# 1:デモモードON
my $DemoMode = 0;

#認証
my %CookieList = &GetCookie;
my $CookiePass = $CookieList{'adminpass'};
my $InputPassword = $q->param('password');
my $Mode = $q->param('mode');
if($Mode eq 'auth') {
	unless(&CheckPassword($InputPassword)) {
		&ErrorPrint("認証エラー");
	}
} else {
	if($CookiePass eq '') {
		&PrintEntrance;	# 認証画面出力
	} else {
		unless(&CheckCookiePassword($CookiePass)) {
			&ErrorPrint("認証エラー");
		}
	}
}

#処理分岐
if($Mode eq 'init') {
	my $DeleteConfirmFlag = $q->param('deleteconfirm');
	unless($DeleteConfirmFlag) {
		&ErrorPrint("本当にログを初期化する場合には、チェックを入れて実行してください。");
	}
	&Init;	# ログデータ初期化
} elsif($Mode eq 'download') {
	&DownLoad;	# ログデータダウンロード
} else {
	my $set_cookie_flag = 0;
	if($CookiePass eq '') {
		$set_cookie_flag = 1;
	}
	&PrintAdmin($set_cookie_flag);	# 管理者用画面出力
}
exit;

######################################################################
#サブルーチン
######################################################################

sub CheckCookiePassword {
	my($cookie_pass) = @_;
	my $salt;
	if($cookie_pass =~ /^\$1\$([^\$]+)\$/) {
		$salt = $1;
	} else {
		$salt = substr($cookie_pass, 0, 2);
	}
	my $pass = crypt($ADMINPASSWORD, $salt);
	if($pass eq $cookie_pass) {
		return 1;
	} else {
		return 0;
	}
}

sub DownLoad {
	if($DemoMode) {
		&ErrorPrint("デモのため、ダウンロードできません。");
	}
	my $Delimiter = $q->param('delimiter');
	my $CharCode = $q->param('charcode');
	my $ReturnCode = $q->param('returncode');
	my $LogSize = -s "${LOGDIR}/votelog.cgi";
	open(VOTELOG, "${LOGDIR}/votelog.cgi") || &ErrorPrint("ログファイル ${LOGDIR}/votelog.cgi をオープンできませんでした。");
	if(my $result = &Lock(*VOTELOG)) {
		&ErrorPrint("只今、混雑しております。しばらくお待ちください。: $result");
	}
	my($Buff);
	sysread(VOTELOG, $Buff, $LogSize);
	close(VOTELOG);

	if($Delimiter eq 'tab') {
		$Buff =~ s/,/\t/g;
	} elsif($Delimiter eq 'space') {
		$Buff =~ s/,/ /g;
	}

	if($CharCode eq 'euc') {
		&jcode::convert(\$Buff, "euc", "sjis");
	} elsif($CharCode eq 'jis') {
		&jcode::convert(\$Buff, "jis", "sjis");
	}

	if($ReturnCode eq 'crlf') {
		$Buff =~ s/\n/\r\n/g;
	} elsif($ReturnCode eq 'cr') {
		$Buff =~ s/\n/\r/g;
	}

	my $TransferSize = length $Buff;
	unless($TransferSize) {
		&ErrorPrint("ログのサイズが0バイトのため、ダウンロードできません。");
	}
	print "Content-type: application/octet-stream\n";
	print "Content-Disposition: attachment; filename=votelog.cgi;\n";
	print "Content-length: $TransferSize\n";
	print "\n";
	print $Buff;
}


sub Init {
	if($DemoMode) {
		&ErrorPrint("デモのため、初期化できません。");
	}
	open(VOTELOG, ">${LOGDIR}/votelog.cgi") || &ErrorPrint("ログファイル ${LOGDIR}/votelog.cgi をオープンできませんでした。");
	close(VOTELOG);
	print "Content-type: text/html; charset=Shift_JIS\n";
	print "\n";
	print "<p>ログの初期化が完了しました。</p>\n";
	print "<a href=\"$ThisCgiUrl\">管理者メニューに戻る</a>\n";
}


sub PrintAdmin {
	my($SetCookieFlag) = @_;
	my $ThisFileName = $q->url(-relative=>1);
	my $CookiePath = $AbsoluteUrl;
	$CookiePath =~ s/$ThisFileName//;
	my $cookie_value = &EncryptPasswd($InputPassword);
	my $CookieString = &SetCookie('adminpass', $cookie_value, $ENV{'HTTP_HOST'}, $CookiePath);
	my $ListUrl = $ThisCgiUrl;
	my $FormUrl = $ThisCgiUrl;
	$ListUrl =~ s/$ThisFileName/kiyolist\.cgi/;
	$FormUrl =~ s/$ThisFileName/kiyoki\.cgi/;
	if($SetCookieFlag) {
		print "$CookieString\n";
	}
	print "Content-type: text/html; charset=Shift_JIS\n";
	print "\n";
	open(ADMINTEMP, "./template/admin.html") || &ErrorPrint("管理者用メニュー画面テンプレート ./template/admin.html をオープンできませんでした。");
	while(<ADMINTEMP>) {
		chop;
		s/<!--cgiurl-->/$ThisCgiUrl/;
		s/<!--listurl-->/$ListUrl/;
		s/<!--formurl-->/$FormUrl/;
		print "$_\n";
	}
	close(ADMINTEMP);
}

sub EncryptPasswd {
	my($pass)=@_;
	my @salt_set = ('a'..'z','A'..'Z','0'..'9','.','/');
	srand;
	my $seed1 = int(rand(64));
	my $seed2 = int(rand(64));
	my $salt = $salt_set[$seed1] . $salt_set[$seed2];
	return crypt($pass,$salt);
}

sub CheckPassword {
	my($InputPassword) = @_;
	if($ADMINPASSWORD eq $InputPassword) {
		return 1;
	} else {
		return 0;
	}
}

sub PrintEntrance {
	print "Content-type: text/html; charset=Shift_JIS\n";
	print "\n";
	print "<html><head><title>futomi's CGI Cafe - 清き一票！</title></head>\n";
	print '<body bgcolor="#FFFFFF">',"\n";
	print '<p>清き一票！ 管理者ログイン</p>',"\n";
	print "<form action=\"$ThisCgiUrl\" method=\"post\">\n";
	print '<input type="hidden" name="mode" value="auth">',"\n";
	print '<table border="0"><tr>',"\n";
	print '<td>パスワード</td>',"\n";
	print '<td><input type="password" name="password"></td>',"\n";
	print '<td><input type="submit" name="auth" value="認証"></tr>',"\n";
	print '</tr></table>',"\n";
	print '</form>',"\n";
	print '</body></html>',"\n\n";
	exit;
}



sub ErrorPrint {
	my($message) = @_;
	print "Content-type: text/html; charset=Shift_JIS\n";
	print "\n";
	open(ERROR, "./template/error.html");
	while(<ERROR>) {
		chop;
		s/<!--message-->/$message/;
		print "$_\n";
	}
	close(ERROR);
	exit;
}

sub Lock {
	local(*FILE) = @_;
	eval{flock(FILE, 2)};
	if($@) {
		return $!;
	} else {
		return '';
	}
}

sub GetCookie {
	my @CookieList = split(/\; /, $ENV{'HTTP_COOKIE'});
	my %Cookie = ();
	my($key, $CookieName, $CookieValue);
	for $key (@CookieList) {
		($CookieName, $CookieValue) = split(/=/, $key);
		$CookieValue =~ s/\+/ /g;
		$CookieValue =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
		$Cookie{$CookieName} = $CookieValue;
	}
	return %Cookie;
}

sub SetCookie {
	my($CookieName, $CookieValue, $Domain, $Path) = @_;
	# URLエンコード
	$CookieValue =~ s/([^\w\=\& ])/'%' . unpack("H2", $1)/eg;
	$CookieValue =~ tr/ /+/;
	my($CookieHeaderString);
	$CookieHeaderString .= "Set-Cookie: $CookieName=$CookieValue\;  domain=$Domain; Path=$Path;";
	return $CookieHeaderString;
}


