#!/usr/bin/perl
use Fcntl;
require './jcode.pl';
#newsファイル定型文・変数定義を読み込み
#require './nconst.pl';
#初期設定ファイルのパス
$iniconf = '../init.dat';

#管理用パスワード
$defpass = '12345';

#Max News Category No.
#$MaxCate = '5';

&dataload;

@name_list = &decoding();
#$admpass = 'zxcv';
&checkvalues();
if ($FORM{pass} eq $defpass and $defpass eq $INIT{pass}){&firstmenu;}
elsif ($FORM{act} eq 'chpass'){&ChgPass;&enter;}
elsif ($FORM{act} eq 'dsave'){&SaveData;&dataload;&admmenu;}
elsif ($FORM{pass} eq $INIT{pass}){&admmenu;}
else{&enter;}
exit;

######################
#   データデコード   #
######################
sub decoding {

    my($buf,$name,$value,$before,@name_list);

    if ($ENV{REQUEST_METHOD} eq "POST") {
        read(STDIN, $buf, $ENV{CONTENT_LENGTH});
    } else {
        $buf = $ENV{QUERY_STRING};
    }
#    $buf || error("データがありません");

    foreach (split(/&/,$buf)) {
        ($name, $value) = split(/=/);
        $name  =~ tr/+/ /;
        $value =~ tr/+/ /;
        $name  =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
        $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
        $name  =~ s/\n//g;
        jcode::convert(\$name,'sjis');
        jcode::convert(\$value,'sjis');
        push(@name_list, $name) if $before ne $name;
        $before = $name;

        $value =~ s/(\r\n)|(\n)/<#>/g;
#        $value =~ s/</&lt;/g;
#        $value =~ s/>/&gt;/g;
        if (defined($FORM{$name})) {
            $FORM{$name} = join('!!!', $FORM{$name}, $value);
        } else {
            $FORM{$name} = $value;
        }
    }

    @name_list;

}

########################
#  送信データチェック  #
########################
sub checkvalues {
	my @msg;
#     foreach (@name_list) {
#         if ($FORM{pass}) {
#             push(@msg, "パスワードの設定条件を検査はしたようです。$FORM{pass}");
#         }
        #if ($_ eq "pass" and $FORM{$_} =~ /[^0-9a-zA-Z]/) {
        if ($FORM{act} ne 'login' and $FORM{fstpass} =~ /[^0-9a-zA-Z]/) {
            push(@msg, "1.パスワードの設定条件を確認してください。");
            &error(@msg) if @msg;
        }
        if ($FORM{fstpass} ne '' and $FORM{fstpass} !~ /^[0-9a-zA-Z]{5,10}$/) {
            push(@msg, "2.パスワードの設定条件を確認してください。");
            &error(@msg) if @msg;
        }
#         elsif ($_ eq "pass" and $FORM{$_} eq $defpass) {
#             push(@msg, "パスワードを初期値から変更してください。");
#         }
#         elsif ($_ eq "path1" and $FORM{$_} !~ /^[0-9a-zA-Z\/\-\_]*/) {
#             push(@msg, "news1ファイルのパスが正しくないようです。確認してください。");
#         }
#         elsif ($_ eq "path2" and $FORM{$_} !~ /^[0-9a-zA-Z\/\-\_]*/) {
#             push(@msg, "news2ファイルのパスが正しくないようです。確認してください。");
#         }
#         elsif ($_ eq "path3" and $FORM{$_} !~ /^[0-9a-zA-Z\/\-\_]*/) {
#             push(@msg, "news3ファイルのパスが正しくないようです。確認してください。");
#         }
#     }
#         if ($FORM{pass} !~ /^[0-9a-zA-Z]{4,10}$/) {
#             push(@msg, "パスワードの設定条件を確認してください。$FORM{pass}");
#         }
        
        &error(@msg) if @msg;

}


#$msg =~ s/\n/<br>/g;
#$msg =~ s/　/&nbsp;/g;

########################
#  設定データ読み込み  #
########################
sub dataload{
	my @msg;
	my $i;
#    $logfile = './log.dat';

	open (IN,"$iniconf") || push(@msg, "$iniconfオープン失敗");
    &error(@msg) if @msg;
	eval{flock(IN,1)};
	@log = <IN>;
	chomp @log;
	close (IN);
# 	foreach (@log){
# 		$_=~ s/\r|\n//g;
# 	}
	#設定データを分解
	@INIT = split(/<>/,$log[0]) ;
	%INIT = ('pass' => "$INIT[0]", 'sitename' => "$INIT[1]",
			 'maxlog' => "$INIT[2]", 'maxcat' => "$INIT[3]");
	for ($i = 1; $i <= $INIT{maxcat}; ++$i){
		@{"News$i"} = split(/<>/,$log["$i"]) ;
		%{"NEWS$i"} = ('title' => ${"News$i"}[0], 'path' => ${"News$i"}[1], 'width' => ${"News$i"}[2],
					   'listg' => ${"News$i"}[3], 'header' => ${"News$i"}[4], 'footer' => ${"News$i"}[5]);
		${"NEWS$i"}{header} =~ s/<#>/\n/g;
		${"NEWS$i"}{footer} =~ s/<#>/\n/g;
	}
	#Include File Footer Header 読み込み
	
}

#################################
#  編集メニュー 表示           #
#################################
sub admmenu{
	my ($a1,@temp,$a2);
	my $i = 0;
	my $j = 4;
	&hphead;
    if($admesg){
        print '<div class="admsg">'."\n";
        print "$admesg\n";
        print '<a href="../nacn.cgi">Auto Change News</a>'."\n";
        print "</div>\n";
    }
	print <<'EOD';
	<form method="post" action="./initconf.cgi">
	<table summary="設定項目入力フォーム" class="spec">
	<tr> 
	<th class="spec" abbr="パスワード">パスワード</th>
EOD
    print '	<td class="list"><input name="fstpass" type="text" value="'."$INIT{pass}".'" tabindex="1" accesskey="a" />'."\n";
	print <<'EOD';
	<ul>
		<li>半角英数のみ</li>
		<li>記号は使用不可</li>
		<li>大文字小文字を区別します</li>
		<li>文字数 5文字以上10文字以内</li>
	</ul></td>
	</tr>
	<tr> 
	<th class="spec" abbr="サイト名">サイト名</th>
EOD
    print ' <td class="list"><input name="sitename" type="text" value="'."$INIT{sitename}".'" tabindex="2" accesskey="b" /></td>'."\n";
	print <<'EOD';
	</tr>
	<tr> 
	<th class="spec" abbr="Max記事">最大記事保存数</th>
EOD
    print ' <td class="list"><input name="maxlog" type="text" value="'."$INIT{maxlog}".'" tabindex="3" accesskey="c" /></td>'."\n";
	print <<'EOD';
	</tr>
	<tr> 
	<th class="spec" abbr="カテ数">生成カテゴリー数</th>
EOD
    print ' <td class="list"><input name="maxcat" type="text" value="'."$INIT{maxcat}".'" tabindex="4" accesskey="d" /></td>'."\n";
	print '	</tr>'. "\n";
	
	#カテゴリ数分だけルーチン
	for ($i = 1; $i <= $INIT{maxcat}; ++$i){
		if ($i % 2){
			$Th_Color = 'spec2';
		} else { $Th_Color = 'spec';}
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'カテゴリー名">news'."$i".'カテゴリー名</th>'."\n";
    	print '	<td class="list"><input name="title'."$i".'" type="text" size="60" value="'. ${"NEWS$i"}{title} .'" tabindex="'.($j + 1).'" accesskey="'.chr($j + 97).'" /></td>'."\n";
		print '	</tr>'."\n";
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'ファイルのパス">news'."$i".'ファイルのパス <font color="red">（注1)</font></th>'."\n";
		print '	<td class="list"> <input name="path'."$i".'" type="text" size="60" value="'. ${"NEWS$i"}{path} .'" tabindex="'.($j + 2).'" accesskey="'.chr($j + 98).'" /></td>'."\n";
		print '	</tr>'."\n";
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'表示幅">news'."$i".'差込ファイルでの表示幅</th>'."\n";
	    print '	<td class="list"> <input name="width'."$i".'" type="text" size="5" value="'. ${"NEWS$i"}{width} .'" tabindex="'.($j + 3).'" accesskey="'.chr($j + 99).'" /></td>'."\n";
		print '	</tr>'."\n";
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'用">news'."$i".'リスト記号 or 画像パス <font color="red">（注2)</font></th>'."\n";
	    print '	<td class="list"> <input name="listg'."$i".'" type="text" size="60" value="'. ${"NEWS$i"}{listg} .'" tabindex="'.($j + 4).'" accesskey="'.chr($j + 100).'" /></td>'."\n";
		print '	</tr>'."\n";
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'header">生成Incファイル'."$i".'ヘッダー <font color="red">（注3)</font></th>'."\n";
	    print '	<td class="list"> <textarea name="header'."$i".'" cols="60" rows="5" tabindex="'.($j + 5).'" accesskey="'.chr($j + 101).'">'. ${"NEWS$i"}{header} .'</textarea></td>'."\n";
		print '	</tr>'."\n";
		print '	<tr>'."\n";
		print '	<th class="'.$Th_Color.'" abbr="news'."$i".'header">生成Incファイル'."$i".'フッター <font color="red">（注3)</font></th>'."\n";
	    print '	<td class="list"> <textarea name="footer'."$i".'" cols="60" rows="5" tabindex="'.($j + 6).'" accesskey="'.chr($j + 102).'">'. ${"NEWS$i"}{footer} .'</textarea></td>'."\n";
		print '	</tr>'."\n";
		$j += 6;
	}
	print <<'EOD';
	</table>
	<div>
	<input type="hidden" name="act" value="dsave" />
	<input type="submit" value="　設　定　" tabindex="23" accesskey="y" />
	<input type="reset" value="　キャンセル　" tabindex="24" accesskey="z" />
	</div>
	</form>
	<div class="atten">
		<ul>(注1)
		<li>差込ファイル（xxx.shtml)からの相対パスで！</li>
		<li>ファイル名の拡張子は特に制限ない。拡張子は無くても良い。</li>
		</ul>
		<ul>(注2)
		<li>画像であれば差込ファイル（xxx.shtml)からの相対パスで!</li>
		<li>リスト画像はgifのみ可。 ファイル名の拡張子は、.gif(小文字のみ）有効</li>
		</ul>
		<ul>(注3)
		<li>自動生成するインクルードファイルのヘッダー･フッター部を変更可能。</li>
		<li>スペースや改行は有効。自動生成されるインクルードファイルにも反映される。</li>
		</ul>
	</div>
EOD
	&hpfoot;
}

#####################
#  Firstメニュー    #
#####################
sub firstmenu{
	my ($a1,@temp,$a2);
	my $i = 0;
	&hphead;
	print <<'EOD';
	<div class="info">ここで、必ずパスワードを初期値から変更してください。
	</div>
	<form method="post" action="./initconf.cgi">
	<table>
	<tr> 
	<th abbr="パスワード">パスワード</th>
EOD
    print '	<td><input name="fstpass" type="text" value="'.$INIT{pass}.'" tabindex="1" accesskey="a" />'."\n";
	print <<'EOD';
	<ul>
		<li>半角英数のみ</li>
		<li>記号は使用不可</li>
		<li>大文字小文字を区別します</li>
		<li>文字数 5文字以上10文字以内</li>
	</ul></td>
	</tr>
	</table>
	<div>
	<input type="hidden" name="act" value="chpass" />
	<input type="submit" value="　設　定　" tabindex="2" accesskey="b" />
	<input type="reset" value="　キャンセル　" tabindex="3" accesskey="c" />
	</div>
	</form>
EOD
	&hpfoot;
}


############################
#   管理人確認             #
############################
sub enter{
	&hphead;
	print '<div class="info">'."\n";
	print 'パスワードを入力してください。<br />'."\n";
	if ($admesg eq '' and  $INIT{pass} eq $defpass){
		print <<'EOD';
	初めて本スクリプトを実行する場合は、必ず次の画面でパスワードは変更してください。<br />
	次の画面でパスワードを設定するまでは、初期値"12345"がパスワードとなります。
	<ul>
		<li>半角英数のみ</li>
		<li>記号は使用不可</li>
		<li>大文字小文字を区別します</li>
		<li>文字数 5文字以上10文字以内</li>
	</ul>
EOD
	}
	print <<'EOD';
	</div>
	<div>
	<form method="post" action="./initconf.cgi">
	<p>
	password
	<input type="hidden" name="act" value="login" />
	<input type="password" name="pass" size="16" tabindex="1" accesskey="p" />
	<input type="submit" value="進む" accesskey="s" tabindex="2" />
	</p>
	</form>
	</div>
EOD
    if($admesg){
        print '<div class="admsg">'."\n";
        print "$admesg\n";
        print '<a href="../nacn.cgi">Auto Change News</a>'."\n";
        print "</div>\n";
    }
	&hpfoot;
}

############################
#  ヘッダ部表示            #
############################
sub hphead{
print "Content-type:text/html; charset=shift_jis\n\n";
print <<'EOD';
<?xml version="1.0" encoding="Shift_JIS" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS" />
<meta http-equiv="content-style-type" content="text/css" />
<title>Auto Change News</title>
<link rel="stylesheet" href="../def.css" type="text/css" media="screen" />
</head>
<body>
    <div class="navbar1">
        初期設定
    </div>

EOD
}

############################
#フッタ部表示              #
############################
sub hpfoot{
print <<'EOD';
    <div class="navbar2">
        初期設定
    </div>
    <div>
        <a href="http://www.i-live.ne.jp/">Internet Life Total Support Shop i-Live</a>
    </div>
</body>
</html>
EOD
exit;
}


####################
#  設定データ保存  #
####################
sub SaveData {
	my @msg;
	my $logfile;
	my $LogFlag;
	
    1 while (not defined($locktmp = my_flock()));
    
    sysopen(CNT, "$iniconf", O_WRONLY) || push(@msg, "$iniconfオープン失敗");
    seek(CNT, 0, 0) || push(@msg, "can't rewind numfile: $!");
    truncate(CNT, 0) || push(@msg, "can't truncate numfile: $!");
    &error(@msg) if @msg;
#    print CNT @chnew;
    print CNT "$FORM{fstpass}".'<>'."$FORM{sitename}".'<>'."$FORM{maxlog}".'<>'."$FORM{maxcat}".'<>'."\n";
	for ($i = 1; $i <= $INIT{maxcat}; ++$i){
#         $FORM{"header$i"} =~ s/(\r\n)|(\n)/<#>/g;
#         $value =~ s/</&lt;/g;
#         $value =~ s/>/&gt;/g;
    	print CNT $FORM{"title$i"}.'<>'.$FORM{"path$i"}.'<>'.$FORM{"width$i"}.'<>'.$FORM{"listg$i"}.'<>'.$FORM{"header$i"}.'<>'.$FORM{"footer$i"}.'<>'."\n";

        #カテ別データファイルを確認、なければ作成
        $logfile = '../log'.$i.'.dat';
        unless (-e $logfile){
        	$LogFlag = (system "/usr/bin/touch", $logfile) ;
        	if ($LogFlag == 0){
        	    $admesg .= "新規カテのログファイル$logfileを作成しました。<br />";
        	} else { push(@msg, "$logfile 作成失敗");}
        }

    }
    close CNT;

    my_funlock($locktmp);
    &error(@msg) if @msg;
    $admesg .= '設定を変更しました。';
}

####################
#  パスワード変更  #
####################
sub ChgPass {
	my @msg;
	my $i;
    1 while (not defined($locktmp = my_flock()));
    
    sysopen(CNT, "$iniconf", O_WRONLY) || push(@msg, "$iniconfオープン失敗");
    &error(@msg) if @msg;
    seek(CNT, 0, 0) || die "can't rewind numfile: $!";
    truncate(CNT, 0) || die "can't truncate numfile: $!";
#    print CNT @chnew;
    print CNT "$FORM{fstpass}".'<>サイト名<>20<>1<>'."\n";
    print CNT '新着情報<>./news.txt<>300<>./rdr.gif<>     <!-- ここから Include --><#>     <table border="0" cellpadding="0" cellspacing="0"><#>     <tbody><#><>     </tbody><#>     </table><#>     <!-- ここまで Include --><#><>'."\n";
#     for ($i = 1; $i < 14; ++$i){
#         print CNT "$log[$i]\n";
#     }
    close CNT;

    my_funlock($locktmp);
    $admesg = 'パスワードを更新しました。';

}

########################
#   ファイルLock       #
########################
sub my_flock {
  my %lfh = (dir => './lockdir/', basename => 'lockfile',
	     timeout => 60, trytime => 10, @_);

  $lfh{path} = $lfh{dir} . $lfh{basename};

  for (my $i = 0; $i < $lfh{trytime}; $i++, sleep 1) {
    return \%lfh if (rename($lfh{path}, $lfh{current} = $lfh{path} . time));
  }
  opendir(LOCKDIR, $lfh{dir});
  my @filelist = readdir(LOCKDIR);
  closedir(LOCKDIR);
  foreach (@filelist) {
    if (/^$lfh{basename}(\d+)/) {
      return \%lfh if (time - $1 > $lfh{timeout} and
	  rename($lfh{dir} . $_, $lfh{current} = $lfh{path} . time));
      last;
    }
  }
  undef;
}

##########################
#   ファイルUnLock       #
##########################
sub my_funlock {
  rename($_[0]->{current}, $_[0]->{path});
}

####################
#   エラー処理     #
####################
sub error {
    foreach (@_) {
        $FORM{ERROR_MSG} .= "<tr><td class=\"list\"><li>$_<br /></td></tr>";
    }
    
	&hphead;
	print <<'EOD';
<table class="spec">
    <tr>
      <th class="spec">入力項目に誤りがあるようです。</th>
    </tr>
EOD
    print "$FORM{ERROR_MSG}";
	print <<'EOD';
    <tr>
      <td class="list"><input type="button" value="戻　る" onclick="history.back()"></td>
    </tr>
</table>
EOD
	&hpfoot;
    exit;
}
