#!/usr/bin/perl
#▲[1]パールへのPathを記述

#-----------------------------------------------------------------------------#
#
#  サンプル名：簡易型掲示板
#
#-----------------------------------------------------------------------------#

#▼[2]jcode.plライブラリファイルを読み込み、実行可能な状態にする
require './jcode.pl';

#▼[3]最大で何個のメッセージを保存するかを指定する定数
$max_message = 20;
#▼[4]掲示板の内容を保存するファイル名を指定
$data_file = "./kgkr.dat";
#▼[5]トップに表示するタイトル文字列を指定
$title_string = "今日の気懸り- 掲示板 - ";

#▼[6]文字列"_END_"が出てくるまでの行を、ヒア文字列として$html_headerに読み込み
#ヘッダーとして使用するHTML
#ここのHTML部分を書き換える事で、ユーザの入力フォームを変更する事が出来る
$html_header=<<"_END_";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML LANG="ja">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP" >
<TITLE>$title_string</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>$title_string</H1>
</CENTER>
<HR>
<TABLE BORDER="0">
<FORM ACTION="./kgkr.cgi" METHOD="POST">
<TR><TD><B>名前</B></TD>
<TD><INPUT TYPE="TEXT" SIZE="20" NAME="name"></TD></TR>
<TR>
<TD><B>Ｅメール</B></TD>
<TD><INPUT TYPE="TEXT" SIZE="20" NAME="mail"></TD></TR>
<TR><TD><B>タイトル</B></TD>
<TD><INPUT TYPE="TEXT" SIZE="30" NAME="title"></TD></TR>
<TR><TD><B>ＵＲＬ</B></TD>
<TD><INPUT TYPE="TEXT" SIZE="45" NAME="url" VALUE="http://"></TD>
</TR>
<TR><TD COLSPAN="2"><B>メッセージ</B><BR>
<TEXTAREA NAME="message" ROWS="7" COLS="55"></TEXTAREA><BR>
<INPUT TYPE="SUBMIT" NAME="SUBMIT" VALUE="投稿する">
<INPUT TYPE="RESET" VALUE="リセット">
<P><FONT SIZE="2">
・ 名前とメッセージ欄は必須です。<BR>
・ 古い記事から削除されます。<BR>
</FONT></P>
</TD></TR>
</TABLE>
</FORM>
<HR>
_END_

#▼[7]文字列"_END_"が出てくるまでの行を、$html_messageに読み込み
#メッセージ表示に使用するHTML
#ここのHTML部分を書き換える事で、掲示板内容の表示を変更する事が出来る
$html_message=<<"_END_";
<TABLE BORDER=0>
<TR>
<TD><B>#TITLE</B></TD>
<TD WIDTH="3"></TD>
<TD>投稿者：
<B>#NAME</B></FONT>
投稿日： #DATE</TD>
<TD WIDTH="3"></TD>
<TD>#URL</TD>
</TR>
</TABLE>
<TABLE BORDER="0"><TR><TD></TD><TD>
#MESSAGE
</TD></TR></TABLE>
<HR>
_END_

#▼[8]文字列"_END_"が出てくるまでの行を、$html_footerに読み込み
#フッターとして使用するHTML
$html_footer=<<"_END_";
</BODY>
</HTML>
_END_

#▼[9]文字列"_END_"が出てくるまでの行を、$html_errorに読み込み
#エラーがあった場合に表示するHTML
$html_error=<<"_END_";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML LANG="ja">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP" >
<TITLE>$title_string</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>$title_string</H1>
</CENTER>
<HR>
<CENTER><B>エラー：#ERROR</B><BR>
<FORM METHOD="GET" ACTION="./kgkr.cgi">
<INPUT TYPE="submit" VALUE=" 戻る " ></CENTER>
</FORM></BODY></HTML>
_END_

#▼Main関数の呼び出し
#ここで指定した関数が、Perlで最初に呼び出される関数
&Main();

#▼[10]日付を取得し、指定の書式に変換して戻り値とする関数
sub GetDate() {
  my $date_string;
  my @week = ("日","月","火","水","木","金","土");
  #▼日付の書式(桁数など)を変更するには、ここをいじる
  my $date_format = "%04d/%02d/%02d(%s) %02d:%02d:%02d";
  my ($second, $minute, $hour, $day, $month, $year, $iweek) = localtime( );
  $year  = $year  + 1900;
  $month = $month + 1;
  #▼変数$date_formatに、実際の日付データを代入していく
  $date_string = sprintf( $date_format, $year, $month, $day, $week[$iweek], $hour, $minute, $second);
  return( $date_string );
}

#▼掲示板データをファイルに書き込む関数
#引数($で指定)は5個
sub DataWrite( $$$$$ ) {
  #▼引数配列を、変数に割り振る
  my ( $name, $mail, $title, $url, $message ) = @_;
  my $SEEK_END = 2;  
  my $LOCK_EX = 0x02;

  #▼データ書き込み用のファイルを、追加書き込み専用で開く
  open( OUT, ">>$data_file");
  #▼ファイルを排他ロック(読み書き禁止)する
  flock( OUT, $LOCK_EX );
  #▼ファイルの最後にファイルポインタを移動
  seek( OUT, 0, $SEEK_END );
  #▼書式を指定するための変数$formatを定義
  my $format = "%s,%s,%s,%s,%s,%s\n";
  #▼書式を指定し、ファイルにデータを書き込む
  printf OUT $format, &GetDate(), $name, $mail, $title, $url, $message;
  #▼ファイルポインタのクローズ
  close( OUT );
}

#▼メイン関数
sub Main() {
  my $query_string;
  my %parameter;

  #▼ブラウザへConten-typeを送る
  print "Content-type: text/html\r\n\r\n";
  #▼POSTメソッドによってデータが送られてきたかどうかを確認
  if ($ENV{'REQUEST_METHOD'} eq "POST") {
    #▼標準入力(STDIN)から、変数#query_stringに
    #必要な長さ($ENV{'CONTENT_LENGTH'})文字列を読み込む
    read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'});
    #▼読み込んだ文字列を分解し、$parameterに代入
    foreach (split( /&/, $query_string)) {
      my ($key, $value) = split( '=', $_);
      $value =~ s/\+/ /g;
      $value =~ s/\%([\da-fA-F][\da-fA-F])/pack("C",hex($1))/eg;
      &jcode'convert( \$value, 'euc' );
      $value =~ s/\r\n/<BR>/g;
      $value =~ s/\n/<BR>/g;
      $parameter{$key} = $value;
    }
    #▼名前(name)かメッセージ(message)が入力されていない場合、エラーを表示
    if( ($parameter{'name'} eq '') || ($parameter{'message'} eq '') ) {
      $html_error =~ s/#ERROR/名前もしくはメッセージが未記入です。/g;
      print $html_error;
      exit;
    }
    #▼関数DataWriteを、引数を付けて呼び出す
    &DataWrite(
                $parameter{'name'},
                $parameter{'mail'},
                $parameter{'title'},
                $parameter{'url'},
                $parameter{'message'},
    );
  }
  #▼$html_headerをブラウザにを表示
  print "$html_header";
  #▼$data_fileの指すファイルが、読み出し可能かどうかを確認
  if( -r $data_file ) {
    my @lines;
    open( IN, "$data_file");
    #▼ファイルポインタINの内容をグロブし、スカラー配列@linesに代入
    #<>で囲むと配列コンテキストで評価されるので、配列に直接代入出来る
    @lines = <IN>;
    close( IN );
    #▼@linesの内容を配列単位で逆順序にし、@rev_linesに代入
    my @rev_lines = reverse( @lines );
    #▼$msg_countに、@linesの行数を代入
    my $msg_count = @lines;
    #▼$max_messageより、メッセージの個数が多い場合、多い(古い)分を削除
    if( $max_message < $msg_count ) {
      foreach( 0..($msg_count - $max_message) ) {
        pop( @rev_lines );
      }
    }
    #▼@rev_lineを、1行ずつ順に処理
    foreach( @rev_lines ) {
      #▼@rev_linesを分解し、各変数に代入
      my ( $date, $name, $mail, $title, $url, $message ) = split( ',', $_);
      my $html = $html_message;
      if( $mail ne '' ) {
        my $string = "<A HREF=\"mailto:$mail\">$name</A>";
        #[文字列を単一行](g)とみなして、[#NAME]を[$string]に[すべて置換](s)する
        $html =~ s/#NAME/$string/g;
      }
      else { 
        $html =~ s/#NAME/$name/g;
      }
      if( $url ne 'http://' ) {
        my $string = "<A HREF=\"$url\">$url</A>";
        $html =~ s/#URL/$string/g;
      }
      else { 
        $html =~ s/#URL//g;
      }
      if( $title eq '' ) {
        $html =~ s/#TITLE/無題/g;
      }
      else {
        $html =~ s/#TITLE/$title/g;
      }
      $html =~ s/#DATE/$date/g;
      $html =~ s/#MESSAGE/$message/g;
      #▼$htmlをブラウザに表示
      print "$html";
    }
  }
  #▼$html_footerをブラウザに表示
  print "$html_footer";
}
