#! /usr/bin/perl -w

use strict;
use vars qw(%Conf);
use constant LOCK_SH => 1;
use constant LOCK_EX => 2;
use constant LOCK_NB => 4;
use constant LOCK_UN => 8;

%Conf = (
	data_file => "../topics.txt",
	charcode => "sjis",  # データファイルの文字コード jcode.pl の形式
	br => "\x0D\x0A",  # データファイルの改行
	stylesheet => "../default.css",
	title => "トピックスの編集",
	backto => "../",
	passwd => "fukafuka",
	form_mesg => << "EOD",
<ul>
	<li>トップページに表示されるトピックスを変更します。</li>
	<li>各トピックは&lt;p&gt;〜&lt;/p&gt;で括って下さい。</li>
	<li>バックアップはとってません。既存のトピックを削除するときは気を付けてください。</li>
	<li>[Clear]ボタンを押すとフォーム内のデータが元に戻ります。</li>
	<li>パスワードを入力し、[Edit]ボタンを押すと変更が反映されます。</li>
	<li>変更が成功するとトップページに戻ります。</li>
</ul>

EOD

);

&main();

sub main {
	my %form =();
	require("jcode.pl");

	&read_query(\%form);
	&write_data(\%form) if ($form{'action'} eq "edit");
	&print_form();
	exit(0);

}

sub write_data {
	my $form = shift;

	if($form->{'passwd'} eq $Conf{'passwd'}) {
		$form->{'topics'} =~ s/\x0D\x0A|\x0D|\x0A/$Conf{'br'}/g;
		&jcode::convert(\$form->{'topics'}, $Conf{'charcode'});
		open(OUT, "> $Conf{'data_file'}") or 
			print_error("Writing Error", "The data file could not open.", $!);;
		eval{ flock(OUT, LOCK_EX) };
		print(OUT $form->{'topics'});
		close(OUT);
		eval{ flock(OUT, LOCK_UN) };
		print("Location: $Conf{'backto'}\n\n");
		exit(0);
	}
}

sub read_query {
	my $query = shift;
	my($key, $value, $buf) = ();

	if ($ENV{'REQUEST_METHOD'} eq "POST") {
		read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
		foreach (split(/&/, $buf)) {
			$key = $value = "";
			($key, $value) = split(/=/, $_, 2);
			$value =~ tr/+/ /;
			$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			&jcode::convert(\$value, "euc");
			$query->{$key} = $value;
		}
	}
}

sub escape_metachar {
	my $ref_string = shift;
	$$ref_string =~ s/&/&amp;/g;
	$$ref_string =~ s/</&lt;/g;
	$$ref_string =~ s/>/&gt;/g;
	$$ref_string =~ s/\"/&quot;/g;
}

sub print_form {
	open(IN, $Conf{'data_file'}) or 
		print_error("Loading Error", "The data file could not open.", $!);
	eval{ flock(IN, LOCK_SH) };

	print("Content-Type: text/html; charset=EUC-JP\n");
	print("Content-Language: ja\n");
	print("\n\n");

	print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
	print("<html lang=\"ja\">\n\n");
	print("<head>\n");
	print("\t<title>", $Conf{'title'},"</title>\n");
	print("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"", $Conf{'stylesheet'}, "\">\n");
	print("</head>\n\n");

	print("<body class=\"edit_topics\">\n");
	print("<h2>", $Conf{'title'}, "</h2>\n\n");
	print($Conf{'form_mesg'});

	print <<"EOD";
<div style="text-align: right">
<form action="$ENV{'SCRIPT_NAME'}" method="POST">
<table class="edit_topics">
	<tr>
		<td>
			<input type="hidden" name="action" value="edit">
<textarea name="topics" cols="65" rows="7">
EOD

	while(<IN>) {
		$_ =~ s/\x0D\x0A|\x0D|\x0A/\n/g;
		&jcode::convert(\$_, "euc");
		&escape_metachar(\$_);
		print($_);
	}

	print <<"EOD";
</textarea>
		</td>
	</tr>
	<tr>
		<td>
			Password:
			<input type="password" name="passwd" class="passwd">
		</td>
	</tr>
	<tr>
		<td>
			<input type="submit" value="Edit" class="edit">
			<input type="reset" value="Clear" class="clear">
		</td>
	</tr>
</table>
</form>
</div>
EOD

	print("\n<div class=\"back\">\n<a href=\"", $Conf{'backto'}, "\">■戻る</a>\n</div>\n");
	print("\n<div class=\"about\">\n\t topics.cgi ver. 0.41",
		" by <a href=\"mailto:morita\@sky.club.ne.jp\">Morita, K.</a>\n</div>\n\n");
	print("\n</body>\n\n</html>");
	
	eval{ flock(IN, LOCK_UN) };
	close(IN);
}

sub print_error {
	my($error_name, @error_mesg) = @_;

	print("Content-Type: text/html; charset=ISO-8859-1\n");
	print("Content-Language: en\n");
	print("\n");
	print("<!doctype html public \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
	print("<html lang=\"en\">\n<head>\n\t<title>System Error</title>\n");
	print("</head>\n\n<body>\n\n<h1>$error_name</h1>\n\n<ul>\n");
	foreach (@error_mesg) {
		print("\t<li>$_</li>\n");
	}
	print("</ul>\n\n</body>\n</html>\n");

	exit(1);
}

