#!/usr/bin/perl

# SimpleLink
# シンプルなリンク集
# Copyright(C) Satsuki 2004-2005
#
# 2005.7.18  Ver. 1.0

use strict;
use vars qw (%CONFIG);
require "./jcode.pl";
#use CGI::Carp qw(fatalsToBrowser);

########### 環境設定 ##########################################
$CONFIG{SCRIPT}  = "link.cgi";   # スクリプト名
$CONFIG{LOG}     = "log.dat";    # ログファイル
$CONFIG{SKIN}    = "skin.html";  # デザインファイル (HTML)
$CONFIG{PASS}    = "89da7";       # 管理パスワード（必ず変更してください）
########### 環境設定 ここまで #################################

# ログの形式
# no, title, url, comment, imageurl

&main();
exit;

sub main () {
	my (%form) = ();
	&ReadParse (\%form);

	if ($form{action} eq "delete") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_delete(\%form); # 記事削除
	}
	elsif ($form{action} eq "write") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_write(\%form); # ログファイルに書き込み
	}
	elsif ($form{action} eq "edit") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_edit(\%form);
	}
	elsif ($form{action} eq "up") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_up(\%form);
	}
	elsif ($form{action} eq "down") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_down(\%form);
	}
	elsif ($form{action} eq "admin") {
		&error("パスワードが違います") if ($form{pass} ne $CONFIG{PASS});
		&_admin(\%form);
	}
	else {
		&_disp(\%form);
	}
}

### 画面表示 ###
sub _disp ($) {
	my $form = $_[0];
	my (@data, @html, $html1) = ();

	# ログファイル読み込み
	open (FILE, "<$CONFIG{LOG}") or error("ログファイルが開けません: $CONFIG{LOG}");
	flock (FILE, 1);
	@data = <FILE>;
	close (FILE);

	# デザインファイル読み込み
	open (FILE, "<$CONFIG{SKIN}") or error("デザインファイルが開けません: $CONFIG{SKIN}");
	flock (FILE, 1);
	my $tmp;
	$tmp .= $_ while (<FILE>);
	close (FILE);
	@html = split (/<!--CUT-->/, $tmp);

	foreach (@data) {
		chomp $_;
		my @tmp = split(/,/, $_);
		my $a = $html[1];
		$a =~ s/%%no%%/$tmp[0]/g;
		$a =~ s/%%title%%/$tmp[1]/g;
		$a =~ s/%%url%%/$tmp[2]/g;
		$a =~ s/%%comment%%/$tmp[3]/g;
		$a =~ s/%%imageurl%%/$tmp[4]/g;
		$html1 .= $a;
	}
	print "Content-Type: text/html; charset=SHIFT_JIS\n\n";
	print "$html[0]$html1$html[2]";
}

### 管理モード ###
sub _admin ($) {
	my $form = $_[0];
	my (@data, $list) = ();

	# ログファイル読み込み
	open (FILE, "<$CONFIG{LOG}") or error("ログファイルが開けません: $CONFIG{LOG}");
	flock (FILE, 1);
	@data = <FILE>;
	close (FILE);

	$list = "<table border=1>\n<tr><td>no</td><td>title</td><td>url</td><td>comment</td><td>imageurl</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
	foreach (@data) {
		chomp $_;
		my @tmp = split(/,/, $_);
		$list .= <<_END_
<tr>
	<td><form method="POST" action="$CONFIG{SCRIPT}" style="margin:0;" onSubmit="return confirm('変更を保存します') ">
$tmp[0]</td>
	<td><input type="text" name="title" value="$tmp[1]"></td>
	<td><input type="text" name="url" value="$tmp[2]"></td>
	<td><input type="text" name="comment" value="$tmp[3]"></td>
	<td><input type="text" name="imageurl" value="$tmp[4]"></td>
	<td>
			<input type="hidden" name="no" value="$tmp[0]">
			<input type="hidden" name="action" value="edit">
			<input type="hidden" name="pass" value="$form->{pass}">
			<input type="submit" value="変更">
		</form>
	</td>
	<td>
		<form method="POST" action="$CONFIG{SCRIPT}" style="margin:0;" onSubmit="return confirm('この項目を削除します') ">
			<input type="hidden" name="no" value="$tmp[0]">
			<input type="hidden" name="action" value="delete">
			<input type="hidden" name="pass" value="$form->{pass}">
			<input type="submit" value="削除">
		</form>
	</td>
	<td><a href="$CONFIG{SCRIPT}?action=up&pass=$form->{pass}&no=$tmp[0]">↑</a></td>
	<td><a href="$CONFIG{SCRIPT}?action=down&pass=$form->{pass}&no=$tmp[0]">↓</a></td>
</tr>
_END_
	}
	$list .= "</table>\n";

	print <<_END_;
Content-Type: text/html; charset=Shift_JIS

<html>
<head>
<title>SimpleLink 管理画面</title>
</HEAD>

<BODY>
<H2>SimpleLink 管理画面</H2>
<a href="$CONFIG{SCRIPT}">戻る</a><BR><BR>

<form method="POST" action="$CONFIG{SCRIPT}">
	<table border="0">
	<TR><TD>title</TD><TD>: <input type="text" size="30" name="title"></TD></TR>
	<TR><TD>url</TD><TD>: <input type="text" size="50" name="url"></TD></TR>
	<TR><TD>comment</TD><TD>: <input type="text" size="50" name="comment"></TD></TR>
	<TR><TD>imageurl</TD><TD>: <input type="text" size="50" name="imageurl"></TD></TR>
	</table>
	<input type="hidden" name="action" value="write">
	<input type="hidden" name="pass" value="$form->{pass}">
	<input type="submit" value="追加">
</form>
<BR><BR>

$list

<BR>
</body>
</html>
_END_
}

### ログファイル書き込み ###
sub _write ($) {
	my $form = $_[0];
	my (@data, $no) = ();

	#デコード
	foreach (keys(%$form)) {
		$form->{$_} =~ s/"/&quot;/g;
		$form->{$_} =~ s/,/&#44;/g; #区切り文字
	}

	open (FILE, "+<$CONFIG{LOG}") or error("ログファイルが開けません: $CONFIG{LOG}");
	flock (FILE, 2);
	@data = <FILE>;

	# 最大ID+1
	my @numdata = sort { $b <=> $a } @data;
	$no = (split (/,/, $numdata[0]))[0];
	$no++;
	unshift (@data, "$no,$form->{title},$form->{url},$form->{comment},$form->{imageurl}\n");

	truncate (FILE, 0);
	seek (FILE, 0, 0);
	print FILE @data;
	close (FILE);

	print "Location: $CONFIG{SCRIPT}?action=admin&pass=$form->{pass}\n\n";
}

### 記事削除 ###
sub _delete ($) {
	my $form = $_[0];
	my (@data, @data1) = ();

	if ($form->{no} ne "") {
		open (FILE, "+<$CONFIG{LOG}");
		flock (FILE, 2);
		@data1 = <FILE>;
		foreach (@data1) {
			my @buf = split (/,/, $_);
			push @data, $_ if ($buf[0] ne $form->{no});
		}
		truncate (FILE, 0);
		seek (FILE, 0, 0);
		print FILE @data;
		close (FILE);
	}

	print "Location: $CONFIG{SCRIPT}?action=admin&pass=$form->{pass}\n\n";
}

### 記事編集 ###
sub _edit ($) {
	my $form = $_[0];
	my (@data, @data1) = ();

	#デコード
	foreach (keys(%$form)) {
		$form->{$_} =~ s/"/&quot;/g;
		$form->{$_} =~ s/,/&#44;/g; #区切り文字
	}

	if ($form->{no} ne "") {
		open (FILE, "+<$CONFIG{LOG}");
		flock (FILE, 2);
		@data1 = <FILE>;
		foreach (@data1) {
			my @buf = split (/,/, $_);
			if ($buf[0] ne $form->{no}) {
				push @data, $_;
			}
			else {
				push @data, "$form->{no},$form->{title},$form->{url},$form->{comment},$form->{imageurl}\n";
			}
		}
		truncate (FILE, 0);
		seek (FILE, 0, 0);
		print FILE @data;
		close (FILE);
	}

	print "Location: $CONFIG{SCRIPT}?action=admin&pass=$form->{pass}\n\n";
}

### 順番変更（上） ###
sub _up ($) {
	my $form = $_[0];
	my (@data, $a) = ();

	open (FILE, "+<$CONFIG{LOG}");
	flock (FILE, 2);
	@data = <FILE>;

	my $i = 0;
	foreach (@data) {
		my @buf = split (/,/, $_);
		$a = $i if ($buf[0] eq $form->{no});
		$i++;
	}
	if ($a > 0) {
		@data[$a, $a-1] = @data[$a-1, $a];
	}

	truncate (FILE, 0);
	seek (FILE, 0, 0);
	print FILE @data;
	close (FILE);

	print "Location: $CONFIG{SCRIPT}?action=admin&pass=$form->{pass}\n\n";
}

### 順番変更（下） ###
sub _down ($) {
	my $form = $_[0];
	my (@data, $a) = ();

	open (FILE, "+<$CONFIG{LOG}");
	flock (FILE, 2);
	@data = <FILE>;

	my $i = 0;
	foreach (@data) {
		my @buf = split (/,/, $_);
		$a = $i if ($buf[0] eq $form->{no});
		$i++;
	}
	if ($a < $#data) {
		@data[$a, $a+1] = @data[$a+1, $a];
	}

	truncate (FILE, 0);
	seek (FILE, 0, 0);
	print FILE @data;
	close (FILE);

	print "Location: $CONFIG{SCRIPT}?action=admin&pass=$form->{pass}\n\n";
}

### エラー表示 ###
sub error ($) {
	my $form = shift;
	print <<"_ERROR_";
Content-Type: text/html; charset=Shift_JIS

<HTML>
<HEAD><TITLE>エラー</TITLE></HEAD>
<BODY><center><BR><BR><BR>
<H2>Error!</H2>
<H3>$form</H3><BR><BR>
<a href="javascript:history.go(-1)">[戻る]</a>
</center></body></html>
_ERROR_
	exit;
}

### フォーム読み取り ###
sub ReadParse ($) {
	my ($buf, @pairs, $hash) = ();
	$hash = shift;

	if (uc($ENV{REQUEST_METHOD}) eq "POST") {
		read(STDIN, $buf, $ENV{CONTENT_LENGTH});
	}
	else {
		$buf = $ENV{QUERY_STRING}; 
	}

	@pairs = split(/&/,$buf);
	foreach (@pairs) {
		(my $name, my $value) = split(/=/, $_);
		$value =~ s/\+/ /g;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
		&jcode'convert (\$value,'sjis');
		if ($hash->{$name} ne '') {
			$hash->{$name} .= ",$value";
		} else {
			$hash->{$name} = $value;
		}
	}
	return 1;
}
