#!/usr/local/bin/perl

# ユーザ変数設定（ここから）-----------------------------------------------------------------#

$im_env{'adm_pw'}       = "RC KOSHIEN BBS";        #パスワード未記入時のデフォルト値

$im_env{'back_url'}     = "http://www.rckoshien.co.jp/race2001/index.html";         #戻り先ＵＲＬ
$im_env{'back_label'}   = "レース情報TOP";        #戻り先ラベル

$im_env{'jcode_pl'}     = "jcode.pl";     #日本語コード変換スクリプトのパス・名称（このファイルからの相対パス）
$im_env{'dat_dir'}      = "./dat";          #データ用ディレクトリ（このファイルからの相対パス）
$im_env{'log_dir'}      = "./dat/log";      #ログファイル用ディレクトリ（このファイルからの相対パス）
$im_env{'lock_dir'}     = "./dat/lock";     #ロックファイル用ディレクトリ（このファイルからの相対パス）
$im_env{'gbook_dat'}    = "gbook.dat";      #データファイル名（ファイル名のみ指定）
$im_env{'gbook_lock'}   = "gb.lock";        #ロックファイル名（ファイル名のみ指定）

$im_env{'use_lock'}     = "yes";            #ファイルロックがかかったままになるときは "no"（できるだけ "yes"で使用）
$im_env{'form_posi'}    = "top";            #入力フォームの位置 上位置は "top" 、下位置は "bottom"
$im_env{'limit_num'}    = 50;               #最大記録記事数（20以上500以下）
$im_env{'display_num'}  = 10;               #表示記事数（0を指定すると全記事表示）
$im_env{'table_width'}  = 600;              #文字表示領域の幅（ピクセル数で指定）

$im_env{'write_mes'}    = '<B>新規の情報に更新されました</B>';
$im_env{'form_title'}   = 'タイトル';       
$im_env{'form_name'}    = 'ネーム';   
$im_env{'form_matter'}  = 'コメント';       
$im_env{'form_mail'}    = 'E-MAIL';         
$im_env{'form_url'}     = 'HOME-PAGE';      
$im_env{'form_pw'}      = '編集キー';       
$im_env{'name_dec'}     = '';           
$im_env{'err_color'}    = '#FFFF00';        #エラーメッセージの表示色

$im_env{'style_sheet'}="
   A:link    { color:#cc0000; }
  A:visited { color:#ff0000; }
  TD.head   { color:#cc0000; }
  TD.gbtitle{ color:#cc0000;  font-weight:bold; }
  TD.title  { background:#cc0000; color:#FFFF00; font-weight:bold; }
  TD.form   { background:#cc0000; color:#ffffff; }
  TD.name   { background:#ffffff; color:#6633aa; }
  TD.matter { background:#FFFFFF; color:#000000; }
";
$im_env{'script_name'}  = "index.cgi";   #スクリプト名

# ユーザ変数設定（ここまで）-----------------------------------------------------------------#

$im_env{'tm'}=time;

require "$im_env{'jcode_pl'}";

&get_form_data(*form);

$form{'mes'}="$im_env{'form_title'}・$im_env{'form_name'}・$im_env{'form_matter'}の入力は必須です";
$form{'submit_value'}="書込み";
$form{'submit_name'}="write";
if($im_env{'limit_num'}>=20){$im_env{'limit_num'}=20;}
elsif($im_env{'limit_num'}<=500){$im_env{'limit_num'}=20;}

if($form{'log'}){
    if($form{'file'} eq $im_env{'gbook_dat'}){
        $im_env{'dir'}=$im_env{'dat_dir'};
        $im_env{'dat'}=$im_env{'gbook_dat'};
        $form{'log'}="";
    }
    else{
        $im_env{'dir'}=$im_env{'log_dir'};
        $im_env{'dat'}=$form{'file'};
    }
}
else{
    $im_env{'dir'}=$im_env{'dat_dir'};
    $im_env{'dat'}=$im_env{'gbook_dat'};
}

open(GBD,"$im_env{'dir'}/$im_env{'dat'}");
@gb_dat=<GBD>;
close(GBD);

$form{'max_page'}=int($#gb_dat/$im_env{'display_num'})+1;

if($form{'fw'}){
    if(++$form{'page'}>=$form{'max_page'}){$form{'page'}=$form{'max_page'};}
}
elsif($form{'rw'}){
    if(--$form{'page'}<=1){$form{'page'}=1;}
}
elsif($form{'page'}){
    if($form{'page'}>=$form{'max_page'}){$form{'page'}=$form{'max_page'};}
    elsif($form{'page'}<=1){$form{'page'}=1;}
    else{$form{'page'}=$form{'page'};}
}
else{$form{'page'}=1;}

$form{'ct_s'}=($form{'page'}-1)*$im_env{'display_num'};
$form{'ct_e'}=($form{'page'})*$im_env{'display_num'}-1;
$form{'page'}=sprintf("%2.2d",$form{'page'});

if($form{'edit'}){
    foreach $i (@gb_dat){
        #print $i\n;
        $i=~s/\n|\r//;
        if($i=~m/(.*) & (.*) & (.*) & (.*) & (.*) & (.*) & (.*)/){
            if($form{'name'} eq $1 && $form{'title'} eq $2 && $form{'time'} eq $3){
                $form{'name'}  =$1;
                $form{'title'} =$2;
                $form{'mail'}  =$4;
                $form{'url'}   =$5;
                $form{'matter'}=$6;
                $form{'mail'}  =~s/mailto://g;
                $form{'submit_value'} ="編集";
                $form{'submit_name'} ="edit_write";
                $form{'title'} =&decode_ISO_Latin1($form{'title'});
                $form{'name'}  =&decode_ISO_Latin1($form{'name'});
                $form{'matter'}=&decode_ISO_Latin1($form{'matter'});
                last;
            }
        }
    }
}
elsif($form{'edit_write'}){
    $write_flag=0;
    foreach $i (@gb_dat){
        $i=~s/\n|\r//;
        if($i=~m/(.*) & (.*) & (.*) & (.*) & (.*) & (.*) & (.*)/){
            if($form{'time'} eq $3 &&  $form{'pw'} eq $7){
                $form{'title'} =&encode_ISO_Latin1($form{'title'});
                $form{'name'}  =&encode_ISO_Latin1($form{'name'});
                $form{'matter'}=&encode_ISO_Latin1($form{'matter'});
                if($form{'mail'}){$form{'mail'}="mailto:$form{'mail'}";}else{$form{'mail'}="";}
                if($form{'url'} eq "http://"){$form{'url'} ="";}
                $i="$form{'name'} & $form{'title'} & $form{'time'} & $form{'mail'} & $form{'url'} & $form{'matter'} & $form{'pw'}";
                $write_flag=1;
                last;
            }
        }
    }
    if($write_flag){
        &write_data(*im_env,*gb_dat);
        $form{'mes'}=$im_env{'write_mes'};
        ($form{'name'},$form{'title'},$form{'time'},$form{'mail'},$form{'url'},$form{'matter'},$form{'pw'},$form{'time'})=("","","","","","","","");
    }
    else{
        #$form{'matter'}=~s/\r\n/\n/g;
        ($form{'name'},$form{'title'},$form{'time'},$form{'mail'},$form{'url'},$form{'matter'},$form{'pw'},$form{'time'})=("","","","","","","","");
        $form{'mes'}="<FONT color=\"$im_env{'err_color'}\">修正できませんでした（パスワードが違います）</FONT>";
    }
}

if($form{'write'}){
    $form{'mes'}="";
    unless($form{'title'}) {$form{'mes'} ="$im_env{'form_title'}･";}
    unless($form{'name'})  {$form{'mes'}.="$im_env{'form_name'}･";}
    unless($form{'matter'}){$form{'mes'}.="$im_env{'form_matter'}･";}
    unless($form{'mes'}){
        @time=localtime($im_env{'tm'});
        $form{'time'}=sprintf("%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d",1900+$time[5],$time[4]+1,$time[3],$time[2],$time[1],$time[0]);
        if($form{'url'} eq "http://"){$form{'url'} ="";}
        if($form{'mail'}){$form{'mail'}="mailto:$form{'mail'}";}else{$form{'mail'}="";}
        if($form{'pw'}){$pw=$form{'pw'};}else{$pw=$im_env{'adm_pw'};}
        $gb_dat[0]=~m/(.*) & (.*) & (.*) & (.*) & (.*) & (.*) & (.*)/;
        if($1 eq &encode_ISO_Latin1($form{'name'}) && $2 eq &encode_ISO_Latin1($form{'title'}) && $6 eq &encode_ISO_Latin1($form{'matter'})){
            $form{'matter'}=~s/\r\n/\n/g;
           }
        else{
            $form{'title'} =&encode_ISO_Latin1($form{'title'});
            $form{'name'}  =&encode_ISO_Latin1($form{'name'});
            $form{'matter'}=&encode_ISO_Latin1($form{'matter'});
            unshift(@gb_dat,"$form{'name'} & $form{'title'} & $form{'time'} & $form{'mail'} & $form{'url'} & $form{'matter'} & $pw");
            &write_data(*im_env,*gb_dat);
            $form{'mes'}=$im_env{'write_mes'};
            ($form{'name'},$form{'title'},$form{'time'},$form{'mail'},$form{'url'},$form{'matter'},$form{'pw'})=("","","","","","","");
        }
    }
    else{
        $form{'matter'}=~s/\r\n/\n/g;
        $form{'mes'}=~s/･$//;
        $form{'mes'}="<FONT color=\"$im_env{'err_color'}\">$form{'mes'}が未記入です</FONT>";
    }
}

&print_header(*im_env,*form);

if($im_env{'form_posi'} eq "top"){
    if($form{'log'}){&print_loglist(*im_env,*form);}
    else{&print_form(*im_env,*form);}
}

$ct=0;
foreach $i (@gb_dat){
    $i=~s/\n|\r//;
    unless($form{'log'}){if($form{'ct_s'} > $ct++){next;}}
    if($i=~m/(.*) & (.*) & (.*) & (.*) & (.*) & (.*) & (.*)/){
        $mat_dat{'name'}  =$1;
        $mat_dat{'title'} =$2;
        $mat_dat{'time'}  =$3;
        if($4){$mat_dat{'mail'}="<A href=\"$4\">$im_env{'form_mail'}</A>";}
        else{$mat_dat{'mail'}=$im_env{'form_mail'};}
        if($5){$mat_dat{'url'}="<A href=\"$5\">$im_env{'form_url'}</A>";}
        else{$mat_dat{'url'}=$im_env{'form_url'};}
        $mat_dat{'matter'}=$6;
        unless($form{'log'}){$mat_dat{'edit'}="<A href=\"$im_env{'script_name'}?name=$mat_dat{'name'}&title=$mat_dat{'title'}&time=$mat_dat{'time'}&edit=edit#input_form\">_</A>";}
        else{$mat_dat{'edit'}=".";}
    }
    &print_gbook(*mat_dat,*im_env);
    unless($form{'log'}){if($form{'ct_e'} < $ct){last;}}
}
if($im_env{'form_posi'} eq "bottom"){
    if($form{'log'}){&print_loglist(*im_env,*form);}
    else{&print_form(*im_env,*form);}
}
&print_footer(*script,*im_env);
exit 0;

#--------------------------------------------------------------------------------------------#
sub print_header{
#--------------------------------------------------------------------------------------------#
    local(*v,*f)=@_;
    local($navi)=" [";
    unless($f{'log'}){
        if($v{'form_posi'} eq "bottom"){$navi=" [<A href=\"#input_form\">入力フォーム</A>] [";}
    }
    print "Content-type: text/html\n\n";
    print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n";
    print <<"_HEADER_";
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<STYLE type="text/css">
<!--$v{'style_sheet'}-->
</STYLE>
<TITLE>RC甲子園BBS</TITLE>
</HEAD>
<body bgcolor="#000000" text="#ffffff" background="back2.gif" link="#ffff00" vlink="#ffff00" alink="#ffff00" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0" bgproperties=fixed>
<P align="center"><IMG src="../race/gif/bbs_title.gif" width="300" height="148" border="0"></P>
<TABLE border="0" cellspacing="0" cellpadding="0" width="$v{'table_width'}" align="center">
  <TR>
    <TD width="30%" class="head">　</TD>
    <TD align="center" class="gbtitle">$v{'gb_title'}</TD>
    <TD width="30%" align="right" class="head">$navi <A href="$v{'back_url'}">$v{'back_label'}</A> ]</TD>
  </TR>
  <TR>
    <TD colspan="3" class="head"></TD>
  </TR>
</TABLE>
_HEADER_
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub print_loglist{
#--------------------------------------------------------------------------------------------#
    local(*v,*f)=@_;
    $form{'file'}=~m/(\d+).log/;
    local(@time)=localtime($1);
    $f{'mes'}=sprintf("%2.2d/%2.2d/%2.2d 以前のデータを表\示しています",1900+$time[5],$time[4]+1,$time[3]);
    local($log_list,$submit)=&out_loglist(*v);
    print <<"_LOGLIST_";
<DIV><A name="input_form"></A></DIV>
<FORM action="$v{'script_name'}" method="post">
<TABLE border="0" cellspacing="0" cellpadding="2" width="$v{'table_width'}" align="center">
    <TR>
        <TD nowrap class="form"><B>$f{'mes'}</B></TD>
        <TD nowrap align="right" class="form">
            $log_list
            $submit
        </TD>
    </TR>
</TABLE>
</FORM>
_LOGLIST_
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub print_form{
#--------------------------------------------------------------------------------------------#
    local(*v,*f)=@_;
    unless($f{'mes'})   {$f{'mes'}="　";}
    unless($f{'title'}) {$f{'title'}="";}
    unless($f{'name'})  {$f{'name'}="";}
    unless($f{'matter'}){$f{'matter'}="";}
    unless($f{'mail'})  {$f{'mail'}="";}
    unless($f{'url'})   {$f{'url'}="http://";}
    unless($f{'pw'})    {$f{'pw'}="";}
    unless($f{'time'})  {$f{'time'}="";}
    local($w_title)  =$v{'table_width'}*0.11;
    local($w_name)   =$v{'table_width'}*0.07;
    local($w_matter) =$v{'table_width'}*0.12;
    local($w_url)    =$v{'table_width'}*0.11;
    local($w_mail)   =$v{'table_width'}*0.07;
    local($w_pw)     =$v{'table_width'}*0.02;
    local($log_list,$submit) =&out_loglist(*v);
    print <<"_FORM_";
<DIV><A name="input_form">　</A></DIV>
<FORM action="$v{'script_name'}" method="post">
<TABLE border="0" cellspacing="0" cellpadding="1" width="$v{'table_width'}" align="center">
    <TR>
        <TD colspan="4" nowrap class="title">　 $f{'mes'}</TD>
    </TR>
    <TR>
        <TD nowrap align="right" class="form">$v{'form_title'}</TD>
        <TD colspan="3" class="form"><INPUT type="text" name="title" value="$f{'title'}" size="$w_title"></TD>
    </TR>
    <TR>
        <TD nowrap align="right" class="form">$v{'form_name'}</TD>
        <TD class="form"><INPUT type="text" name="name" value="$f{'name'}" size="$w_name"></TD>
        <TD nowrap align="right" class="form">$log_list</TD>
        <TD nowrap class="form">$submit</TD>
    </TR>
    <TR>
        <TD nowrap align="right" class="form">$v{'form_mail'}</TD>
        <TD class="form"><INPUT type="text" name="mail" value="$f{'mail'}" size="$w_mail"></TD>
        <TD nowrap align="right" class="form">
            PAGE
            <INPUT type="submit" name="rw" value="&lt;">
            <INPUT type="text" name="page" value="$f{'page'}" size="2">
            <INPUT type="submit" name="fw" value="&gt;">
        </TD>
        <TD nowrap class="form">
            <INPUT type="submit" name="ps" value="JUMP">
        </TD>
    </TR>
    <TR>
        <TD nowrap align="right" class="form">$v{'form_url'}</TD>
        <TD colspan="3" class="form"><INPUT type="text" name="url" size="$w_url" value="$f{'url'}"></TD>
    </TR>
    <TR>
        <TD nowrap align="right" valign="top" class="form">$v{'form_matter'}</TD>
        <TD colspan="3" class="form"><TEXTAREA name="matter" rows="5" cols="$w_matter" wrap="off">$f{'matter'}</TEXTAREA></TD>
    </TR>
    <TR>
        <TD class="form">　</TD>
        <TD nowrap class="form">
            ■ＨＴＭＬタグは使えません<BR>■$v{'form_pw'}を入力すれば、後で記事編集が出来ます
        </TD>
        <TD colspan="2" nowrap class="form">
            $v{'form_pw'}
            <INPUT type="password" name="pw" value="$f{'pw'}" size="$w_pw">
            <INPUT type="hidden" name="time" value="$f{'time'}">
            <INPUT type="submit" name="$f{'submit_name'}" value="$f{'submit_value'}">
            <INPUT type="reset" value="クリア">
        </TD>
    </TR>
</TABLE>
</FORM>
_FORM_
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub print_gbook{
#--------------------------------------------------------------------------------------------#
    local(*md,*v)=@_;
    local($iw)=int( $v{'table_width'}*0.01);
    local($nw)=int( $v{'table_width'}*0.5 );
    print <<"_MATTER_";
<DIV>　</DIV>
<TABLE border="0" cellspacing="0" cellpadding="3" width="$v{'table_width'}" align="center">
    <TR>
        <TD colspan="3" class="title">$md{'title'}</TD>
    </TR>
    <TR>
        <TD width="$iw" class="name">　</TD>
        <TD width="$nw" class="name"><B>$md{'name'}</B><SMALL>$v{'name_dec'}$md{'edit'}</SMALL></TD>
        <TD nowrap class="name">$md{'time'} [$md{'mail'}] [$md{'url'}]</TD>
    </TR>
    <TR>
        <TD class="matter">　</TD>
        <TD colspan="2" class="matter">$md{'matter'}</TD>
    </TR>
</TABLE>
_MATTER_
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub out_loglist{
#--------------------------------------------------------------------------------------------#
    local(*v)=@_;
    local(@time);
    local($ln,$anc,$ls,$su)=("","","","");
    opendir(LOG_DIR,$v{'log_dir'});
    local(@ln)=readdir(LOG_DIR);
    closedir(LOG_DIR);
    foreach $ln (reverse sort @ln){
        if($ln=~m/(\d+).log/){
            @t=localtime($1);
            $anc=sprintf("%2.2d/%2.2d/%2.2d",$t[5]+1900,$t[4]+1,$t[3]);
            $ls.="<OPTION value=\"$ln\">$anc 以前</OPTION>";
        }
    }
    if($ls){
        $ls="<SELECT name=\"file\"><OPTION value=\"$v{'gbook_dat'}\">最新データ</OPTION>$ls</SELECT>";
        $su="<INPUT type=\"submit\" name=\"log\" value=\"データ切換\">";
    }
    else{
        $ls="　";
        $su="　";
    }
    return ($ls,$su);
}

#--------------------------------------------------------------------------------------------#
sub print_footer{
#--------------------------------------------------------------------------------------------#
    local(*sc,*v)=@_;
    print <<"_FOOTER_";
<TABLE width="$v{'table_width'}" align="center">
    <TR><TD class="head"><HR>
<TD width="30%" align="right" class="head">$navi <A href="$v{'back_url'}">$v{'back_label'}</A> </TD></TR>
    <TR>
      <TD nowrap align="right" class="head">
        
      </TD>
    </TR>
</TABLE>
</BODY>
</HTML>
_FOOTER_
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub write_data{
#--------------------------------------------------------------------------------------------#
    local(*v,*gbd)=@_;
    local($log,$w,$ct);
    if($v{'use_lock'} eq "yes"){&set_lock($v{'lock_dir'},$v{'gbook_lock'});}
    if(@gbd>=$v{'limit_num'}*2){
        $log=$v{'tm'};
        open(GBD,">$v{'dir'}/$v{'dat'}");eval "flock(GBD,2)";
        open(LOG,">$v{'log_dir'}/$log.log");eval "flock(LOG,2)";
        $ct=0;
        foreach $w (@gbd){
            if($ct++ < $v{'limit_num'}){
                $w=~s/\n|\r//g;
                print GBD "$w\n";
            }
            else{
                $w=~s/\n|\r//g;
                print LOG "$w\n";
            }
        }
        close(LOG);eval "flock(LOG,8)";
        close(GBD);eval "flock(GBD,8)";
    }
    else{
        open(GBD,">$v{'dir'}/$v{'dat'}");eval "flock(GBD,2)";
        foreach $w (@gbd){
            $w=~s/\n|\r//g;
            print GBD "$w\n";
        }
        close(GBD);eval "flock(GBD,8)";
    }
    if($v{'use_lock'} eq "yes"){&reset_lock($v{'lock_dir'},$v{'gbook_lock'});}
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub get_form_data{
#--------------------------------------------------------------------------------------------#
    local(*f,$char)=@_;
    local($method,$query,$i,$key,$value)=('','','','','');
    local(@kv);
    unless($char){$char='sjis';}
    $char =~ tr/A-Z/a-z/;
    $method = $ENV{'REQUEST_METHOD'};
    $method =~ tr/A-Z/a-z/;
    if($method eq 'post'){read(STDIN,$query,$ENV{'CONTENT_LENGTH'});}
    elsif($ENV{'QUERY_STRING'}){$query=$ENV{'QUERY_STRING'};}
    else{return 0;}
    @kv=split(/&/,$query);
    foreach $i (@kv) {
        ($key, $value) = split(/=/,$i);
        $value=~tr/+/ /;
        $value=~s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C",hex($1))/eg;
        &jcode'convert(*value,$char,$char,"z");
        $f{$key}=$value;
    }
    return 1;
}

#--------------------------------------------------------------------------------------------#
sub encode_ISO_Latin1{
#--------------------------------------------------------------------------------------------#
    local($v)=@_;
    unless($v){return '';}
    $v=~s/&/&amp;/g;
    $v=~s/</&lt;/g;
    $v=~s/>/&gt;/g;
    $v=~s/"/&quot;/g;
    $v=~s/'/&#39;/g;
    $v=~s/\r\n/\n/g;
    $v=~s/\r/\n/g;
    $v=~s/\n/<BR>/g;
    return $v;
}

#--------------------------------------------------------------------------------------------#
sub decode_ISO_Latin1{
#--------------------------------------------------------------------------------------------#
    local($v)=@_;
    unless($v){return '';}
    $v=~s/&amp;/&/g;
    $v=~s/&lt;<//g;
    $v=~s/&gt;/>/g;
    $v=~s/&quot;/"/g;
    $v=~s/&#39;/'/g;
    $v=~s/<BR>/\n/g;
    return $v;
}

#--------------------------------------------------------------------------------------------#
sub set_lock{
#--------------------------------------------------------------------------------------------#
    local($s_l_file)="$_[0]/$_[1]";
    local($s_l_tmpfile)="$_[0]/$$".$_[1];
    local($s_l_retry)=5;
    while ($s_l_retry){
        if(rename($s_l_file,$s_l_tmpfile)){return 1;}
        else{sleep(1);$s_l_retry--;}
    }
    return 0;
}

#--------------------------------------------------------------------------------------------#
sub reset_lock{
#--------------------------------------------------------------------------------------------#
    local($r_l_file)="$_[0]/$_[1]";
    local($r_l_tmpfile)="$_[0]/$$".$_[1];
    if(rename($r_l_tmpfile,$r_l_file)){return 1;}
    return 0;
}
