#!/usr/bin/perl
# -*- tab-width: 4 -*-
#$ontcgi_path = '/nasu/ns_list/nasu011/cgi/';

# アップロードできる画像ファイルの最大バイト数
$uploadFile_max = 100 * 1024;

require "${ontcgi_path}jcode.pl";
use Fcntl;
use AnyDBM_File;

sub printAllTopics;		# 案内を一覧表示する
sub printAllPosts;		# 詳細を一覧表示する
sub printHeaderTree;	# 詳細とその付記の見出しを表示する

sub parseFormData;		# フォームデータを解析する
sub errorMessage;		# エラーメッセージを表示する

require "${ontcgi_path}ontenv.pl";

$menu_file = (($miniMenu_flag & 8) == 8) ? 'index.shtml' : 'index.html';

&parseFormData();
$job	 = $in{'job'};	# フォーム押したボタン
$note_no = $in{'no'};	# 詳細する案内番号(undefなら新規に案内作成)
$post_no = $in{'re'};	# 付記する詳細番号(0ならベース案内に詳細)

if (-e "${ontcgi_path}data/ont_dmy") {
	open(DMYFILE, "${ontcgi_path}data/ont_dmy")
	  or die "DMYFILE=${ontcgi_path}data/ont_dmy : $!";
	flock(DMYFILE, 2);
	tie %DBMFILE, AnyDBM_File, "${ontcgi_path}data/ont_dbm", O_RDONLY, 0644
	  or die "DBMFILE=${ontcgi_path}data/ont_dbm : $!";

	$postPass_crypt = $DBMFILE{'wripass'};
	@notes_que = split(/&/, $DBMFILE{'queue'});

	if ($note_no eq undef) {
		$note_no = 0;
	}
	else {
		($userName, $email, $writeTime, $post_num, $lock_flag, $profile,
		  $remoteHOST, $remoteADDR, $password_crypt, $title, $caption)
		  = split(/"/, $DBMFILE{"${note_no}:0"}, 11);
	}	

	untie %DBMFILE;
	flock(DMYFILE, 8);
	close(DMYFILE);
}

if ($note_no > 0 && grep($_ == $note_no, @notes_que) == 0) {
	&errorMessage('** 倉庫にある案内ではこの機能は使えません **');
	exit(1);
}

if ($job =~ /^案内を一覧/) {
	&printAllTopics();
	exit(0);
}
elsif ($job =~ /^詳細を/) {
	&printAllPosts($note_no);
	exit(0);
}

# 入力フォームを表示

$thisPageTitle = ($note_no == 0)
  ? '新しい案内を作る' : "${notes_name}${note_no}に詳細";

$cookieData = $ENV{'HTTP_COOKIE'};
if ($cookieData =~
 /^ONT=NAME:[^"]*"EMAIL:[^"]*"PROFILE:[^"]*"PASSWD:[^"]*"WRIPASS/) {
	$cookieData =~ s/^ONT=//o;
	$cookieData =~ s/_sem_/;/go;
# ↓クッキーが文字化けする時は先頭の#をはずす
#	$cookieData =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	@cookieData = split(/"/, $cookieData);

	for (@cookieData) {
		($key, $value) = /^([^:]*):(.*)$/o;
		$cookie{$key} = $value;
	}
}

$textarea_rows = ($ENV{'HTTP_USER_AGENT'} =~ /lynx/i) ? 25 : 12;

print <<END;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
        "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-type" content="text/html; charset=EUC-JP">
${headTagOption}
<TITLE>${menuPageTitle} / ${thisPageTitle}</TITLE>
</HEAD>

<BODY ${bodyTagOption} class="form">
END

	if ($note_no == 0 || $job eq '詳細') {
		&printHeader(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"",
		  $thisPageTitle);
	}
	else {
		&printHeader(STDOUT, BACK, "href=\"${onthtml_url}/${note_no}.html\"",
		  $thisPageTitle);
	}


	print <<END;
<FORM method="POST" action="${ontcgi_url}/ontwrite.cgi" accept-charset="EUC-JP,Shift_JIS" enctype="multipart/form-data">
<INPUT type="hidden" name="no" value="${note_no}">
END

if ($post_no ne undef) {
	print "<INPUT type=\"hidden\" name=\"re\" value=\"${post_no}\">\n";
}
if ($job eq '詳細') {
	print "<INPUT type=\"hidden\" name=\"reload\" value=\"0\">\n";
}

if ($note_no == 0) {
	print "** この${notes_name}のために、新しい案内を作ります **<BR><BR>\n";
}
else {
	$nameNEmail = ($email eq undef)
	  ? $userName : "<A href=\"mailto:${email}\">${userName}</A>";

	print <<END;
<TABLE border="0" cellspacing="0" width="95%" class="index">
<TR><TD bgcolor="${noteHeadColor}" align="left" class="head">${notes_name}${note_no} | ■${title} </TD><TD bgcolor="${noteHeadColor}" align="right" class="head">( 詳細 ${post_num} 件 )</TD></TR>
</TD></TR>
</TABLE>
<BR>
END
}

print <<END;
<TABLE border="0" cellspacing="2" class="input">
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">名前</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="text" name="name" value="${cookie{'NAME'}}" size="64" maxlength="64">(必須項目)</TD>
</TR>
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">E-mailアドレス</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="text" name="email" value="${cookie{'EMAIL'}}" size="64" maxlength="64"></TD>
</TR>
<!-- 
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">自己紹介/近況</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="text" name="profile" value="${cookie{'PROFILE'}}" size="64" maxlength="64"></TD>
</TR>
 -->
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">タイトル</TD>
END

if ($post_no eq undef) {
	print <<END;
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="text" name="title" size="64" maxlength="64">(必須項目)</TD>
</TR>
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">内容</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><TEXTAREA name="contents" cols="80" rows="${textarea_rows}"></TEXTAREA><BR>(内容に書かれたURLやメールアドレスは、自動的にリンクになります)</TD>
</TR>
END
}
else {
	open(DMYFILE, "${ontcgi_path}data/ont_dmy")
	  or die "DMYFILE=${ontcgi_path}data/ont_dmy : $!";
	flock(DMYFILE, 2);
	tie %DBMFILE, AnyDBM_File, "${ontcgi_path}data/ont_dbm", O_RDONLY, 0644
	  or die "DBMFILE=${ontcgi_path}data/ont_dbm : $!";

	($userName, $email, $writeTime, $reply_no, $del_flag, $profile,
	  $remoteHOST, $remoteADDR, $password_crypt, $title, $caption)
	  = split(/"/, $DBMFILE{"${note_no}:${post_no}"}, 11);

	@pos = split(/&/, $DBMFILE{"${note_no}:IDX"});
	for ($idx_no = 1; $DBMFILE{"${note_no}:IDX${idx_no}"}; $idx_no++) {
		@pos = (@pos, split(/&/, $DBMFILE{"${note_no}:IDX${idx_no}"}));
	}
 	$pos_num = @pos;

	untie %DBMFILE;
	flock(DMYFILE, 8);
	close(DMYFILE);

	$title =~ s/^(?:R[eE]\d*:)*/Re$post_no:/o;

	open(NOTFILE, "${onthtml_path}/${note_no}.html")
	  or die "NOTFILE=${onthtml_path}/${note_no}.html : $!";
	flock(NOTFILE, 2);

	if ($post_no > 0) {
		for ($i = 0; $i < ($pos_num - $post_no); $i++) {
			$pos += $pos[$i];
		}
		seek(NOTFILE, $pos, 0);
	}

	while (<NOTFILE>) {
		if (/^<BR>/o) {
			$contents = $_;
			last;
		}
		elsif (/^<HR/o) {
			last;
		}
	}

	flock(NOTFILE, 8);
	close(NOTFILE);

	if ($contents eq undef || $contents eq "<BR>\n") {
		$contents = '';
	}
	else {
		$contents =~ s/<BR>/\n> /go;
		$contents =~ s!<A[^>]*>([^<]*)</A>!$1!go;
		if (($permitTag_flag & 1) == 1) {
			$contents =~ s!</?(?:FONT|font|STRONG|strong|B|b)[^>]*?>!!go;
		}
		if (($permitTag_flag & 2) == 2 || ($supportURL_flag & 2) == 2) {
			$contents =~ s!<IMG([^>]*)>!&lt;IMG$1&gt;!go;
		}

		$contents = ($post_no == 0)
		  ? "( ${userName}さんは${notes_name}${note_no}で書きました )"
		  . $contents
		  : "( ${userName}さんは詳細${post_no}で書きました )" . $contents;
	}

	print <<END;
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="text" name="title" value="${title}" size="64" maxlength="64">(必須項目)</TD>
</TR>
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">内容</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><TEXTAREA name="contents" cols="80" rows="${textarea_rows}">${contents}
</TEXTAREA><BR>(内容に書かれたURLやメールアドレスは、自動的にリンクになります)</TD>
</TR>
END
}

if ($uploadFile_max > 0) {
	print <<END;
<TR>
<TD bgcolor="${noteHeadColor}" align="left">添付する画像ファイル</TD>
<TD bgcolor="${noteBodyColor}" align="left" colspan="2"><INPUT type="file" name="file" size="60"></TD>
</TR>
END
}

print <<END;
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">削除パスワード</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="password" name="passwd" value="${cookie{'PASSWD'}}" size="8" maxlength="8">(英数字8文字以内/設定すると他人が削除できなくなります)</TD>
</TR>
END

if ($postPass_crypt ne undef && ($lock_flag == 1 || $postPass_mode == 1
  || ($postPass_mode == 2 && $note_no == 0))) {

	print <<END;
<TR>
<TD bgcolor="${noteHeadColor}" align="left" class="head">詳細パスワード</TD>
<TD bgcolor="${noteBodyColor}" align="left" class="body"><INPUT type="password" name="wripass" value="${cookie{'WRIPASS'}}" size="8" maxlength="8">(英数字8文字以内/詳細するにはパスワードが必要です)</TD>
</TR>
END
}

print <<END;
</TABLE>
<INPUT type="submit" value="登録する"><INPUT type="reset" value="リセット">
</FORM>
END

if ($note_no == 0 || $job eq '詳細') {
	&printFooter(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"");
}
else {
	&printFooter(STDOUT, BACK, "href=\"${onthtml_url}/${note_no}.html\"");
}


### sub printAllTopics() :案内を一覧表示する
#
sub printAllTopics {
	my(@notes_que);
	my($userName, $email, $writeTime, $post_num, $lock_flag, $profile,
	   $remoteHOST, $remoteADDR, $password_crypt, $title, $caption);

	print <<END;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
        "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-type" content="text/html; charset=EUC-JP">
${headTagOption}
<TITLE>${menuPageTitle} / 案内を一覧/検索</TITLE>
</HEAD>

<BODY ${bodyTagOption} class="list">
END


	&printHeader(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"",
	  '案内を一覧/検索');

	print <<END;
<FORM method="POST" action="${ontcgi_url}/ontseek.cgi" accept-charset="EUC-JP,Shift_JIS">
キーワード<INPUT type="text" name="keyword" size="30" maxlength="40"><INPUT type="submit" value="検索"><BR>
(<STRONG>絞込検索：</STRONG>半角空白に続けてキーワードを追加してください)
</FORM>
END

	open(DMYFILE, "${ontcgi_path}data/ont_dmy")
	  or die "DMYFILE=${ontcgi_path}data/ont_dmy : $!";
	flock(DMYFILE, 2);
	tie %DBMFILE, AnyDBM_File, "${ontcgi_path}data/ont_dbm", O_RDONLY, 0644
	  or die "DBMFILE=${ontcgi_path}data/ont_dbm : $!";

	@notes_que = split(/&/, $DBMFILE{'queue'});

	foreach $i (@notes_que) {
		($userName, $email, $writeTime, $post_num, $lock_flag, $profile,
		  $remoteHOST, $remoteADDR, $password_crypt, $title, $caption)
		  = split(/"/, $DBMFILE{"${i}:0"}, 11);

		print <<END;
<FORM method="POST" action="${ontcgi_url}/ontinput.cgi">
<INPUT type="hidden" name="no" value="${i}">
<TABLE width="95%" border="0" cellspacing="0" class="index">
<TR><TD bgcolor="${noteHeadColor}" align="left" class="head">${notes_name}${i}  <A href="${onthtml_url}/${i}.html" target="_blank">${title}</A> </TD><TD bgcolor="${noteHeadColor}" align="right" class="head">( 詳細 ${post_num} 件 )</TD><TD bgcolor="${noteHeadColor}" width="5%" align="right" class="head"><INPUT type="submit" name="job" value="詳細"></TD></TR>
END

		if ($caption ne undef && ($captions_flag & 1) == 1) {
			print <<END;
<TR><TD bgcolor="${noteHeadColor}" align="right" colspan="3">
<TABLE width="100%" cellpadding="2" class="caption">
<TR><TD bgcolor="${noteHeadColor}" width="5%" align="left" class="left"><BR></TD><TD bgcolor="${noteBodyColor}" width="1%" align="left" class="center"><BR></TD><TD bgcolor="${noteHeadColor}" align="left" class="right">
${caption}<BR>
</TD></TR>
</TABLE>
</TD></TR>
END
		}

		print <<END;
</TABLE>
</FORM>
END
	}
	untie %DBMFILE;
	flock(DMYFILE, 8);
	close(DMYFILE);

	&printFooter(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"");
}

### sub printAllPosts() :詳細をツリー表示する
#
# (IN)
#	$note_no	:ツリー表示する案内番号
#
sub printAllPosts {
	my($note_no) = @_;
	my($userName, $email, $writeTime, $post_num, $lock_flag, $profile,
	   $remoteHOST, $remoteADDR, $password_crypt, $title, $caption);

	print <<END;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
        "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-type" content="text/html; charset=EUC-JP">
${headTagOption}
<TITLE>${menuPageTitle} / 詳細をツリー表示</TITLE>
</HEAD>

<BODY ${bodyTagOption} class="list">
END

	&printHeader(STDOUT, BACK, "href=\"${onthtml_url}/${note_no}.html\"",
	  '詳細をツリー表示');
	print "<BR>\n";

	open(DMYFILE, "${ontcgi_path}data/ont_dmy")
	  or die "DMYFILE=${ontcgi_path}data/ont_dmy : $!";
	flock(DMYFILE, 2);
	tie %DBMFILE, AnyDBM_File, "${ontcgi_path}data/ont_dbm", O_RDONLY, 0644
	  or die "DBMFILE=${ontcgi_path}data/ont_dbm : $!";

	($userName, $email, $writeTime, $post_num, $lock_flag, $profile,
	  $remoteHOST, $remoteADDR, $password_crypt, $title, $caption)
	  = split(/"/, $DBMFILE{"${note_no}:0"}, 11);

	$post_sum = $post_num;
	@pos = split(/&/, $DBMFILE{"${note_no}:IDX"});
	for ($idx_no = 1; $DBMFILE{"${note_no}:IDX${idx_no}"}; $idx_no++) {
		@pos = (@pos, split(/&/, $DBMFILE{"${note_no}:IDX${idx_no}"}));
	}
	foreach $pos (@pos) {
		if ($pos == 0) {
			$post_sum--;
		}
	}

	print "( 詳細総数 ${post_num} 件 / 詳細実数 ${post_sum} 件 )<BR>";

	print <<END;
<TABLE width="95%" border="0" cellspacing="0" class="index">
<TR><TD bgcolor="${noteBodyColor}" align="left" class="body">
END

	for ($i = $post_num; $i >= 0; $i--) {
		&printHeaderTree($i, 0);
	}

	untie %DBMFILE;
	flock(DMYFILE, 8);
	close(DMYFILE);

	print <<END;
</TD></TR>
<TR><TD bgcolor="${noteHeadColor}" align="left" class="head">${notes_name}${note_no}  <A href="${onthtml_url}/${note_no}.html" target="note${note_no}">${title}</A> ${userName} ${writeTime}</TD></TR>
</TABLE>
<BR>
END

	&printFooter(STDOUT, BACK, "href=\"${onthtml_url}/${note_no}.html\"");
}

### sub printHeaderTree() : 詳細とその付記の見出しを表示する
#
# (IN)
#	$post_no	: 表示する詳細番号
#	$depth:		: 再帰の深さ
#
sub printHeaderTree {
	my($post_no, $depth) = @_;
	my(@reply_no, $j);
	my($userName, $email, $writeTime, $reply_no, $del_flag, $profile,
	   $remoteHOST, $remoteADDR, $password_crypt, $title, $caption);
	
	($userName, $email, $writeTime, $reply_no, $del_flag, $profile,
	  $remoteHOST, $remoteADDR, $password_crypt, $title, $caption)
	  = split(/"/, $DBMFILE{"${note_no}:${post_no}"}, 11);

	if ($depth == 0) {
		if ($post_no > 0 && $reply_no ne undef) {
			$replyStack[$reply_no] .= "${post_no}&";
			return;
		}
		elsif ($title =~ /^Re:(\d+)/) {
			$replyStack[$1] .= "${post_no}&";
			return;
		}
	}

	@reply_no = split(/&/, $replyStack[$post_no]);

	foreach $j (@reply_no) {
		&printHeaderTree($j, $depth + 1);
	}

	if ($post_no == 0) {
		return;
	}

	if ($depth > 0) {
		print '　' x ($depth - 1);
		print '⇒';
	}

	if ($del_flag != 0) {
		print "(${post_no}) ( 削除 )<BR>\n";
	}
	else {
		print <<END;
(${post_no}) <A href="${onthtml_url}/${note_no}.html#${post_no}" target="note${note_no}">${title}</A> <BR>
END
	}
	if ($depth == 0) {
		$depth_num++;
		$bgcolor = ($depth_num % 2 == 0) ? $noteBodyColor : $postBodyColor;

		print <<END;
</TD></TR>
<TR><TD bgcolor="${bgcolor}" align="left" class="body">
END
	}

}


### sub parseFormData() :フォームデータを解析する
#
# (OUT)
#	%in		:フォームデータの内容
#
sub parseFormData {
	my($formData_buf, @formData); 
	my($name, $value);

	if ($ENV{'REQUEST_METHOD'} eq 'POST') {
		read(STDIN, $formData_buf, $ENV{'CONTENT_LENGTH'});
	}
	else {
		$formData_buf = $ENV{'QUERY_STRING'};
	}

	@formData = split(/&/, $formData_buf);
	foreach (@formData) {
		($name, $value) = split(/=/);
		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		&jcode'convert(*value, 'euc');
		$in{$name} = $value;
	}
}

### sub errorMessage() :エラーメッセージを表示する
#
# (IN)
#	$message	:表示するエラーメッセージ 
#
sub errorMessage {
	my($message) = @_;

	print <<END;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
        "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-type" content="text/html; charset=EUC-JP">
${headTagOption}
<TITLE>${menuPageTitle} / エラーメッセージ</TITLE>
</HEAD>

<BODY ${bodyTagOption} class="error">
END

	&printHeader(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"",
	  'エラーメッセージ');

	print <<END;
<TABLE width="95%" border="0" cellspacing="0" cellpadding="15" class="message">
<TR><TD bgcolor="${noteBodyColor}" align="center"><SPAN>
${message}<BR>
</SPAN></TD></TR>
</TABLE>
<BR>
END

	&printFooter(STDOUT, MENU, "href=\"${onthtml_url}/${menu_file}\"");
}

# Open!NOTES 2.0a (C)1998-2002 NetComplex Inc. All rights reserved.


