#!/usr/local/bin/perl # 上記は、使用するサ−バ−のパスにあわせる事。 #----------------------------------------------------- # Guest book Ver. 2 #----------------------------------------------------- # ---------- ココから下を変更して下さい。------------- # デザインのテンプレートHTMLファイル名。 $template_file = './guest_book.html'; # 投稿内容のログファイル名。 $log_file = './log.dat'; # 管理者パスワード。必ず変更して下さい。 $master_passwd = 'coffee'; # 1画面に表示するスレット数。 $pages = 10; # 1メッセージの文字数制限値。0なら制限なし。 $max_len = 2000; # このCGIのURL。 # フルパスで指定する場合はhttp://から正しく記述する。 # 例: $cgi_url = 'http://www.lens.gr.jp/~html/cgi-bin/board.cgi' $cgi_url = 'http://www.q-michinoeki.net/cgi/bbs/board.cgi'; # 削除ボタンのラベル。 $delete_label = '削除'; # 返信ボタンのラベル。 $reply_label = '返信'; # 返信フォーム画面のタイトル。 # $reply_title1はメッセージ番号の前、$reply_title2は後に表示される。 $reply_title1 = 'Message No. '; $reply_title2 = 'への返信'; # 次ページ表示ボタンのラベル。 $next_label = '次のページ'; # name欄への入力が無かった場合のデフォルト。 $nanashi_label = '匿名希望'; # name表示色 $name_color = '#FF3300'; # subject欄への入力が無かった場合のデフォルト。 $no_subject = 'タイトルなし'; # subject表示色 $subject_color = '#FF9900'; # blood欄への入力が無かった場合のデフォルト。 $no_blood = '一般'; # 曜日名の表現 @wday_array = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); # ---------- ココまで!! ---------------------------- require './jcode.pl'; &GetQuery; if ($FORM{'mode'} eq "Write") { $date = &GetDates; &WriteData; &PrintData; } elsif ($FORM{'mode'} eq "Delete") { &DeleteData; &PrintData; } elsif ($FORM{'mode'} eq "WriteRes") { &PrintResForm; } else { &PrintData; } exit; sub GetDates { my $times = time; my ($sec, $min, $hour, $mday, $month, $year, $wday, $yday, $isdst) = localtime($times); $min = "0$min" if ($min < 10); $hour = "0$hour" if ($hour < 10); $mday = "0$mday" if ($mday < 10); $month = $month + 1; $month = "0$month" if ($month < 10); $year = $year + 1900; my $youbi = $wday_array [$wday]; return "$year/$month/$mday($youbi) $hour:$min"; } sub GetQuery { my (@pairs, $buffer, $pro); read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value, 'sjis'); $value =~ s/\t/ /g; $value =~ s/\r/\n/g; $value =~ s/\n\n/\n/g; $value =~ s/\n/
/g; $FORM{$name} = $value; } } sub WriteData { $org_number = $FORM{'org_number'}; $host = $FORM{'host'}; if ($FORM{'password'} eq "") { $password = &encrypt($master_passwd); } else { $password = &encrypt($FORM{'password'}); } $name = $FORM{'name'}; $name =~ s/ //g; $name =~ s/ //g; $name =~ s//>/g; $name = $nanashi_label if (!$name); $email = $FORM{'email'}; $blood = $FORM{'blood'}; $blood =~ s//>/g; $blood = $no_blood if (!$blood); $url = $FORM{'url'}; $url ="" if ($url eq "http://"); $subject = $FORM{'subject'}; $subject =~ s//>/g; $subject = $no_subject if (!$subject); $board = $FORM{'board'}; if (length($board) > $max_len && $max_len != 0) { $max_moji = $max_len/2; &error("$max_moji文字以内で書き込んで下さい。"); } $board =~ s/
]*)>(.*)/$1/;

		$tag =~ s/^\/(.*)//;

		$tag =~ s/^([^\s]*).*/$1/;

	}

	$board .= '>' if ($board =~ /<\/$/);

	@tags = reverse(@tags);

	foreach $tag (@tags) {

		next if ($tag =~ /(img|^hr$|^br$)/i);

		$board .= "" if ($tag);

	}

	$board .= '">TagError?' if (($board =~ /.*<\/A>/i));

	$board =~ s/;

		close(LOG);

	

		if (@lines <= 1) { @lines = (); }

	

		$counter = shift(@lines);

		if ($counter eq "") { $counter = 0; }

		$counter = $counter + 1;

	

		@newlines = ();

	

		if ($org_number eq "") {

			unshift(@lines, "$counter\t0\t$date\t$host\t$password\t$name\t$email\t$blood\t$url\t$subject\t$board\n");

			@newlines = @lines;

		} else {

			$mode = 0;

			foreach (@lines) {

				($number, $resnum) = split(/\t/);

				if ($mode == 0 && $number == $org_number) {

					$mode = 1;

				} elsif ($mode == 1 && $resnum == 0) {

					push(@newlines, "$counter\t$org_number\t$date\t$host\t$password\t$name\t$email\t$blood\t$url\t$subject\t$board\n");

					$mode = 2;

				}

				push(@newlines, $_);

			}

			if ($mode == 1) {

				push(@newlines, "$counter\t$org_number\t$date\t$host\t$password\t$name\t$email\t$blood\t$url\t$subject\t$board\n");

			}

		}

	

		unshift(@newlines, "$counter\n");

		open(LOG, ">$log_file") || &error("Can't Write Log File.");

		&lock;

		seek(LOG, 0, 0);

		print LOG @newlines;

		&unlock;

		close(LOG);

	}

}



sub DeleteData {

	if ($FORM{'number'} ne "" && $FORM{'password'} ne "") {



		@lines = ();

		open(LOG, "$log_file") || &error("Can't Open Log File.");

		seek(LOG, 0, 0);

		@lines = ;

		close(LOG);



		$counter = shift(@lines);

		if ($counter eq "") { $counter = 0; }



		$mode = 0;

		foreach (@lines) {

			($number, $org_number, $date, $host, $password) = split(/\t/);

			if ($mode == 0 && $number == $FORM{'number'}) {

				$org_password = $password;

				if ($org_number == 0) {

					$mode = 2;

				} else {

					$mode = 1;

				}

			} elsif ($mode == 2 && $org_number == $FORM{'number'}) {

				next;

			} else {

				push(@newlines, $_);

			}

		}



		if ($mode != 0 && (&checkpass($FORM{'password'}, $org_password) eq 'Ok' || $FORM{'password'} eq $master_passwd)) {

			unshift(@newlines, $counter);

			open(LOG, ">$log_file") || &error("Can't Write Log File.");

			&lock;

			seek(LOG, 0, 0);

			print LOG @newlines;

			&unlock;

			close(LOG);

		}

	}

}



sub PrintData {

	open(ENT, "$template_file") || &error("Can't Read HTML Skeleton File");

	seek(ENT, 0, 0);

	@enter = ;

	close(ENT);



	open(LOG, "$log_file") || &error("Can't Open Log File.");

	seek(LOG, 0, 0);



	print "Content-type: text/html\n\n";



	foreach (@enter) {

		s/\r/\n/g;

		s/\n\n/\n/g;

		push @html, split(/\n/);

	}

	$progress = 'START';



	foreach (@html) {

		if (//) {

			print "$_\n";

			$progress = 'MESSAGE END';

		} elsif ($progress eq 'MESSAGE') {

			next;

		} elsif (//) {

			print "$_\n";



			$progress = 'MESSAGE';

			$counter = ;



			$page = $FORM{'page'};

			if ($page eq "") {

				$page = 1;

			} 

			$start = (($page - 1) * $pages) + 1;

			

			$count = 0;

			while () {

				chop($_);

				($number, $org_number, $date, $host, $password, $name, $email, $blood, $url, $subject, $board) = split(/\t/);

				if ($org_number == 0) { $count++; }

				if ($count >= $start && $count < ($start + $pages)) {

					if ($email =~ /([\w\-]+)@(.+)\.(.+)/) {

						$name_usr = "$name";

					} else {

						$board =~ s/\t/</g; 

						$name_usr = "$name";

					}

					if ($url) {

						$data_usr = "[$date]($host)
$url"; } else { $data_usr = "[$date]($host)"; } if ($org_number == 0) { print "
\n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
No. $number $subject : $name_usr$blood:\n"; print "
\n"; print "\n"; print " \n"; print "
    $board
$data_usr
\n"; } else { print "
\n"; print "\n"; print " \n"; print " \n"; print "

No. $number $subject : $name_usr$blood:
\n"; print "\n"; print " \n"; print " \n"; print "

    $board
$data_usr
\n"; } } } print "
\n"; print "\n"; print " \n"; print "
\n"; print " \n"; print " \n"; print " Message No. \n"; print " Password \n"; print "
\n"; if ($count >= ($start + $pages)) { $next_page = $page + 1; print "\n"; print " \n"; print "
\n"; print " \n"; print "
\n"; } } else { print "$_\n"; } } close(LOG); } sub PrintResForm { open(ENT, "$template_file") || &error("Can't Read HTML Skeleton File"); seek(ENT, 0, 0); @enter = ; close(ENT); open(LOG, "$log_file") || &error("Can't Open Log File."); seek(LOG, 0, 0); foreach (@enter) { s/\r/\n/g; s/\n\n/\n/g; push @html, split(/\n/); } print "Content-type: text/html\n\n"; $progress = 'START'; foreach (@html) { if (//) { print "$_\n"; $progress = 'MESSAGE END'; } elsif ($progress eq 'MESSAGE') { next; } elsif (//) { print "$_\n"; print "\n"; print " \n"; print "
$reply_title1$FORM{'org_number'}$reply_title2
\n"; } elsif (//) { print "$_\n"; print "\n"; print "\n"; } elsif (//) { print "$_\n"; $progress = 'MESSAGE'; $counter = ; while () { chop($_); ($number, $org_number, $date, $host, $password, $name, $email, $blood, $url, $subject, $board) = split(/\t/); if ($number == $FORM{'org_number'} || $org_number == $FORM{'org_number'}) { if ($email =~ /([\w\-]+)@(.+)\.(.+)/) { $name_usr = "$name"; } else { $board =~ s/\t/</g; $name_usr = "$name"; } if ($url) { $data_usr = "[$date]($host)
$url"; } else { $data_usr = "[$date]($host)"; } if ($org_number == 0) { print "
\n"; print "\n"; print "
No. $number $subject : $name_usr$blood:\n"; print "
\n"; print "\n"; print " \n"; print "
    $board
$data_usr
\n"; } else { print "
\n"; print "\n"; print " \n"; print " \n"; print "

No. $number $subject : $name_usr$blood:
\n"; print "\n"; print " \n"; print " \n"; print "

    $board
$data_usr
\n"; } } } print "
\n"; } else { print "$_\n"; } } close(LOG); } sub encrypt { my $plain = shift(@_); my (@salts, $salt, $crypted); @salts = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); srand(time ^ $$); $salt = $salts[int(rand(@salts))] . $salts[int(rand(@salts))]; $crypted = crypt($plain, $salt); return $crypted; } sub checkpass { my ($inputpass, $logpass) = @_; my $salt; $salt = substr($logpass, 0, 2); if (crypt($inputpass, $salt) eq $logpass) { return 'Ok'; } else { return 'No'; } } sub lock { my $retry = 5; my $symlink_check = (eval { symlink("",""); }, $@ eq ""); if (-e "$log_file.lock") { ($mtime) = (stat("$log_file.lock"))[9]; if ($mtime < time - 180) { unlink("$log_file.lock"); } } if (!$symlink_check) { while(-f "$log_file.lock") { if (--$retry <= 0) { &error("System is busy. Please Retry."); } sleep(1); } open(LOCK,">$log_file.lock"); close(LOCK); } else { while (!symlink(".", "$log_file.lock")) { if (--$retry <= 0) { &error("System is busy. Please Retry."); } sleep(1); } } } sub unlock { unlink("$log_file.lock"); } sub error { if (-e "$log_file.lock") { unlink("$log_file.lock"); } print "Content-type: text/html\n\n"; print "\n"; print "\n"; print "ERROR\n"; print "\n"; print "\n"; print "

\n"; print "

ERROR !

\n"; print "

$_[0]

\n"; print "
\n"; print "\n"; exit; }