#!/usr/bin/perl

# =================================================================
# 名前:　nobbs.cgi Ver1.01　<2003/09/12>
# 実行ファイル: 　nobbs.cgi Ver1.01　
#  			機能拡張連携プログラム　graphup.cgi ver1.01
# 			注意！機能拡張連携プログラム　graphup.cgiについては、別ファイルconfig.plで設定します。
# 機能: ホームページ記事発信、ページ作成を支援するCGIスクリプト。
# 画像付き記事一覧掲示板、作成ページ閲覧用CGIスクリプト
#
# 種別：フリーソフト（私用・商用問わず、利用・改造・流用・再配布可）
# 作者: 岡山県吉備高原都市地域イントラネット研究会×森山@北部住区×渡辺@OBIS
# 参照: http://www.kibicity.ne.jp/
# =================================================================
#
# 2003/09/12	GDモジュールがない場合、掲示板への縮小画像表示の不具合を修正。
#
# =================================================================


# 設定ファイル名
my ($BBS_CONF) = 'nobbsconf.pl';

&error('日本語モジュール【jcode.pl】が見つかりません。') unless(-f './jcode.pl');
&error("設定ファイル【$BBS_CONF】が見つかりません。") unless(-f $BBS_CONF);

require 'jcode.pl';
require $BBS_CONF;

# GDモジュールの確認
# MODIFY 2003.09.15
my ($GD) = &CheckGDModule() if ($GD_USE==1);
#MODIFY END
# ----------------------------------------< MAIN >------------------------------------------ #

# 最後のスラッシュを削除
$BBS_LOG_DIR =~ s/\/$//o;

$BBS_IMG_DIR =~ s/\/$//o;
$BBS_IMG_URL =~ s/\/$//o;

$BBS_HTML_DIR =~ s/\/$//o;
$BBS_HTML_URL =~ s/\/$//o;

$BBS_IMG_QUALITY = 60 if(!$BBS_IMG_QUALITY);

# 出力のフラッシュをおこなう
$| = 1;

# フォームデータ取得
&ReadFormData;

# 処理振分け
SWITCH: {

	if ( exists $FORM{'mode'} ) {

		# パスワード入力
		if ( $FORM{'mode'} eq 'admin'  ) { 
			if ( $FORM{'action'} eq '') { &disp_passform; last SWITCH; }

			if ( $FORM{'pass'} ne $admin ) { &error( 'パスワードが違います。' ); }
	
			if ( $FORM{'action'} eq 'edit' ) { &disp_newslist; last SWITCH; }
			if ( $FORM{'action'} eq 'entry') { &disp_entryframe; last SWITCH; }
		}

		# 投稿データ登録
		if ( $FORM{'mode'} eq 'regist' ) { &regist_newsdata; last SWITCH; }
		# 投稿データ削除
		if ( $FORM{'mode'} eq 'delete' ) { &del_newslist; last SWITCH; }
		# 投稿データ修正登録
		if ( $FORM{'mode'} eq 'update' ) { &update_newsdata; last SWITCH; }
		
		if ( $FORM{'mode'} eq 'upform')  { &disp_entryframe; last SWITCH; }
		if ( $FORM{'mode'} eq 'entform') { &disp_entryform; last SWITCH; }
		if ( $FORM{'mode'} eq 'entform2'){ &disp_entryform; last SWITCH; }
		if ( $FORM{'mode'} eq 'edit' ) { &disp_editform; last SWITCH; }

		# 過去ログ参照
		if ( $FORM{'mode'} eq 'history' ) { &MakeHistoryFrame($FORM{'page'}, 1); last SWITCH; }
		if ( $FORM{'mode'} eq 'histhead') { &MakeHistoryTitle($FORM{'page'}); last SWITCH; }
		if ( $FORM{'mode'} eq 'histbody') { &MakeIndexFile($FORM{'page'}, 1); last SWITCH; }

		# 検索条件入力画面表示
		if ( $FORM{'mode'} eq 'find') { &DispFindForm; last SWITCH; }
		if ( $FORM{'mode'} eq 'find_result') { &DispFindForm; last SWITCH; }
		if ( $FORM{'mode'} eq 'srch') { &SearchNewsFiles; last SWITCH; }
		if ( $FORM{'mode'} eq 'srch_result') { &SearchNewsFiles; last SWITCH; }

		&location;
	} else {
		&location;
  }
}

exit;


# フォームデータ取得処理
# ------------------------------------------------------------------------------
sub ReadFormData
{

	my ( $image, $image_name, $name, $value );
	my ( $boundry, $buffer );
	my ( @pairs, $pair, $idx );


	$IpAddr = $ENV{'REMOTE_ADDR'};
	$IpAddr = $ENV{'REMOTE_HOST'} if (!$IpAddr);

	&get_cookie;

	if ( $ENV{'REQUEST_METHOD'} eq 'POST' &&  $ENV{'CONTENT_TYPE'} =~ /multipart\/form-data/ ) {
		# マルチパートなら
		&error( '添付ファイルの容量が大きすぎます。' ) if ( $ENV{'CONTENT_LENGTH'} > (( $BBS_IMG_MAX + 1 ) * 1024 ));
	
		binmode(STDIN);
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

		($boundary) = $ENV{'CONTENT_TYPE'} =~ /boundary=(\S+)$/;

		@pairs = split(/$boundary/, $buffer);

		shift( @pairs );		# 最初と最後は要らない
		pop( @pairs );

		foreach $pair (@pairs) {
			my (@vars) = split( /\r\n/, $pair );

			$name = '';
			$value = '';

			if ( $vars[1] =~ /comment/ ) {
				$name = 'comment';
				for ( $idx = 3; $idx < $#vars; $idx++ ) {
					if( $idx != 3 ) { $value .= '<BR>'; }
					$value .= "$vars[$idx]";
				}

			} elsif ( $vars[1] =~ /filename\=\"(.+)\"/ ) {
				# バイナリデータ
				#	$vars[1]: Content-Disposition: form-data; name="path"; filename="パス" 
				#	$vars[2]:	Content-Type
				#	$vars[4]: データ本体

				$value = $1;
				$name = 'path';

				&jcode::convert(\$value, 'sjis','','z');
				$FORM{$name} = $value;

				$name = 'content_type';
				$vars[2] =~s/Content-Type:\s//g;
				$value = $vars[2];

				# バイナリ中に改行コードが入っていた場合、分割されているので、ここで結合
				$image = '';
				for ( $idx = 4; $idx < $#vars; $idx++ ) {
					$image .= "\r\n" if ( $idx != 4 );
					$image .= $vars[$idx];
				}

				# パスを消して、ファイル名のみを残す。
				$image_name=~ s/^(.*)\\//;
				$image_name=~ s/^(.*)\///;
				$ext = &check_contenttype( $image_name, $value);
				$ext = &get_imagetype(substr( $image, 0, 8)) if ($ext eq 'unknown' );
				&error( 'アップロードできません。' ) if ($ext eq 'unknown' );

				# 現在日取得
				my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
				$date = sprintf( "%02d%02d%02d%02d%02d", $mon + 1, $mday, $hour, $min, $sec );

				# 書込みディレクトリの存在チェック
				&make_dir($BBS_IMG_DIR) if (&check_dir($BBS_IMG_DIR) != 1);

				open(OUT, ">$BBS_IMG_DIR/img${date}.${ext}") || &error("添付ファイルの保存中にエラーが発生しました。");
				binmode(OUT);
				print OUT $image;
				close(OUT);
				chmod 0755, "$BBS_IMG_DIR/img${date}.${ext}";
				undef $image;

				# サムネール作成
				&make_smallimage("img${date}.${ext}") if ( $ext eq 'jpg' );

				$FORM{'image'} = "img${date}.${ext}";
			} elsif (  $vars[1] =~ /name\=\"(.+)\"/ )   {
				$name = $1;
				$value = $vars[3];
			}
			&jcode::convert(\$value, 'sjis','','z');
			$FORM{$name} = $value;
		}
	} else {
		# フォームからのデータを取得
		if ( $ENV{'REQUEST_METHOD'} eq 'POST') {
			# 'POST'
			read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
		} elsif ( $ENV{'REQUEST_METHOD'} eq 'GET') {
			# 'GET'
			$buffer = $ENV{'QUERY_STRING'};
		}

		@pairs = split(/&/, $buffer);

		foreach $pair (@pairs) {
			($name, $value) = split(/=/, $pair);
			$name =~ tr/+/ /;
			$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			$value =~ tr/+/ /;
			$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			&jcode::convert(\$name,'sjis');
			&jcode::convert(\$value,'sjis');

			if ( $tag == 0 ) {
				# タグ禁止の場合
				$value =~ s/&/&amp\;/g;
				$value =~ s/</&lt\;/g;
				$value =~ s/>/&gt\;/g;
				$value =~ s/\"/&quot/g;
			} else {
				$value =~ s/\"/\'/g;
			}

			# 改行処理
			$value =~ s/\r\n/<br>/g;
			$value =~ s/\r/<br>/g;
			$value =~ s/\n/<br>/g;

			if( $name eq 'del' ) { push @DEL, $value; }
	
			$FORM{$name} = $value;
		}
	}

}

# ------------------------------------------------------------------------------
# エラー処理
# ------------------------------------------------------------------------------
sub error
{

	my (@errs)	= @_;				# エラー内容
	my ($msg);
	my ($width) = (($BBS_WIDTH - $BBS_MARGIN) <= 0) ? '100%' : $BBS_WIDTH - $BBS_MARGIN;

	if ($FORM{'image'}) { 
		# バイナリーファイルが書き込まれた後、エラー発生
		unlink "$BBS_IMG_DIR/$FORM{'image'}" if ( -f "$BBS_IMG_DIR$/FORM{'image'}" );
		unlink "$BBS_IMG_DIR/s$FORM{'image'}" if ( -f "$BBS_IMG_DIR/s$FORM{'image'}" );
	}

	$msg .= "  <B>$_</B><BR>\n" foreach(@errs);

	# HTMLの定型を作成
print<<"EOM";
Content-type: text/html

<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
  <TITLE>$BBS_TITLE</TITLE>
</HEAD>
<BODY>
<TABEL BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="$BBS_WIDTH">
<TR><TD WIDTH="$BBS_MARGIN"></TD>
<TD WIDTH="$width">
<DIV ALIGN="CENTER">
<BR>
<H3><B>Error !!</B></H3>
<BR>
<HR noshade size="5">
<BR>
$msg
<BR>
<HR noshade size="5">
</DIV>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
EOM

	exit;
}

# ------------------------------------------------------------------------------
# インデックスへジャンプ
# ------------------------------------------------------------------------------
sub location
{

	if (( $FORM{'debug'}) || (exists($FORM{'remake'}))) {
		&MakeIndexFile($_) for(1..2);
		&MakeHeadLine;
	} else {
		unless ( -f "$BBS_HTML_DIR/$BBS_HTML_FILE1" ) {
			# インデックスが見つからない場合は、作成
			&MakeIndexFile($_) for(1..2);
			&MakeHeadLine;
		}
	}

	print "Location: $BBS_HTML_URL/$BBS_HTML_FILE1?\n\n";

	exit;
}


# ------------------------------------------------------------------------------
# 新インデックスファイルの作成
# ------------------------------------------------------------------------------
sub MakeIndexFile()
{
	my ($Page, $History) = @_;
	my ($width) = ($BBS_WIDTH - $BBS_MARGIN) <= 0 ? '100%' : $BBS_WIDTH - $BBS_MARGIN;


	($Page) = $Page < 1 ? 1 : $Page;

	if ($History) {
		# 標準出力へ
		print "Content-type: text/html\n\n";
	} else {
		# HTMLファイルへ出力
		$file = ($Page <= 1) ? "$BBS_HTML_DIR/$BBS_HTML_FILE1" : "$BBS_HTML_DIR/$BBS_HTML_FILE2";
		open(FH, ">$file") or &error('ファイル作成エラー', "$file");
		select(FH);
	}

	&MakeIndexHeader($History);

	&MakeIndexBody($Page, $History);

	print qq{</TR></TABLE>\n};

	if ($BBS_FOOTER) {
		print qq{<TABLE WIDTH="$BBS_WIDTH" BORDER="0"><TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">};
		print qq{<DIV ALIGN="CENTER">$BBS_FOOTER</DIV></TD></TR></TABLE>\n};
	}

	print qq{</BODY>\n};
	print qq{</HTML>\n};

	close(FH) if(!$History);
	select(STDOUT);

}


# ----------------------------------------------------------------------------- #
# インデックスファイル作成（見出し部）
# ----------------------------------------------------------------------------- #
sub MakeIndexHeader
{
	my ($History) = shift;
	my ($image);
	my ($width) = ($BBS_WIDTH - $BBS_MARGIN) <= 0 ? '100%' : $BBS_WIDTH - $BBS_MARGIN;

print<<"HEADER";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML LANG="ja">
<HEAD>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=Shift_JIS">
<META HTTP-EQUIV="Content-Style-type" CONTENT="text/css">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<TITLE>$BBS_TITLE</TITLE>
HEADER

	&ReadDefaultStyle('DEF') if ($BBS_USE_HEADER && $BBS_HEADER && -f "$BBS_HEADER");

	print qq{</HEAD>\n};
	print qq{<BODY};
	print qq{ BGCOLOR="$BBS_BGCOLOR"} if($BBS_BGCOLOR);
	print qq{ TEXT="$BBS_TEXT"} if($BBS_TEXT);
	print qq{ LINK="$BBS_LINK"} if($BBS_LINK);
	print qq{ VLINK="$BBS_VLINK"} if($BBS_VLINK);
	print qq{ ALINK="$BBS_ALINK"} if($BBS_ALINK);
	print qq{ BACKGROUND="$BBS_BACKGROUND"} if($BBS_BACKGROUND);
	print qq{>\n};

	if($History) {
		print qq{<TABLE WIDTH="$BBS_WIDTH" BORDER="0" CELLSPACING="0" CELLPADDING="0" SUMMARY="frame">\n};
		print qq{<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">\n};
		print qq{	 <TABLE WIDTH="$width" BORDER="0" CELLSPACING="1" CELLPADDING="2" SUMMARY="frame">\n};
		return;
	}

	# 見出し用ＨＴＭＬが存在するか？
	if ($BBS_USE_HEADER && $BBS_HEADER && -f "$BBS_HEADER") {
		print &ReadDefaultHeader;
		if ($BBS_NAVI) {
			print qq{<TABLE WIDTH="$BBS_WIDTH" BORDER="0" CELLSPACING="0" CELLPADDING="0" SUMMARY="frame">\n};
			print qq{<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">\n};
			print qq{	<DIV ALIGN="CENTER">\n};
			print qq{	<TABLE WIDTH="70%" BORDER="0" CELLSPACING="1" CELLPADDING="2" SUMMARY="frame">\n};
		}
	} else {
		# タイトル設定
		print qq{<TABLE WIDTH="$BBS_WIDTH" BORDER="0" CELLSPACING="0" CELLPADDING="0" SUMMARY="frame">\n};
		print qq{<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width"><DIV ALIGN="CENTER">\n};
		print qq{	 <TABLE WIDTH="80%" BORDER="0" CELLSPACING="1" CELLPADDING="2" SUMMARY="frame">\n};
		print qq{	 <TR><TD COLSPAN="5" BGCOLOR="$BBS_TITLE_BGCOLOR" WIDTH="$BBS_TITLE_WIDTH" HEIGHT="$BBS_TITLE_HEIGHT" VALIGN="BOTTOM">\n};

		if($BBS_TITLE_IMAGE){
			$image = qq{		<IMG SRC="$BBS_TITLE_IMAGE" BORDER="0" align="middle">};
			$image = qq{		<A HREF="$BBS_TITLE_LINK">$image</A>} if ($BBS_TITLE_LINK);
			print "$image\n";
		}

		print qq{	 <FONT SIZE="$BBS_TITLE_SIZE" COLOR="$BBS_TITLE_COLOR"><STRONG>$BBS_TITLE_COMMENT</STRONG></FONT>\n};
		print qq{	 </TD></TR>\n};
		print qq{	 <TR><TD COLSPAN="5" HEIGHT="20" ALIGN="CENTER">\n};
		print qq{		 <BR><FONT COLOR="$BBS_NAME_COLOR" SIZE="$BBS_NAME_SIZE"><STRONG>$BBS_NAME</STRONG></FONT>\n};
		print qq{	 </TD></TR>\n};
	}

	# タイトル部　最下段の変更は下記
	# ---------------------------------------------------------------------------
	if ($BBS_NAVI) {
		print qq{	 <TR BGCOLOR="$BBS_NAVI_BGCOLOR">\n};
		print qq{	 <TD WIDTH="20%" HEIGHT="10" ALIGN="CENTER">\n};
		print qq{		 <FONT COLOR="$BBS_MARK_COLOR">$BBS_BACK_MARK</FONT>\n};
#		print qq{		 <A HREF="$HOME_INDEX">ホームへ</A>\n};
		print qq{		 <A HREF="javascript:window.close()">閉じる</A>\n};
		print qq{	 </TD>\n};
		print qq{	 <TD WIDTH="20%" HEIGHT="10" ALIGN="CENTER">\n};
		print qq{		 <FONT COLOR="$BBS_MARK_COLOR">$BBS_NAVI_MARK</FONT>\n};
		print qq{		 <A HREF="$BBS_SCRIPT?mode=history">過去の記事</A>\n};
		print qq{	 </TD>\n};
		print qq{	 <TD WIDTH="20%" HEIGHT="10" ALIGN="CENTER">\n};
		print qq{		 <FONT COLOR="$BBS_MARK_COLOR">$BBS_NAVI_MARK</FONT>\n};
		print qq{		 <A HREF="$BBS_SCRIPT?mode=find">ＢＢＳ記事検索</A>\n};
		print qq{	 </TD>\n};
		if($MAKE_NEWS && $BBS_NAVI_SITE_SEARCH){
			print qq{	 <TD WIDTH="20%" HEIGHT="10" ALIGN="CENTER">\n};
			print qq{		 <FONT COLOR="$BBS_MARK_COLOR">$BBS_NAVI_MARK</FONT>\n};
			print qq{		 <A HREF="$BBS_SCRIPT?mode=srch">サイト内記事検索</A>\n};
			print qq{	 </TD>\n};
		}
		print qq{	 <TD WIDTH="20%" HEIGHT="10" ALIGN="CENTER">\n};
		print qq{		 <FONT COLOR="$BBS_MARK_COLOR">$BBS_NAVI_MARK</FONT>\n};
		print qq{		 <A HREF="$BBS_SCRIPT?mode=admin">スタッフ専用</A>\n};
		print qq{	 </TD>\n};
		print qq{	 </TR>\n};
	}

	print qq{</TABLE><BR></DIV>\n};
}

# ------------------------------------------------------------------------------------------ #
# デフォルト見出しのスタイル定義読込み
# ------------------------------------------------------------------------------------------ #
sub ReadDefaultStyle
{
	my ($flag, $start) = (0, 0);
	my ($html);

	return if(!$BBS_HEADER);

	# 見出し用HTMLの読込み
	open(IN, $BBS_HEADER) or return;

	while (<IN>) {
		chomp;
		if ( $_ =~ /<STYLE/i ) { $flag = 1;
		} elsif ( $flag && $_ =~ /<!--/ ) { $start = 1;
		} elsif ( $flag && $start && $_	 =~ /-->/ ) { $start = 0;
		} elsif ( $flag && $start) { push @BBS_STYLE, $_;
		} elsif ( $_ =~ /<BODY/i) { last;
		}
	}
	close IN;

}

# ------------------------------------------------------------------------------------------ #
# デフォルト見出しの読込み
# ------------------------------------------------------------------------------------------ #
sub ReadDefaultHeader
{
	my ($flag) = 0;
	my ($html);

	# 見出し用HTMLの読込み
	open IN, $BBS_HEADER;
	while (<IN>) {
		if ( $_ =~ /<BODY/i ) { $flag = 1;
		} elsif ( $_	=~ /^<\/BODY/i ) { last;
		} elsif ( $flag ) { $html .= $_;
		}
	}
	close IN;

	return $html;
}


# ----------------------------------------------------------------------------- #
# 掲示板記事部作成
# ----------------------------------------------------------------------------- #
sub MakeIndexBody
{

	my ($Page, $History) = @_;
	my ($first, $count, $skip, $lines);
	my (@line);
	my ($mode) = '';
	my ($log) = 0;

	# 過去ログとの切り分け
	$file = ($History) ? "$BBS_LOG_DIR/$BBS_HIST_FILE" : "$BBS_LOG_DIR/$BBS_LOG_FILE";
	if (!open(IN, "$file")) {
		if ($History) {
			print qq{<DIV ALIGN="CENTER"><BR><FONT SIZE="+1"><STRONG>\n};
			print qq{過去記事は、存在していません。\n};
			print qq{</STRONG></FONT><BR><BR><BR></DIV>\n};
		} else {
			&error( 'データファイルのオープンに失敗しました。');
		}
	}

	$count++ while (<IN>);								# 総投稿数を数える
	$first	= $count - ($Page - 1) * $BBS_PAGE_ROWS;	# 表示したいページの先頭の投稿の行番号
	$skip	= $first - $BBS_PAGE_ROWS;					# スキップしなければならない行数
	$skip	= $skip < 0 ? 0 : $skip;					# スキップする行数がマイナスになるのを防ぐ
	$lines	= $first - $skip;							# 実際に表示される投稿の数 0 < $lines <= $
	seek(IN,0,0);										# ファイルを巻き戻す
	<IN> while($skip--);								# 目的の行まで読み飛ばす
														# 必要なだけ@lineに押し込む。
	unshift(@line, scalar(<IN>)) while($lines-- > 0); 
	close(IN);

	print qq{<A NAME="BODYTOP"></A>\n} if($Page == 1 && $first);

	foreach(@line) {
		chomp;
		my ($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip) = split(/<>/);
		$title = '無題' if(!$title);
		$date = &FormatDate($date);
		$name = "<A HREF=\"mailto:$mail\">$name</A>" if($mail);
		$comment =~ s/(https?:\/\/[\w\/\.\-\?\=\~\&\$\#]+)/<A HREF="$1">$1<\/A>/ig;
	
		&MakeIndexBody1($no, $date, $name, $mail, $title, $comment, $url, $image);
	}

	# 次ページ／前ページ設定
	if(!$History && !$BBS_READONLY){
		if(($count > $BBS_PAGE_ROWS) || ($Page > 1)){
			print qq{<TABLE BORDER="0" SUMMARY="frame"><TR><TD>\n};
			if($Page == 1){
				print qq{<FORM ACTION="$BBS_HTML_URL/$BBS_HTML_FILE2"><INPUT TYPE="submit" VALUE=" 次ページ "></FORM></TD>\n};
			} else {
				print qq{<FORM ACTION="$BBS_HTML_URL/$BBS_HTML_FILE1"><INPUT TYPE="submit" VALUE=" 前ページ "></FORM></TD>\n};
			}
		} else {
			print qq{<TABLE BORDER="0" SUMMARY="frame"><TR><TD>&nbsp;</TD>\n};
		}
		print qq{</TR></TABLE>\n};
	} else {
		$mode = qq{	 <INPUT TYPE="hidden" NAME="mode" VALUE="history">\n} if(!$BBS_READONLY);

		$Page += 2 if (!$BBS_REVERSE && $BBS_READONLY && $log);
		$next = $Page + 1;
		$prev = $Page - 1;
		print qq{<TABLE BORDER="0" SUMMARY="frame"><TR>\n};
		if ($BBS_READONLY) {
			if ($Page > 1) {
				print qq{<TD ALIGN="LEFT">\n};
				if ($Page == 2) {
					print qq{<FORM ACTION="$BBS_HTML_URL/index.html">\n};
				} else {
					print qq{<FORM ACTION="$BBS_HTML_URL/index$prev\.html">\n};
				}
				print qq{	 <INPUT TYPE="submit" VALUE=" 前ページ ">\n};
				print qq{	 </FORM>\n};
				print qq{</TD>\n};
			}

			if ($Page < $BBS_PAGE_ROWS) {
				print qq{<TD ALIGN="LEFT">\n};
				print qq{<FORM ACTION="$BBS_HTML_URL/index$next\.html">\n};
				print qq{	 <INPUT TYPE="submit" VALUE=" 次ページ ">\n};
				print qq{</FORM>\n};
				print qq{</TD>\n};
			}
		} else {
			if ($Page > 1) {
				print qq{<TD ALIGN="LEFT">\n};
				print qq{	 <FORM ACTION="$BbsScript" METHOD="POST" target="_parent">\n};
				print qq{	 <INPUT TYPE="submit" VALUE=" 前ページ ">\n};
				print qq{	 <INPUT TYPE="hidden" NAME="page" VALUE="$prev">\n$mode\n};
				print qq{	 </FORM>\n};
				print qq{</TD>\n};
			}
			if ($count > ($Page * $BBS_PAGE_ROWS)) {
				print qq{<TD ALIGN="LEFT">\n};
				print qq{<FORM ACTION="$BbsScript" METHOD="POST" target="_parent">\n};
				print qq{	 <INPUT TYPE="submit" VALUE=" 次ページ ">\n};
				print qq{	 <INPUT TYPE="hidden" NAME="page" VALUE="$next">\n$mode\n};
				print qq{</FORM>\n};
				print qq{</TD>\n};
			}
		}
		print qq{</TR></TABLE>\n};
	}
}

# HTML　記事部作成（画像掲示板）
# ------------------------------------------------------------------------------
sub MakeIndexBody1
{

	my ($No, $Date, $Name, $Mail, $Title, $Comment, $Url, $Image) = @_;

	my $idx;
	my $count;
	my $line;
	my $html;
	my $html1;
	my $html2;

	my ($nimg_dir, $nimg_url, $simg_dir, $simg_url);

	print qq{<A NAME="NEWSTOP"></A>\n};
	print qq{<TABLE BORDER="0" WIDTH="100%" CELLPADDING="2">\n};
	print qq{<TR>\n};
	print qq{<TD BGCOLOR="$BBS_HEAD_BGCOLOR">\n};
	print qq{<FONT COLOR="$BBS_MARK_COLOR">$BBS_HEAD_MARK</FONT>\n};
	print qq{<FONT COLOR="$BBS_HEAD_COLOR"><STRONG>$Title</STRONG></FONT></TD>\n};
	print qq{</TR></TABLE>\n};

	print qq{<TABLE><TR>\n};
	print qq{<TD WIDTH="10">&nbsp;</TD>\n};
	print qq{<TD ALIGN="LEFT"><FONT SIZE="-1">＞＞ $Date</FONT></TD>\n};
	if ( !$Mail ) {
		print qq{<TD><FONT SIZE="-1">$Name</FONT></TD>\n};
	} else {
		print qq{<TD><FONT SIZE="-1"><A HREF="mailto:$Mail">$Name</A></FONT></TD>\n};
	}
	print qq{</TR></TABLE>\n};

	print qq{<TABLE BORDER="0" WIDTH="100%" CELLPADDING="2">\n};
	print qq{<TR>\n};

	if ($Image && -f "$BBS_IMG_DIR/$Image") {
		$nimg = "$Image";
		$simg = "s$Image";

		$simg = $nimg unless ( -f "$BBS_IMG_DIR/s$Image");

		print qq{<TD WIDTH="10">&nbsp;</TD>\n};
		print qq{<TD WIDTH="$BBS_IMG_WIDTH">\n};
		print qq{<A HREF="$BBS_IMG_URL/$nimg" TARGET="_new">\n};

		my ($x, $y, $type) = &GetImageSize("$BBS_IMG_DIR/$simg", $BBS_IMG_WIDTH, $BBS_IMG_HEIGHT);

		if ($x && $y) {
			print qq{<IMG SRC="$BBS_IMG_URL/$simg" ALIGN="BOTTOM" BORDER="$BBS_IMG_BORDER" WIDTH="$x" HEIGHT="$y">\n};
		} else {
# 2004/06/01 sasaki modify start
#			print qq{<IMG SRC="$BBS_IMG_URL/$simg" ALIGN="BOTTOM" BORDER="$BBS_IMG_BORDER">\n};
			if($simg =~ /\.pdf$/){
				print qq{<IMG SRC="./images/pdf.gif" ALIGN="BOTTOM" BORDER="$BBS_IMG_BORDER">\n};
			}else{
				print qq{<IMG SRC="$BBS_IMG_URL/$simg" ALIGN="BOTTOM" BORDER="$BBS_IMG_BORDER">\n};
			}
# 2004/06/01 sasaki modify end
		}

		print qq{</A></TD>\n};
		print qq{<TD WIDTH="10">&nbsp;</TD>\n};
		print qq{<TD ALIGN="LEFT" VALIGN="TOP" WIDTH="100%">\n};

		# 自動リンクの処理
# 何かバグってたので直しておきます。2004/03/22 sasaki
#		$Comment =~ s/(https?:\/\/[\w\/\.\-_\?\=\~\#\$]+)/<A HREF="$1">$1<\/A>/ig;

		print qq{<FONT SIZE="-1" COLOR="$BBS_MARK_COLOR">$BBS_BODY_MARK</FONT><FONT SIZE="-1">$Comment</FONT></TD>\n};
		print qq{</TR>\n};

		if ($Url) {
			$Url =~ s/^https?:\/\///ig;
			print qq{<TR><TD COLSPAN="4">\n};
			print qq{<FONT SIZE="-1">$BBS_LINK_MARK<A HREF="http://$Url" target="">http://$Url</A></FONT>\n};
			print qq{</TD></TR>\n};
		}
		print qq{</TABLE>\n};
	} else {

		print qq{<TD WIDTH="100%"><BLOCKQUOTE>\n};
		# 自動リンクの処理
# 何かバグってたので直しておきます。2004/03/22 sasaki
#		$Comment =~ s/(https?:\/\/[\w\/\.\-_\?\=\~\#\$]+)/<A HREF="$1">$1<\/A>/ig;
		print qq{<FONT SIZE="-1" COLOR="$BBS_MARK_COLOR">$BBS_BODY_MARK</FONT><FONT SIZE="-1">$Comment</FONT>\n};
		print qq{</BLOCKQUOTE>\n};

		if ($Url) {
			$Url =~ s/^https?:\/\///ig;
			print qq{<BR><FONT SIZE="-1">$BBS_LINK_MARK<A HREF="http://$Url" target="">http://$Url</A></FONT>\n};
		}

		print qq{</TD>\n};
		print qq{</TR></TABLE>\n};
	}
	print qq{$BBS_HR\n};
}

# パスワード入力画面作成
# ------------------------------------------------------------------------------
sub disp_passform
{

	my ($width) = ($BBS_WIDTH) ? $BBS_WIDTH - $BBS_MARGIN : '100%';

print<<"EOM";
Content-type: text/html

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<TITLE>$BBS_TITLE</TITLE>
</HEAD>
<BODY TEXT="$BBS_TEXT" LINK="$BBS_LINK" ALINK="$BBS_LINK" VLINK="$BBS_VLINK" BGCOLOR="$BBS_BGCOLOR" BACKGROUND="$BBS_BACKGROUND">
<TABLE BORDER="0" WIDTH="$BBS_WIDTH" CELLPADDING="0" CELLSPACING="0">
<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">
<FONT SIZE="-1" COLOR="$BBS_MARK_COLOR">$BBS_BACK_MARK</FONT>
<FONT SIZE="-1"><A HREF="$BBS_HTML_URL/$BBS_HTML_FILE1?">掲示板へ戻る</A></FONT>
<TABLE WIDTH="100%">
<TR>
<TH BGCOLOR="$BBS_TITLE_BGCOLOR">
<FONT COLOR="$BBS_TITLE_COLOR">管理入室画面</FONT>
</TH>
</TR>
</TABLE>
<BR>
<DIV ALIGN="CENTER">
<B>管理用パスワードを入力して下さい。</B>
<FORM ACTION="$BBS_SCRIPT" METHOD="POST">
<INPUT TYPE="RADIO" NAME="action" VALUE="entry" checked><B>記事作成</B>
<INPUT TYPE="RADIO" NAME="action" VALUE="edit"><B>編集／削除</B><P>
<INPUT TYPE="PASSWORD" NAME="pass" SIZE="10">
<INPUT TYPE="HIDDEN" NAME="mode" VALUE="admin">
<INPUT TYPE="SUBMIT" VALUE=" 認証 ">
</FORM>
EOM

	if ($MAKE_NEWS) {
		print qq{<BR>$BBS_HR<BR>\n};
		print qq{◆<A HREF="$NEWS_SCRIPT"><B>記事作成はこちらから</B></A>◆\n};
	}

	print qq{</DIV>\n};
	print qq{</TD></TR></TABLE>\n};
	print qq{</BODY>\n};
	print qq{</HTML>\n};
	
	exit;
}

# 編集／削除画面作成
# ------------------------------------------------------------------------------
sub disp_newslist
{

	my $html;
	my $list;
	my ($no, $date, $name, $mail, $title, $comment, $url, $ip);
	my ($width) = ($BBS_WIDTH) ? $BBS_WIDTH - $BBS_MARGIN : '100%';

print<<"EOM";
Content-type: text/html

<HTML>
<HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
  <TITLE>$BBS_TITLE</TITLE>
</HEAD>

<BODY BGCOLOR="$BBS_BGCOLOR" TEXT="$BBS_TEXT" LINK="$BBS_LINK" VLINK="$BBS_VLINK" ALINK="$BBS_ALINK" BACKGROUND="$BBS_BACKGROUND">
<TABLE BORDER="0" WIDTH="$BBS_WIDTH" CELLPADDING="0" CELLSPACING="0">
<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">
<FONT SIZE="-1" COLOR="$BBS_MARK_COLOR">$BBS_BACK_MARK</FONT>
<FONT SIZE="-1"><A HREF="$BBS_HTML_URL/$BBS_HTML_FILE1?">掲示板へ戻る</A></FONT>
<TABLE WIDTH="100%">
<TR>
<TH BGCOLOR="$BBS_TITLE_BGCOLOR"><FONT COLOR="$BBS_TITLE_COLOR">管 理 画 面</FONT></TH>
</TR>
</TABLE>

<TABLE>
<TR>
<TD>
<UL>
<LI>記事を削除する場合はチェックボックスにチェックを入れ、削除ボタンを押して下さい。
<LI>記事を編集する場合は、<B>管理No.</B> をクリックすると編集画面となります。
</UL>
</TD>
</TR>
</TABLE>

<FORM ACTION="$BBS_SCRIPT" METHOD="POST">
<P><DIV ALIGN="CENTER">
<INPUT TYPE="HIDDEN" NAME="pass" VALUE="$FORM{'pass'}">
<INPUT TYPE="HIDDEN" NAME="mode" VALUE="delete">
<INPUT TYPE="SUBMIT" VALUE="記事を削除する">
<INPUT TYPE="RESET" VALUE="リセット">
</DIV></P>

<DIV ALIGN="CENTER">
<TABLE BORDER="1">
<TR>
<TH>削除</TH>
<TH>日付</TH>
<TH>管理No.</TH>
<TH>タイトル</TH>
<TH>コメント</TH>
<TH>投稿者</TH>
</TR>
EOM

	open FH, "$BBS_LOG_DIR/$BBS_LOG_FILE" || &error( "ログファイルのオープンに失敗しました。" );
	my @logs = <FH>;
	close FH;

	foreach $list (reverse(@logs)) {
		chomp $list;
		($no, $date, $name, $mail, $title, $comment, $url, $ip) = split( /<>/, $list);
	
		print qq{<TR>\n};
		print qq{<TH><INPUT TYPE="CHECKBOX" NAME="del" VALUE="$no"></TH>\n};
		print qq{<TD NOWRAP><SMALL>$date</SMALL></TD>\n};
		print qq{<TH><A HREF="$BBS_SCRIPT?mode=edit&edit=$no&pass=$FORM{'pass'}">$no</A></TH>\n};
		print qq{<TD><SMALL><B>$title</B></SMALL></TD>\n};
		$comment =~ s/<BR>/&nbsp;&nbsp;/i;
		if (length($comment) > 60 ) { $comment = &zsubstr($comment, 0, 30). '..'; }
		print qq{<TD><SMALL>$comment</SMALL></TD>\n};
		print qq{<TD><SMALL>$name</SMALL></TD>\n};
		print qq{</TR>\n};
	}

	print qq{</TABLE>\n};
	print qq{</DIV>\n};
	print qq{</FORM>\n};
	print qq{</TD></TR></TABLE>\n};
	print qq{</BODY>\n};
	print qq{</HTML>\n};

}

# 削除処理（記事１件）
# ------------------------------------------------------------------------------
sub del_news
{

	my @LINES;
	my $line;
	my $del;
	my ( $img, $simg );
	
		
	open FH, "+<$BBS_LOG_DIR/$BBS_LOG_FILE" || &error( "ログファイルのオープンに失敗しました。");

	flock(FH, 2) if($lock);

	foreach $line (<FH>) {

		# 管理番号の取得
		my ( $no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip ) = split( /<>/, $line);
		
		$del = 0;
		if ( $no eq $FORM{'no'} ) { 
			if ( $key eq $FORM{'key'} ) {
				$del = 1;

				# 画像があれば、一緒に削除
				if ($image) {
					$img = "$BBS_IMG_DIR/$image";
					$simg = "$BBS_IMG_DIR/s$image";

					unlink "$img"	if ( -f "$img" );
					unlink "$simg"	if ( -f "$simg");
				}
			} else {
				close FH;
				&error( "削除キーが違います。");
			}
		}
		
		push @LINES, $line if( $del != 1 );
	}

	truncate(FH, 0);	# ファイルの切詰め
	seek(FH, 0, 0);  	# ファイルへの書き込み位置を最初に移動させる

	print FH $_ foreach (@LINES);

	close FH;

}

# 削除処理
# ------------------------------------------------------------------------------
sub del_newslist
{

	my @LINES;
	my $line;
	my $del;
	my ( $img, $simg );

	# パスワードチェック
	if ( $FORM{'pass'} ne $admin ) { &error( "パスワードが違います。" ); }

	open FH, "+<$BBS_LOG_DIR/$BBS_LOG_FILE" || &error( "ログファイルのオープンに失敗しました。");
	flock( FH, 2) if ($lock);

	foreach $line (<FH>) {

		# 管理番号の取得
		my ( $no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip ) = split( /<>/, $line);

		$del = 0;
		foreach (@DEL) {
			if ( $no == $_ ) { 
				$del = 1;

				# 画像があれば、一緒に削除
				if ($image) {
					$img = "$BBS_IMG_DIR/$image";
					$simg = "$BBS_IMG_DIR/s$image";

					unlink "$img" if ( -f "$img"  );
					unlink "$simg" if ( -f "$simg" );
				}
				last;
			}
		}

		push @LINES, $line if( $del != 1 );
	}

	truncate(FH, 0);	# ファイルの切詰め
	seek(FH, 0, 0);  	# ファイルへの書き込み位置を最初に移動させる

	print FH $_ foreach(@LINES);

	close FH;

	&MakeIndexFile($_) for(1..2);
	&MakeHeadLine;
	&location;

}

# 登録フレーム表示処理
# ------------------------------------------------------------------------------
sub disp_entryframe
{

	print qq{Content-type: text/html\n\n};
	print qq{<HTML>\n};
	print qq{<HEAD><TITLE>$BBS_TITLE</TITLE></HEAD>\n};
	print qq{<FRAMESET ROWS="65%,*">\n};
	if ($FORM{'mode'} eq 'reply' ) {
		print qq{<FRAME NAME="entry" src="$BBS_SCRIPT?mode=entform&pass=$FORM{'pass'}&no=$FORM{'no'}">\n};
	} elsif ($FORM{'mode'} eq 'upform' ) {
		$FORM{'name'} =~ s/#/-sSs-/g;
		$FORM{'mail'} =~ s/#/-sSs-/g;
		$FORM{'title'} =~ s/#/-sSs-/g;
		$FORM{'url'} =~ s/#/-sSs-/g;
		print qq{<FRAME NAME="entry" src="$BBS_SCRIPT?mode=entform2&pass=$FORM{'pass'}&name=$FORM{'name'}&mail=$FORM{'mail'}&title=$FORM{'title'}&url=$FORM{'url'}">\n};
	} else {
		print qq{<FRAME NAME="entry" src="$BBS_SCRIPT?mode=entform&pass=$FORM{'pass'}">\n};
	}
	print qq{<FRAME NAME="news" src="$BBS_HTML_URL/$BBS_HTML_FILE1#NEWSTOP">\n};
	print qq{</FRAMESET>\n</HTML>\n};
	exit;

}

# 登録画面表示処理
# ------------------------------------------------------------------------------
sub disp_entryform
{

	# パスワードチェック
	if ( $FORM{'pass'} ne $admin ) { &error( "パスワードが違います。" ); }

	my $html;
	my $enctype, $cookie;
	my ( $date, $name, $mail, $title, $comment, $url, $image, $key, $ip );
	
	if( $FORM{'mode'} eq 'entform2') {
		$name  = $FORM{'name'};
		$mail  = $FORM{'mail'};
		$title = $FORM{'title'};
		$url   = $FORM{'url'};
		
		# 文字化け用デコード
		$name =~ s/-sSs-/#/g;
		$mail =~ s/-sSs-/#/g;
		$title =~ s/-sSs-/#/g;
		$url =~ s/-sSs-/#/g;
		$url =~ s/^http:\/\///;
	} else {
		$name = $COOKIES{'name'};
		$mail = $COOKIES{'mail'};
	}

	$enctype = 'ENCTYPE="multipart/form-data"';

	$date = &MakeFormatDate($BBS_DATE_FORMAT);
	if ($FORM{'no'}) {
		my ($retitle, $recomment) = &get_replynews;

		$title = "Re:[$FORM{'no'}] $retitle";
		$comment = "> $recomment";
		$comment =~ s/<BR>/\n> /ig;
	}
	$cookie = qq{<INPUT TYPE="HIDDEN" NAME="cookie" VALUE="no">\n} if( $FORM{'mode'} eq 'entform2');

	# 投稿用画面の表示
print<<"EOM";
Content-type: text/html

<HTML>
<HEAD>
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
  <TITLE>$BBS_TITLE</TITLE>
</HEAD>
<BODY BGCOLOR="$BBS_BGCOLOR" TEXT="$BBS_TEXT" LINK="$BBS_LINK" VLINK="$BBS_VLINK" ALINK="$BBS_ALINK" BACKGROUND="$BBS_BACKGROUND">
<TABLE width="$BBS_WIDTH"><TR><TD>
<DIV ALIGN="CENTER">
<FORM ACTION="$BBS_SCRIPT" METHOD="POST" target="_parent" $enctype>
<INPUT TYPE="HIDDEN" NAME="mode" VALUE="regist">
<INPUT TYPE="HIDDEN" NAME="pass" VALUE="$FORM{'pass'}">
$cookie
投稿する記事を以下のフォームに記入し、「投稿する」ボタンを押してください。
<BR><BR>
<TABLE BORDER="1">
<TR><TD NOWRAP><FONT SIZE="-1"><STRONG>日　付</STRONG></FONT></TD>
<TD><INPUT TYPE="TEXT" NAME="date" Value="$date" size="40"></TD></TR>
<TR><TD NOWRAP><FONT SIZE="-1"><STRONG>お名前</STRONG></FONT></TD>
<TD><INPUT TYPE="TEXT" NAME="name" Value="$name" size="30"></TD></TR>
<TR><TD NOWRAP><FONT SIZE="-1"><STRONG>メール</STRONG></FONT></TD>
<TD><INPUT TYPE="TEXT" NAME="mail" Value="$mail" size="30"></TD></TR>
<TR><TD NOWRAP><FONT SIZE="-1"><STRONG>タイトル</STRONG></FONT></TD>
<TD><INPUT TYPE="TEXT" NAME="title" Value="$title" size="40">　
<INPUT TYPE="SUBMIT" VALUE=" 投稿する "><INPUT TYPE="RESET" VALUE=" リセット "><TD></TR>
<TR><TD COLSPAN="2"><FONT SIZE="-1"><STRONG>コメント：</STRONG></FONT><BR>
<TEXTAREA NAME="comment" COLS="65" ROWS="6" WRAP="$BBS_WRAP">$comment</TEXTAREA></TD></TR>
<TR><TD NOWRAP><STRONG>ＵＲＬ</STRONG></TD>
<TD><INPUT TYPE="TEXT" NAME="url" SIZE="78" VALUE="http://$url"></TD></TR>
EOM

	# MODIFY 2003.09.14
	if ($BBS_IMAGE_USE == 1) {
		print "<TR><TD NOWRAP><STRONG>画像ファイル</STRONG></TD>\n";
		print "<TD><INPUT TYPE=\"file\" NAME=\"path\" SIZE=\"50\"></TD></TR>\n";
	}
	# MODIFY END

print<<"EOM";
</TABLE>
</FORM>
</DIV>
</TD></TR></TABLE></BODY>
</HTML>
EOM

}

# 修正画面表示処理
# ------------------------------------------------------------------------------
sub disp_editform
{

	my $html;
	my ( $no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip );
	my ($enctype);
	my ($width) = ($BBS_WIDTH) ? $BBS_WIDTH - $BBS_MARGIN : '100%';


	open (FH, "$BBS_LOG_DIR/$BBS_LOG_FILE") || &error("ログファイルのオープンに失敗しました。");
		
	foreach $line (<FH>) {
		( $no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip ) = split( /<>/, $line);
		last if ( $no eq $FORM{'edit'} );
	}
	close FH;

	&error("修正記事が見つかりません。") if ( $no ne $FORM{'edit'} );

	$enctype = 'ENCTYPE="multipart/form-data"' if (!$image);

	# 投稿用画面の表示
	$html  = "Content-type: text/html\n\n";
	$html .= "<HTML>\n";
	$html .= "<HEAD>\n";
	$html .= '  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">'. "\n";
	$html .= '  <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">'."\n";
	$html .= "  <TITLE>$BBS_TITLE</TITLE>\n";
	$html .= "</HEAD>\n";

	$html .= "<BODY BGCOLOR=\"$BBS_BGCOLOR\" TEXT=\"$BBS_TEXT\" LINK=\"$BBS_LINK\" VLINK=\"$BBS_VLINK\" ALINK=\"$BBS_ALINK\" BACKGROUND=\"$BBS_BACKGROUND\">\n";
	$html .= "<TABLE WIDTH=\"$BBS_WIDTH\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n";
	$html .= "<TR><TD WIDTH=\"$BBS_MARGIN\"></TD><TD WIDTH=\"$width\">\n";
	$html .= "<FONT SIZE=\"-1\" COLOR=\"$BBS_MARK_COLOR\">$BBS_BACK_MARK</FONT>\n";
	$html .= "<FONT SIZE=\"-1\"><A HREF=\"$BBS_HTML_URL/$BBS_HTML_FILE1?\">掲示板へ戻る</A></FONT>\n";

	$html .= "<CENTER>\n";	
	$html .= "<TABLE WIDTH=\"100%\" CELLPADDING=\"0\" CELLSPACING=\"0\">\n";
	$html .= '<TR>'."\n";
	$html .= "<TH BGCOLOR=\"$BBS_TITLE_BGCOLOR\">\n";
	
	$html .= "<FONT COLOR=\"$BBS_TITLE_COLOR\">編 集 画 面</FONT>\n";
	$html .= '</TH>'."\n";
	$html .= '</TR>'."\n";
	$html .= '</TABLE>'."\n";

	$html .= "<FORM ACTION=\"$BBS_SCRIPT\" METHOD=\"POST\" $enctype>\n";
	
	$html .= "<INPUT TYPE=\"HIDDEN\" NAME=\"mode\" VALUE=\"update\" >\n";
	$html .= "<INPUT TYPE=\"HIDDEN\" NAME=\"pass\" VALUE=\"$FORM{'pass'}\">\n";
	$html .= "<INPUT TYPE=\"HIDDEN\" NAME=\"no\" VALUE=\"$no\">\n";

	$html .= '編集する部分のみ書き換え、編集ボタンを押して下さい。';
	$html .= "<P>\n";
	$html .= "<TABLE BORDER=\"1\">\n";
	
	$html .= "<TR><TD NOWRAP><FONT SIZE=\"-1\"><B>日　付</B></FONT></TD>\n";
	$html .= "<TD><INPUT TYPE=\"TEXT\" NAME=\"date\" Value=\"$date\" size=\"40\"></TD></TR>\n";

	$html .= "<TR><TD NOWRAP><FONT SIZE=\"-1\"><B>お名前</B></FONT></TD>\n";
	$html .= "<TD><INPUT TYPE=\"TEXT\" NAME=\"name\" Value=\"$name\" size=\"30\"></TD></TR>\n";
	
	$html .= "<TR><TD NOWRAP><FONT SIZE=\"-1\"><B>メール</B></FONT></TD>\n";
	$html .= "<TD><INPUT TYPE=\"TEXT\" NAME=\"mail\" Value=\"$mail\" size=\"30\"></TD></TR>\n";

	$html .= "<TR><TD NOWRAP><FONT SIZE=\"-1\"><B>タイトル</B></FONT></TD>\n";
	$html .= "<TD><INPUT TYPE=\"TEXT\" NAME=\"title\" Value=\"$title\" size=\"40\">　";
	$html .= "<INPUT TYPE=\"SUBMIT\" VALUE=\" 編集する \"><INPUT TYPE=\"RESET\" VALUE=\" リセット \"><TD></TR>\n";

	$html .= "<TR><TD COLSPAN=\"2\"><FONT SIZE=\"-1\"><B>コメント：</B></FONT><BR>\n";
	
	$comment =~ s/<BR>/\n/ig;
	
	$html .= "<TEXTAREA NAME=\"comment\" COLS=\"65\" ROWS=\"6\" WRAP=\"$wrap\">$comment</TEXTAREA></TD></TR>";
	
	$html .= "<TR><TD NOWRAP><B>ＵＲＬ</B></TD>\n";
	$html .= "<TD><INPUT TYPE=\"TEXT\" NAME=\"url\" SIZE=\"78\" VALUE=\"http://$url\"></TD></TR>\n";

	$html .= "<TR><TD NOWRAP><B>画像ファイル</B></TD>\n";
	if ($image) {
		$html .= "<TD>画像ファイルあり</TD></TR>\n";
	} else {
		$html .= "<TD><INPUT TYPE=\"file\" NAME=\"path\" SIZE=\"50\"></TD></TR>\n";
	}

	$html .= "</TABLE>\n";
	$html .= "</FORM>\n";

	$html .= "</CENTER>\n";
	$html .= "</TD></TR></TABLE>\n";
	
	$html .= "</BODY>\n";
	$html .= "</HTML>\n";

	print "$html";

}

# 投稿記事登録処理
# ------------------------------------------------------------------------------
sub regist_newsdata
{

	my $no;
	my $dummy;
	my $log;
	my @logs;
	my $key;
	my $image_path;
	my $count;
	my $upper;
	my $lower;
	

#	&check_formitem;
	# パスワードチェック
	if ( $FORM{'pass'} ne $admin ) { &error( "パスワードが違います。" ); }

	open (FH, "+<$BBS_LOG_DIR/$BBS_LOG_FILE") or &error( "ログファイルのオープンに失敗しました。");
	flock(FH, 2) if( $lock );

	@logs = <FH>;

	my ($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip ) = split(/<>/, $logs[$#logs] );
	$no++;

	chomp($ip);

	if ($d_regist) {
		if ($name eq $FORM{'name'} && $mail eq $FORM{'mail'} && $title eq $FORM{'title'} && $comment eq $FORM{'comment'} && $ip eq $IpAddr ) {
			&error( '二重投稿は、禁止されています。');
		}
	}

	# urlの[http://]を消す。
	$FORM{'url'} =~ s/https?:\/\///ig;

	$image_path = $FORM{'image'};


	$title = "無題" if( !$title );

	$log = join( '<>', $no, $FORM{'date'}, $FORM{'name'}, $FORM{'mail'}, $FORM{'title'}, $FORM{'comment'}, $FORM{'url'}, $image_path, $key, $IpAddr );


	truncate(FH, 0);	# ファイルの切詰め
	seek(FH, 0, 0);  	# ファイルへの書き込み位置を最初に移動させる

	push(@logs, "$log\n");

	$upper = $#logs;
	$lower = $upper < ($BBS_PAGE_ROWS * 2 - 1 ) ? 0 : $upper - $BBS_PAGE_ROWS * 2 + 1;

	print FH $logs[$_] for ($lower .. $upper);
	close FH;

	# 過去ログへ
	if($lower > 0){
		open(FH, ">> $BBS_LOG_DIR/$BBS_HIST_FILE");
		print FH $logs[$_] for( 0..$lower - 1 );
		close FH;
	}

	$COOKIES{'name'} = $FORM{'name'};
	$COOKIES{'mail'} = $FORM{'mail'};


	# 記事作成からの場合は、クッキーおあずけ
	if ($FORM{'cookie'} ne 'no') { &set_cookie;}

	&MakeIndexFile($_) for(1..2);
	&MakeHeadLine;
	&location;

}

# 投稿記事修正処理
# ------------------------------------------------------------------------------
sub update_newsdata
{

	my $no;
	my $dummy;
	my $log;
	my @logs;
	my $key;
 	my $image_path;
	
#	&check_formitem;
	
	# パスワードチェック
	if ( $FORM{'pass'} ne $admin ) { &error( "パスワードが違います。" ); }

	open FH, "+<$BBS_LOG_DIR/$BBS_LOG_FILE" or error( "ログファイルのオープンに失敗しました。");
	flock(FH, 2) if( $lock == 1 );

	foreach $log (<FH>) {
		($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip ) = split(/<>/, $log );
		if ($no ne $FORM{'no'}) {
			push @logs, $log;
		} else {
			$FORM{'url'} =~ s/http:\/\///ig;
			$image_path = ($FORM{'image'}) ? $FORM{'image'} : $image;
			$log = join( '<>', $no, $FORM{'date'}, $FORM{'name'}, $FORM{'mail'}, $FORM{'title'}, $FORM{'comment'}, $FORM{'url'}, $image_path, $key, $IpAddr ); 
			push @logs, "$log\n";
		}
	}

	truncate(FH, 0);	# ファイルの切詰め
	seek(FH, 0, 0);  	# ファイルへの書き込み位置を最初に移動させる

	foreach $log (@logs) {
		print FH $log;
	}
	
	close FH;

	&MakeIndexFile($_) for(1..2);
	&MakeHeadLine;
	&location;

}

# Cookieの値を読み出す
# ------------------------------------------------------------------------------
sub get_cookie {

	my ($key, $val);
	
	
	if ( $ENV{'HTTP_COOKIE'} ne '' ){
		foreach ( split(/\s*;\s*/,$ENV{'HTTP_COOKIE'}) ){
			foreach ( split(/\,/,$_) ){
				my ($key,$val) = split(/=/,$_);
				$val =~ tr/+/ /;
				$val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
				$COOKIES{$key} = $val;
			}
		}
	}
}

# Cookieに値を書き込むためのSet-Cookie:ヘッダを生成する
# ------------------------------------------------------------------------------
sub set_cookie {
	
	my($tmp, $key, $val);
	
	$tmp = '';
	while (($key, $val) = each %COOKIES) {
	
		$val =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		if ($tmp ne '' ) { $tmp .= ','; }
		$tmp .= "$key=$val";
	}
	
	$tmp = "Set-Cookie: ". $tmp;
	$tmp .= "; ";
		
	$tmp .= "expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";
	
	print "Content-type: text/html\n";
	print "$tmp";
	
}


# 表示用日付の取得を行なう。
# ------------------------------------------------------------------------------
sub getformatdate {

	my $dsp_date;

	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	my @weekday_j = ( '日', '月', '火', '水', '木', '金', '土' );
	my @weekday = ( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu','Fri','Sat');


	if ( $date_format == 0 ) {
		# 洋式
		$dsp_date = sprintf( "%04d/%02d/%02d(%s) %02d:%02d", $year + 1900, $mon + 1, $mday, $weekday[$wday], $hour, $min );
	} elsif ( $date_format == 1 ) {
		# 和式
		$dsp_date = sprintf( "%04d年%02d月%02d日（%s）%02d時%02d分", $year + 1900, $mon + 1, $mday, $weekday_j[$wday], $hour, $min );
	} else {
		# 短い形式
		$dsp_date = sprintf( "%04d/%02d/%02d %02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min );
	}
	
	return $dsp_date;

}


# 表示用日付のフォーマット指示に従い作成を行う。
# ------------------------------------------------------------------------------
sub MakeFormatDate {

	my ($fdate) = shift;

	my ($y, $m, $d, $h, $n, $s, $j, $w);
	my ($f_y, $f_m, $f_d, $f_h, $f_n, $f_s, $f_j, $f_w);
	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
	my @weekday_j = ( '日', '月', '火', '水', '木', '金', '土' );
	my @weekday = ( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday','Friday','Saturday');

	$y = $1 if($fdate =~ m/(y+)/go);
	$m = $1 if($fdate  =~ m/(m+)/go);
	$d = $1 if($fdate  =~ m/(d+)/go);

	$h = $1 if($fdate  =~ m/(h+)/go);
	$n = $1 if($fdate  =~ m/(n+)/go);
	$s = $1 if($fdate  =~ m/(s+)/go);

	$w = $1 if($fdate  =~ m/(w+)/go);
	$j = $1 if($fdate  =~ m/(j+)/go);

	$f_y = (length($y) == 2) ? sprintf("%02d", $year % 100) : sprintf("%04d", $year + 1900);
	$f_m = (length($m) == 1) ? $mon + 1 : sprintf("%02d", $mon + 1);
	$f_d = (length($d) == 1) ? $mday : sprintf("%02d", $mday);

	$f_h = (length($h) == 1) ? $hour : sprintf("%02d", $hour);
	$f_n = (length($n) == 1) ? $min : sprintf("%02d", $min);
	$f_s = (length($s) == 1) ? $sec : sprintf("%02d", $sec);

	if ($w) {
		$f_w = (length($w) == 1) ? substr($weekday[$wday], 0, 3) : $weekday[$wday];
	}
	if ($j) {
		$f_j = (length($j) == 1) ? $weekday_j[$wday] : "$weekday_j[$wday]曜日";
	}

	$fdate =~ s/$y/$f_y/e;
	$fdate =~ s/$m/$f_m/e;
	$fdate =~ s/$d/$f_d/e;

	$fdate =~ s/$h/$f_h/e;
	$fdate =~ s/$n/$f_n/e;
	$fdate =~ s/$s/$f_s/e;

	$fdate =~ s/$w/$f_w/e;
	$fdate =~ s/$j/$f_j/e;

	return $fdate;


}


# バイナリファイルが選択された場合、[Content_Type]より、拡張子の設定を行う。
# /---------------------------------------------------------------------------/
sub check_contenttype {

	my ( $filename, $content_type ) = @_;

	# 画像
	$ext{'image/jpg'}	= 'jpg'; 
	$ext{'image/jpeg'}	= 'jpg'; 	# for NN
	$ext{'image/pjpg'}	= 'jpg';
	$ext{'image/pjpeg'}	= 'jpg';	# for IE
	$ext{'image/gif'}	= 'gif';		# for NN&IE
	$ext{'image/png'}	= 'png';
	
	# その他バイナリ
	$ext{'application/pdf'} = 'pdf';


	foreach $key ( keys %ext ) {
		if( $content_type =~ /$key/ig ) {
			return $ext{$key};
		}
	}
	
	if( $filename=~ /\.gif$/i ) {  return 'gif';}
	if( $filename=~ /\.jpe?g$/i ) { return 'jpg';}
	if( $filename=~ /\.png$/i ) { return 'png';}
	
	return 'unknown';
	
}

# 画像ファイル形式の取得を行なう。
# /---------------------------------------------------------------------------/
sub get_imagetype {

  my $header = shift;

  my $type = "unknown";
  my ($x,$y) = undef,undef;

  if($header =~ /^GIF8[79]a/) {$type = "gif"; }
  if($header =~ /^\xFF\xD8/) { $type = "jpg";  }
  if($header =~ /^\x89PNG\x0D\x0A\x1A\x0A/) { $type = "png"; }
	
  return($type);

}

# ディレクトリ存在チェック
# /---------------------------------------------------------------------------/
sub check_dir
{

	my ($dir) = @_;

	if( -d "$dir" ) {
		return 1;
	} else {
		return 0;
	}

}


# ディレクトリ作成処理
# /---------------------------------------------------------------------------/
sub make_dir
{
	my ($dir) = @_;
	
	umask(0);
	if( mkdir( "$dir" ,0755) ) {
		chmod 0755, "$dir";
		return;
	} else {
		&error("ディレクトリの作成に失敗しました。[$dir]");
	}
}

# 返信用メッセージ作成
# /---------------------------------------------------------------------------/

# サムネール画像の作成
# /---------------------------------------------------------------------------/
sub make_smallimage
{

	my ($file) = shift;

	my @bound;
	my $newImage;
	my $oldImage;
	
	my ($img, $simg);
	
	$img = "$BBS_IMG_DIR/$file";
	$simg = "$BBS_IMG_DIR/s$file";

	if($GD) {
		my ($x, $y, $type) = &GetImageSize($img, $BBS_IMG_WIDTH, $BBS_IMG_HEIGHT);
		if ( $type eq 'jpg' && $x && $y) { 
			open (OLD, "$img") || return;
			# 本当に、GDが使えるか？試しに作ってみる
			eval {$oldImage = newFromJpeg GD::Image(\*OLD)};
			if ($@) {
				close OLD;
				return;
			}

			@bound = $oldImage->getBounds(); 

			$newImage = new GD::Image($x, $y) || return; 

			$newImage->copyResized($oldImage, 0, 0, 0, 0, $x, $y, $bound[0], $bound[1]); 

			open NEW, ">$simg";
			binmode NEW; 
			print NEW $newImage->jpeg($BBS_IMG_QUALITY);

			close OLD;
			close NEW;

			chmod 0755, "$simg";
		}
	}

}

# 新着更新機能追加
# /---------------------------------------------------------------------------/



# ----------------------------------------------------------------------------- #
# 新着メッセージ作成処理
# ----------------------------------------------------------------------------- #
sub MakeHeadLine
{
	my ($ins, $count, $skip);
	my (@lines, $line);
	my ($date_color, $hl_date);
	my @html;
	my @news;
	my ($x, $y, $type);


	my ($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip );
	
	open FH, "$BBS_LOG_DIR/$BBS_LOG_FILE" || &error( 'データファイルのオープンに失敗しました。');

	# 最終行からHL_MAX行取得処理
	$count++ while(<FH>);		# 総件数
	$skip = $count - $HL_MAX;
	$skip = $skip < 0 ? 0 : $skip;

	seek(FH, 0, 0);				# ファイルへの書き込み位置を最初に移動させる

	<FH> while($skip-- > 0);	# 目的の行まで読み飛ばす

	push(@lines, $_) while(<FH>); 
	close(FH);

	foreach(reverse(@lines)) {

		($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip) = split( /<>/, $_, 10);

		$title = '無題' if(!$title);

		if ($image) {
			$simg_dir = "$BBS_IMG_DIR/s$image";
			$simg_url = "$BBS_IMG_URL/s$image";

			unless ( -f $simg_dir) {
				# 縮小画像が無い場合、または、jpeg以外の画像
				$simg_dir = "$BBS_IMG_DIR/$image";
				$simg_url = "$BBS_IMG_URL/$image";
			}

			($x, $y, $type) = &GetImageSize($simg_dir, $BBS_IMG_WIDTH, $BBS_IMG_HEIGHT);
		}

		$color = &GetHeadLineColor($name);

		if($color){
			$date_color = $color;
		} else {
			$date_color = $HL_DATE_COLOR;
		}

		if ($HL_DATE_MARK) {
			$hl_date = $HL_DATE_MARK;
			$hl_date =~ s/[\@\$]DATE/$date/ie;
		}

		push @news, qq{<TR>};

		my  (@hl_text, @hl_img);
		if($url) {
			push @hl_text, qq{<td width="20%" class="nomal"><font color="#FF6600">■</font><A HREF="http://$url" target="miniinfo">$hl_date</A></td>};
			push @hl_text, qq{<td width="80%" class="nomal"><A HREF="http://$url" target="miniinfo">$title</A></td>};
		} else {
			push @hl_text, qq{<td width="20%" class="nomal"><font color="#FF6600">■</font>$hl_date</td>};
			push @hl_text, qq{<td width="80%" class="nomal">$title</td>};
		}
		# 記事内容を表示。
		if($HL_TEXT) {
			push @hl_text, qq{<TD>};
			$str_nobr = $comment;
			$str_nobr =~ s/<BR>//g;	# sasaki add 改行しない
			$str_nobr =~ s/<br>//g;	# sasaki add 改行しない
			$str_nobr = &zsubstr($str_nobr, 0, $HL_TEXT);
			$str = &zsubstr($comment, 0, $HL_TEXT);
			$str_nobr .= '...' if($str ne $comment);

			$HL_TEXT_SIZE = $HL_SIZE if(!$HL_TEXT_SIZE);
			push @hl_text, qq{$str_nobr};
			push @hl_text, qq{</TD>};
		}
		if ($HL_LAYOUT <= 1) {
			push @news, @hl_text;
		} else {
			push @news, @hl_text;
		}
		push @news, qq{</TR>\n};
	}

	# index.htmlの更新
	open FH, "+<$HL_HTML" or &error( "インデックスファイルのオープンに失敗しました。");
	flock( FH, 2 );

	$ins = 1;
	foreach (<FH>) {
		if ($_ =~ /<!-+$HL_FR_SIG-+>/i) {
			$ins = 0;
			push @html, $_;
			push @html, @news;
		} else {
			$ins = 1 if ($_ =~ /<!-+$HL_TO_SIG-+>/);
			push @html, $_ if($ins);
		}
	}

	truncate(FH, 0);	# ファイルの切詰め
	seek(FH, 0, 0);		# ファイルへの書き込み位置を最初に移動させる

	print FH @html;

	close FH;

}

# ----------------------------------------------------------------------------- #
# 新着表示時に使用する表示色を設定
# ----------------------------------------------------------------------------- #
sub GetHeadLineColor()
{

	my ($name) = shift;
	my ($multilbyte) = 0;
	my $idx;

	$multibyte = 1 if ($name =~ /[\x80-\xff]/);

	for($idx = 0; $idx < $#HL_COLOR; $idx = $idx + 2) {

		if($multibyte){
			return $HL_COLOR[$idx + 1] if (index($name, $HL_COLOR[$idx]) != -1);
		} else {
			return $HL_COLOR[$idx + 1] if ($HL_COLOR[$idx] =~ /$name/ );
		}
	}

	return;

}

# ----------------------------------------------------------------------------- #
# 全角で？文字取得
# ----------------------------------------------------------------------------- #
sub zsubstr {

	my($str, $pos, $len) = @_;

	$str =~ s/(.)/$1\0/g;
	$str =~ s/([\x81-\x9f\xe0-\xfc])\0(.)\0/$1$2/g;
	$str = (!$len) ? substr($str, $pos * 2) : substr($str, $pos * 2, $len * 2);
	$str =~ tr/\0//d;

	return $str;
}

# ------------------------------------------------------------------------------------------ #
# ＧＤモジュールのチェック
# ------------------------------------------------------------------------------------------ #
sub CheckGDModule()
{
	# 画像加工モジュール
	# GDモジュールがインストールされていない場合の対処を追加
	# GDモジュール自体が読み込めなかった場合、$GD=0

	eval "use GD";							# 画像加工モジュール
	return (!$@) ? 1 : 0;

}

# ----------------------------------------------------------------------------- #
#  画像ファイルのサイズ取得を行なう。（サイズ指定の場合、同比率のサイズを返す）
# ----------------------------------------------------------------------------- #
sub GetImageSize()
{

	my ($file, $maxx, $maxy ) = @_;
	my ($header, $type, $ratio);
	my ($x, $y);

	# ファイルの存在チェック
	return unless( -f "$file" );

	# 対象ファイルのオープン
	open IN, "$file";

	seek IN, 0 ,0;
	# Windowsでは、バイナリモードで
	binmode(IN);

	# ヘッダー部を読みファイル種別を特定する。
	read IN, $header, 8;
	seek IN, 0, 0;

	# ファイル種別により、処理の振り分け
	if($header =~ /^GIF8[79]a/) {
		$type = "gif";
		($x, $y) = &GetGifSize(\*IN);
	} elsif($header =~ /^\xFF\xD8/) {
		$type = "jpg";
		($x, $y) = &GetJpgSize(\*IN);
	} elsif($header =~ /^\x89PNG\x0D\x0A\x1A\x0A/) {
		$type = "png";
		($x, $y) = &GetPngSize(\*IN);
	} elsif($header =~ /^\x42\x4D/) {
		$type = "bmp";
		($x, $y) = &GetBmpSize(\*IN);
	}

	seek IN, 0, 0;
	close IN;

	if ( $maxx || $maxy ) {
		if ( $x && $y ) {
			if ( $x > $maxx ) {
				$ratio = $maxx / $x;
				if (( $y * $ratio ) <= $maxy ) {
					$x = $maxx;
					$y = $y * $ratio;
				}
			}

			if ( $y > $maxy ) {
				$ratio = $maxy / $y;
				if (( $x * $ratio ) <= $maxx ) {
					$x = $x * $ratio;
					$y = $maxy;
				}
			}

			$x = int $x;
			$y = int $y;
		}
	}

	undef $x if( $x < 0);
	undef $y if( $y < 0);

	return($x, $y, $type);

}

# ----------------------------------------------------------------------------- #
# BMP画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetBmpSize
{

	my ($fh) = shift;
	my ($x, $y) = (undef, undef);
	my $buf;

	# 18バイト目から8バイトを読込む
	seek($fh, 18, 0);
	read($fh, $buf, 8);
	($x, $y) = unpack("V2", $buf);

	return($x, $y);
}

# ----------------------------------------------------------------------------- #
# GIF画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetGifSize()
{

	my ($fh) = shift;
	my ($x, $y) = (undef, undef);
	my $buf;

	# 先頭から 10 バイトを読み込む。
	seek($fh, 0, 0);
	read($fh, $buf, 10);

	# リトルエンディアンの short 
	($x, $y) = unpack("x6 vv", $buf);
	return($x, $y);
}

# ----------------------------------------------------------------------------- #
# PNG画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetPngSize()
{

	my ($fh) = shift;
	my ($x, $y) = (undef,undef);
	my $buf;

	# 先頭から 24 バイト読み込む。
	seek($fh, 0, 0);
	read($fh, $buf, 24);

	($x, $y) = unpack("x16 NN", $buf);
	return($x, $y);
}

# ----------------------------------------------------------------------------- #
# JPG画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetJpgSize
{

	my ($fh) = shift;
	my ($marker, $code, $len);
	my ($x, $y) = (undef, undef);

	# 先頭 2 バイトを読み飛ばす
	read($fh, $buf, 2);

	for(;;){
		my $tmp_marker;

		$len = 4;
		read($fh, $tmp_marker, $len);

		# マーカー,マーカーのサイズ情報を取得
		($marker, $code, $len) = unpack("a a n", $tmp_marker);

		# マーカーの読み飛ばしに失敗? あきらめてループから脱出
		if($marker ne "\xFF") { 
			last;
		} elsif( ord($code) >= 0xC0 && ord($code) <= 0xC3) {
			# サイズ情報が含まれてるマーカーを発見
			my $buf;
			$len = 5;
			read($fh, $buf, $len);
			($y, $x) = unpack("xnn", $buf);
			last;
		} else { 
			# マーカー情報を読み飛ばす、マーカーのサイズ情報自体が含まれてるので 2 引く
			my $tmp;
			read($fh, $tmp, $len - 2);
		}
	}
	return($x, $y);
}
# ------------------------------------------------------------------------------------------ #
# 日付編集処理
# ------------------------------------------------------------------------------------------ #
sub FormatDate {

	my ($Date, $Short) = @_;
	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
	my @weekday_j = ( '日', '月', '火', '水', '木', '金', '土' );
	my @weekday = ( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu','Fri','Sat');

	if($Date){
		($year, $mon, $mday, $hour, $min, $sec) = split(/\/|\s|:/, $Date);
		if ($mon < 3) { --$year; $mon += 12;}
		$wday = ($year + int($year/4) - int($year/100) + int($year/400) + int((13 * $mon + 8) / 5) + $mday ) % 7;
		($year, $mon, $mday, $hour, $min, $sec) = split(/\/|\s|:/, $Date) if($mon > 12);
	} else {
		($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
		$year += 1900;
		$mon += 1;
	}

	if ($Short) {
		if($Bbs){
			return sprintf( "%02d/%02d %02d:%02d", $mon, $mday, $hour, $min);
		} else {
			return sprintf( "%02d/%02d", $mon, $mday);
		}
	} else {
		if($Bbs == 2) {
			if ($DateFormat == 0) {
				# 洋式
				return sprintf( "%04d/%02d/%02d(%s) %02d:%02d:%02d", $year, $mon, $mday, $weekday[$wday], $hour, $min, $sec);
			} elsif ( $DateFormat == 1 ) {
				# 和式
				return sprintf( "%04d年%02d月%02d日（%s） %02d時%02d分%02d秒", $year, $mon, $mday, $weekday_j[$wday], $hour, $min, $sec);
			} else {
				# 短い形式
				return sprintf( "%04d/%02d/%02d %02d:%02d", $year, $mon, $mday, $hour, $min, $sec );
			}
		} else {
			if ($DateFormat == 0) {
				# 洋式
				return sprintf( "%04d/%02d/%02d(%s)", $year, $mon, $mday, $weekday[$wday]);
			} elsif ( $DateFormat == 1 ) {
				# 和式
				return sprintf( "%04d年%02d月%02d日（%s）", $year, $mon, $mday, $weekday_j[$wday]);
			} else {
				# 短い形式
				return sprintf( "%04d/%02d/%02d", $year, $mon, $mday );
			}
		}
	}
}
# ----------------------------------------------------------------------------- #
# 過去ログ用フレーム表示
# ----------------------------------------------------------------------------- #
sub MakeHistoryFrame
{
	my ($Page) = shift;

	$Page = (!$Page) ? 1 : $Page;

print<<"EOM";
Content-type: text/html

<HTML>
<HEAD><TITLE>過去の記事</title></HEAD>
<FRAMESET ROWS="20%,*\">
<FRAME NAME="head" src="$BBS_SCRIPT?mode=histhead&page=$Page" no>
<FRAME NAME="body" src="$BBS_SCRIPT?mode=histbody&page=$Page">
</FRAMESET>
</HTML>
EOM

	exit;

}

# ----------------------------------------------------------------------------- #
# 過去ログ用タイトル表示
# ----------------------------------------------------------------------------- #
sub MakeHistoryTitle
{
	my ($Page) = shift;
	my ($max);

	my ($width) = $BBS_WIDTH - $BBS_MARGIN;
	$width = (!$width) ? "100%" : $width;

	$Page = (!$Page) ? 1 : $Page;

print<<"HEADER";
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang="ja">
<HEAD>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<TITLE>過去記事見出し</TITLE>
HEADER

&ReadDefaultStyle;

print<<"EOM";
</HEAD>

<BODY BGCOLOR="$BBS_BGCOLOR" TEXT="$BBS_TEXT" LINK="$BBS_LINK" ALINK="$BBS_ALINK" VLINK="$BBS_VLINK" BACKGROUND="$BBS_BACKGROUND">
<TABLE BORDER="0" WIDTH="$BBS_WIDTH" SUMMARY="frame" CELLPADDING="0" CELLSPACING="0">
<TR><TD WIDTH="$BBS_MARGIN"></TD><TD WIDTH="$width">
<FONT COLOR="$BBS_MARK_COLOR">$BBS_BACK_MARK</FONT><A HREF="$BBS_HTML_URL/$BBS_HTML_NAME1" target="_parent">&nbsp;最新の記事掲示板へ（戻る）</A>　</SPAN>
<TABLE WIDTH="100%" SUMMARY="frame" CELLPADDING="0" CELLSPACING="0">
<TR>
<TH BGCOLOR="$BBS_TITLE_BGCOLOR"><FONT COLOR="$BBS_TITLE_COLOR">過去の記事</FONT></TH></TR></TABLE>
<DIV ALIGN="CENTER"><BR>
EOM

$max = &GetLogMax();

print "ページ：" if($max);

for ( 1 .. $max ) {
	if ($_ == $Page) {
		print qq{[<SPAN STYLE="color:red;">$_</SPAN>]\n};
	} else {
		print qq{[<A HREF="$BBS_SCRIPT?mode=history&amp;page=$_" target="_parent">$_</A>]\n};
	}
}

	print "</DIV></TD></TR></TABLE></BODY></HTML>\n";

	exit;

}

# ----------------------------------------------------------------------------- #
# 過去ログの最大ページ数を取得
# ----------------------------------------------------------------------------- #
sub GetLogMax()
{

	my ($count);
	my ($max);

	open FH, "$BBS_LOG_DIR/$BBS_HIST_FILE" or return 0;
	$count++ while(<FH>);
	close FH;

	$max = $count / $BBS_PAGE_ROWS;
	$max++ if($count % $BBS_PAGE_ROWS);

	return int($max);

}


# ----------------------------------------------------------------------------- #
# 記事検索処理
# ----------------------------------------------------------------------------- #
sub DispFindForm
{

	my (%finish);
	my (@words, @lines, $line);
	my ($history, $count, $multibyte);
	local ($word, $temp, $comp);

	my ($title) = ($FORM{'mode'} eq 'find') ? 'ＢＢＳ記事検索' : $FORM{'word'};
	my ($newswidth) = ($BBS_WIDTH) ? ($BBS_WIDTH - $BBS_MARGIN) : '100%';

	# HTMLの定型を作成
	# HTMLの定型を作成
print <<"EOM";
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang="ja">
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=Shift_JIS">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<TITLE>$title</TITLE>
EOM

	&ReadDefaultStyle;

	print qq{</HEAD>\n};
	print qq{<BODY BGCOLOR="$BBS_BGCOLOR" TEXT="$BBS_TEXT" LINK="$BBS_LINK" ALINK="$BBS_ALINK" VLINK="$BBS_VLINK" BACKGROUND="$BBS_BACKGROUND">\n};
	print qq{<TABLE WIDTH="$BBS_WIDTH" border="0" CELLPADDING="0" CELLSPACING="0"><TR><TD WIDTH="$BBS_MARGIN"></TD><TD width="$newswidth">\n};

if ($FORM{'mode'} eq 'find') {
print<<"EOM1";
[<A HREF="$BBS_HTML_URL/$BBS_HTML_NAME1">掲示板にもどる</A>]
<DIV ALIGN="CENTER">
<TABLE width="100%" SUMMARY="frame" CELLPADDING="0" CELLSPACING="0">
<TR>
	<TH bgcolor="$BBS_TITLE_BGCOLOR"><FONT COLOR="$BBS_TITLE_COLOR">$title</FONT></TH>
</TR>
</TABLE>
</DIV>
<DIV ALIGN="CENTER">
<TABLE SUMMARY="frame">
<TR>
<TD>■検索したい<STRONG>キーワード</STRONG>を入力し、検索条件を選択し「検索」を押してください。<BR>
		■複数のキーワードを入力するときは、<STRONG>半角スペース</STRONG>で区切って下さい。</TD>
</TR>
</TABLE>

<FORM action="$BBS_SCRIPT" method="POST"><INPUT type="hidden" name="mode" value="$FORM{'mode'}">
<TABLE BORDER="0" SUMMARY="frame"><TR><TD>
<TABLE BORDER="1" SUMMARY="frame">
<TR><TD nowrap>キーワード：</TD><TD><INPUT type="text" name="word" size="30" value="$FORM{'word'}"></TD></TR>
<TR><TD nowrap>検索条件：</TD><TD><INPUT id="AND" type="radio" name="ANDOR" value="and"><LABEL for="AND">AND</LABEL>　
<INPUT id="OR" type="radio" name="ANDOR" value="or" checked><LABEL for="OR">OR</LABEL>　</TD></TR>
</TABLE>
</TD></TR>
<TR><TD align="right"><INPUT type="submit" value="検　索">　<INPUT type="reset" value="取消し"></TD></TR>
</TABLE>
</FORM>
</DIV>
EOM1
} else {
print<<"EOM1";
[<A HREF="$BBS_HTML_URL/$BBS_HTML_NAME1">掲示板にもどる</A>]
<DIV ALIGN="CENTER">
<TABLE width="100%" SUMMARY="frame">
<TR>
	<TD align="center"><H2><HR WIDTH="100%" SIZE="3" noshade>$title<HR WIDTH="100%" SIZE="3" noshade></H2></TD>
</TR>
</TABLE>
</DIV>
EOM1
}

	$word = $FORM{'word'};
	if ($word =~ /[\x80-\xff]/) {
		$multibyte = 1;		# 日本語が含まれている
		&jcode::convert( \$word, 'euc');
		$word =~ s/([\x80-\xff][\x80-\xff]|[\x00-\x7f])/($1 eq "\xa1\xa1") ? " " : $1/eg;
		&jcode::convert( \$word, 'sjis');
	} else {
		$word =~ s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g;
	}

	@words = split(/ /,$word);
	return if($#words < 0);

	for $history (0..1) {
		if($history){
			open( FH, "$BBS_LOG_DIR/$BBS_LOG_FILE") or &error("ログファイルのオープンに失敗しました。");
		} else {
			open( FH, "$BBS_LOG_DIR/$BBS_HIST_FILE");	# 過去ログファイルは、無くても可
		}

		foreach $line (<FH>) {

			chomp $line;
			my ($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip) = split(/<>/, $line );
			$comp = join('<>', $name, $title, $comment);
			$comp =~ s/<br>/\n/ig;
			&jcode::convert(\$comp, 'euc');

			# 完了フラグを初期化
			$count = 0;
			$finish{$_} = 0 foreach(@words);

			foreach $temp (@words){
				&jcode::convert(\$temp, 'euc');

				if($multibyte){
					next if(index($comp, $temp) < 0);
				} else {
					next if($comp !~ /$temp/i);
				}

				$finish{$temp} = 1;

				$temp =~ s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g if ($multibyte);
				$comp =~ s/($temp)/<STRONG>$1<\/STRONG>/ig;
				$comp =~ s/\n/<br>/g;
				next if( $FORM{'ANDOR'} eq 'and' && ++$count < $#words + 1 );

				&jcode::convert(\$comp, 'sjis');
				($name, $titme, $comment) = split( /<>/, $comp);
				$line = join('<>', $no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip);
				push @lines, $line;
				last;
			}
		}
		close FH;
	}

	foreach $line (reverse(@lines)){
		my ($no, $date, $name, $mail, $title, $comment, $url, $image, $key, $ip) = split(/<>/, $line );
		&MakeIndexBody1($no, $date, $name, $mail, $title, $comment, $url, $image);
	}

	if($#lines < 0){
		print qq{<HR>\n};
		print qq{見つかりませんでした。\n};
	} else {
		print $#lines + 1;
		print qq{ 件見つかりました。\n};
		print qq{</TD></TR></TABLE>\n};
	}

	print "</TD></TR></TABLE>\n";
	print "</BODY>\n";
	print "</HTML>\n";
}

# ----------------------------------------------------------------------------- #
# サイト検索処理
# ----------------------------------------------------------------------------- #
sub SearchNewsFiles
{


	my ($title) = ($FORM{'mode'} eq 'srch') ? 'サイト内記事検索' : $FORM{'word'};
	my ($newswidth) = ($BBS_WIDTH) ? ($BBS_WIDTH - $BBS_MARGIN) : '100%';

	# HTMLの定型を作成
print <<"EOM";
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang="ja">
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=Shift_JIS">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<TITLE>$title</TITLE>
EOM

	&ReadDefaultStyle;

	print qq{</HEAD>\n};
	print qq{<BODY BGCOLOR="$BBS_BGCOLOR" TEXT="$BBS_TEXT" LINK="$BBS_LINK" ALINK="$BBS_ALINK" VLINK="$BBS_VLINK" BACKGROUND="$BBS_BACKGROUND">\n};
	print qq{<TABLE WIDTH="$BBS_WIDTH" border="0"><TR><TD WIDTH="$BBS_MARGIN"></TD><TD width="$newswidth">\n};

if($FORM{'mode'} eq 'srch') {
print<<"EOM1";
[<A HREF="$BBS_HTML_URL/$BBS_HTML_NAME1">掲示板にもどる</A>]
<DIV ALIGN="CENTER">
<TABLE width="100%" SUMMARY="frame">
<TR>
	<TH bgcolor="$BBS_TITLE_BGCOLOR"><FONT COLOR="$BBS_TITLE_COLOR">$title</FONT></TH>
</TR>
</TABLE>
</DIV>
<DIV ALIGN="CENTER">
<TABLE SUMMARY="frame">
<TR>
<TD >■検索したい<STRONG>キーワード</STRONG>を入力し、検索条件を選択し「検索」を押してください。<BR>
		■複数のキーワードを入力するときは、<STRONG>半角スペース</STRONG>で区切って下さい。</TD>
</TR>
</TABLE>

<FORM action="$BBS_SCRIPT" method="POST"><INPUT type="hidden" name="mode" value="$FORM{'mode'}">
<TABLE BORDER="0" SUMMARY="frame"><TR><TD>
<TABLE BORDER="1" SUMMARY="frame">
<TR><TD nowrap>キーワード：</TD><TD><INPUT type="text" name="word" size="30" value="$FORM{'word'}"></TD></TR>
<TR><TD nowrap>検索条件：</TD><TD><INPUT id="AND" type="radio" name="ANDOR" value="and"><LABEL for="AND">AND</LABEL>　
<INPUT id="OR" type="radio" name="ANDOR" value="or" checked><LABEL for="OR">OR</LABEL>　</TD></TR>
</TABLE>
</TD></TR>
<TR><TD align="right"><INPUT type="submit" value="検　索">　<INPUT type="reset" value="取消し"></TD></TR>
</TABLE>
</FORM>
</DIV>
EOM1

} else {
print<<"EOM1";
[<A HREF="$BBS_HTML_URL/$BBS_HTML_NAME1">掲示板にもどる</A>]
<DIV ALIGN="CENTER">
<TABLE width="100%" SUMMARY="frame">
<TR>
	<TD style="font-size:14pt ; font-weight:bold;" align="center"><HR WIDTH="100%" SIZE="3" noshade>$title<HR WIDTH="100%" SIZE="3" noshade></TD>
</TR>
</TABLE>
</DIV>
EOM1
}

print "<DL>\n";

# 検索条件があれば、検索処理をおこなう。
$SEARCH_DIR =~ s/\/$//;

if($FORM{'word'}) {
	&SearchFiles($_) foreach (split(/ /, $SEARCH_DIR));
}

print qq{</DL>\n</TD></TR></TABLE></DIV>
\n</BODY>\n</HTML>\n};

}

# ----------------------------------------------------------------------------- #
# サイト検索（対象ファイル抽出処理）
# ----------------------------------------------------------------------------- #
sub SearchFiles
{

	my($Dir) = shift;
	my(@DirList, $file, $ext);

	$ext = join('|', @Ext);

	opendir(DIR, $Dir);
	@DirList = readdir(DIR);
	closedir(DIR);

	foreach (@DirList) {
		next if ( $_ =~ /\.\.?$/ );

		$file = "$Dir/$_";
		if (-d $file) {
			&SearchFiles($file);
		} else {
			&FindSearchFiles($file) if($file =~ /\.$ext/i);
		}
	}
}

# ----------------------------------------------------------------------------- #
# サイト検索単語マッチ処理
# ----------------------------------------------------------------------------- #
sub FindSearchFiles
{

	my ($File) = shift;

	my (%finish);
	my (@words, @lines);
	my ($i, $history, $comp, $count, $multibyte);

	# 各種変数を初期化する
	$count = 0;

	local ($detail, $cond, $line, $title, $word);

	$word = $FORM{'word'};
	if ($word =~ /[\x80-\xff]/) {
		$multibyte = 1;
		&jcode::convert(\$word, "euc");
		$word =~ s/([\x80-\xff][\x80-\xff]|[\x00-\x7f])/($1 eq "\xa1\xa1") ? " " : $1/eg;
		&jcode::convert(\$word, "sjis");
	} else {
		$word =~ s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g;
	}

	@words = split(/ +/,$word);

	# オープン処理：失敗時は、スキップ
	open (FH, "$File") or return;
	@lines = <FH>;
	close FH;

	@lines = split(/\r/, $lines[0]) if (($#lines == 0) && ($lines[0] =~ /\r[^\n]/));

	$start = 0;
	$count = 0;
	$finish{$_} = 0 foreach(@words);

	for $i (0 .. $#lines) {

		$line = $lines[$i];

		$title = $line if($line =~ /<title>/i);
		$start = 1 if( $lines[$i] =~ /<body/i );

		next if (!$start);
		next if ($line =~ /<!-+(.*)-+>/);

		foreach $cond (@words) {
			next if($finish{$cond});

			if ($multibyte) {
				next if(index($line, $cond) == -1);
			} else {
				next if($line !~ /$cond/i);
			}

			$finish{$cond} = 1;

			next if( $FORM{'ANDOR'} eq 'and' && ++$count < $#words + 1 );

			print "<DT><FONT COLOR=\"$BBS_MARK_COLOR\">■ </SPAN><A HREF=\"$File\" TARGET=\"new_\">";

			$title =~ s/<[^>]*(>|$)//g;
			$title =~ s/[\r\n]+//g;
			$title =~ s/^\s+$//g;
			&jcode::convert(\$title, 'sjis' );
			$title = $File if (!$title);

			print "$title</A>\n";

			print "( <A HREF=\"$File\" TARGET=\"new_\">";
			$File =~ s/^(.*)\\//;
			$File =~ s/^(.*)\///;
			print "$File</A> )\n";
			print "<DD>\n";

			$imin = (($i - $ResultLines) < 0) ? 0 : $i - $ResultLines;
			$imax = (($i + $ResultLines) > $#lines) ? $#lines : $i + $ResultLines;

			for ($imin .. $imax) {
				$detail = $lines[$_];
				&jcode::convert(\$detail, 'euc');
				$detail =~ s/<[^>]*(>|$)//g;
				&jcode::convert(\$cond, "euc");
				$cond =~ s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g;

				$detail =~ s/($cond)/<STRONG>$1<\/STRONG>/ig;
				&jcode::convert(\$detail, 'sjis');

				$detail =~ s/^\s+//g;
				print "$detail";
			}

			print "<BR>&nbsp;\n";
			print "</DD>\n";
			$i = $#lines;
			last;
		}
	}
}
