#!/usr/bin/perl

#Perlのパス↑サーバーのマニュアルをみて確認

#pkBBS-f ver.8(C)Copyright えふ

#ver.6---さらに軽量化
#ver.7---セキュリティ面の修正
#ver.8---逆引きできないホスト制限 改ページでページリンク レスのテーブルのalign=rightを中止
#         レスのボタンを一番下に置くようにした　レス画面で一番下のレスをアンカーで上に持ってくる

#*************** 設置に必要な最低限の設定項目 ***************************

#--------------【基本ファイル】---------------

$script='whatsnew.cgi';
#CGIスクリプト

$html='diary.html';
#スキン

$a_html='form.html';
#書き込み画面

$logfile='diary.log';
#データを記録するファイル

#--------------【基本設定】---------------

$passwd='9776';
#最初に管理室に入るためのパスワード(英数字8文字以内)

$maxsize=250000;
#投稿量の限度(バイト)画像ファイルを含む

$max=20;
#記録する記事の数

$pagemax=20;
#1ページに表示する記事数

$titlealt='無題';
#タイトルがないときに表示するタイトル '無題'など

$tag=1;
#タグを許可する
#また、1にしたときは下の$inlinkを0にしてください。
#1:する 0:しない

$inlink=1;
#記事中のURLにリンクをはる 1:する 0:しない

@avoid=('<table','<td','<tr','<meta','<form','<embed','<script','<style','<body','<!--');
#禁止タグ($tagを1にしたときのみ有効)

$l_target="_top";
#リンクのターゲット

$iconsize='';
#アイコン画像のサイズ
#アイコンの縦横サイズが全て同じときは、'width="50" height="50"'などと指定すると読み込みが
#スムーズになります。

$weathersize='';
#天気アイコンのサイズ
#上に同じ

$w_align='align="absbottom"';
#天気アイコンのalign

$fukidashisize='';
#吹き出し画像のサイズ
#上と同じ

$jcode_on=1;
#jcode.plを使うか
#0: 使わない 1: 使う

$upimgdir='./upfile/';
#画像をアップするディレクトリ
#CGIスクリプトから見たパス 

$upimgdir_http='';
#BiglobeのようにCGIが別サーバーで動く場合は、''のなかにupfileフォルダの絶対パスをhttp://から記入
#(例)$upimgdir_http='http://www5e.biglobe.ne.jp/~hoge/pkbbs_f/upfile/';

$wh_max=72;
#アップする画像の最大縦横サイズ
#これより大きい場合は縮小します。

$i_align="right";
#アップした画像のalign属性(テキストの回りこみ)

$i_enlarge=1;
#縮小表示された画像をクリックしたら拡大表示させる
#0:しない1:する

$img_style='style="margin-right:10px;margin-bottom:2px"';
#アップした画像のマージンをスタイルで設定
#$img_style='class="img"';のようにクラスを設定してスキン側で設定してもOK

$hizuke=1;
#日付の表示方式を決める
#1:2000/4/26(Wed) 2:30 0:2000年4月26日(水) 2時30分

$jikan=0;
#日付に時刻を表示するか
#1:する0:しない

$cook_on=0;
#管理パスをクッキーに保存するか
#1:する0:しない
#1にしたときは、スキンの管理パス入力フォームで、
#<input size="8" type="password" name="pass" maxlength="8" value="#pass">
#のようにvalue値に#passと記入してください。

$c_valid=360;
#クッキーを保存する日数

#********************** アイコン画面などのデザイン ******************************

#アイコンサンプル画面、使い方画面などのデザイン項目です。

$skin_use=1;
#スキンの文字色、背景色、背景画像などをそのままアイコン画面などに使用する
#1:する 0:しない 

#0にした場合、下の項目でテキスト色などを決めてください。
#管理画面、エラー画面については、必ずこれらが適用されます。

$t_size="10pt";
#テキストの大きさ

$t_color="#000000";
#テキスト色

$l_color="#0000ff";
#リンク色

$b_color="#ffffff";
#背景色

#*********************** 各種機能など必要なら変える項目 ************

#---------------【ホスト制限】---------------

$good_only=0;
#アクセスを拒否したいホストがある場合は1にします。

@rejected=("","","");
#アクセス制限を使う場合、""の中に拒否するホスト名を記述
#ホスト名は、ダイヤルアップの場合アクセスのたびに変わる部分と同じ部分が
#あるので、変わる部分には*をいれてください。
#(例)osaka1-25.ne.jpとosaka2-102.ne.jpなら
#osaka*.ne.jp
#プロキシを拒否するときは、proxy*(ホスト名がproxyではじまっている場合)とか
#*proxy*(ホスト名の途中にproxyとある場合)などと記入します。

#************************ 設定はここまで *************************
my(%FORM,$buff,$c_name,%DUMMY,%COOKIE,$host,$addr,$passflag,@delnum,$r_host,$imagedata,$ext,);

if($good_only){
	&gethost;
	foreach (@rejected){
		$_=~ s/\*/\.\*/g;
		if($r_host=~/$_/i){ &error("このホストからのアクセスを現在禁止しています。"); }
	}
}
$FORM{'page'}=0;
&decode;
sub decode{
	my($upflag,$boundary,@dmy,$upfname,$c_type_line,$dum,$app,$name,$value,$buff,@pairs,$pair);
	if($ENV{'CONTENT_LENGTH'} > $maxsize){ &error("投稿の容量が大きすぎます。"); }
	$upflag=0;
	if($ENV{'CONTENT_LENGTH'} && $ENV{'CONTENT_TYPE'} =~ /multipart\/form-data/){
		binmode(STDIN);
		$boundary = <STDIN>;
		$boundary =~ s/\x0D\x0A//;
		while(<STDIN>){
			if(/upfile/){ 
				s/\x0D\x0A//;
				s/"//g;
				@dmy = split(/filename=/, $_);
	      		$upfname = $dmy[1]; 

				$c_type_line = <STDIN>;
				$c_type_line =~s /\x0D\x0A//;
				($dum, $app) = split(/\//,$c_type_line);

				if($app eq "gif"){
					$ext=".gif";
					$upflag=1;
				}
				elsif($app eq "jpeg"){
					$ext=".jpg";
					$upflag=1;
				}
				elsif($app eq "jpg"){
					$ext=".jpg";
					$upflag=1;
				}
				elsif($app eq "pjpeg"){
					$ext=".jpg";
					$upflag=1;
				}
				elsif($app eq "octet-stream"){
					$app="";
				}
				if($app && !$upflag){
					&error("アップできる画像はJPEG、GIFファイルのみです。");
				}
				if(!$app && $upfname){
					&error("アップできる画像はJPEG、GIFファイルのみです。");
				}
				$dum = <STDIN>;
				while(<STDIN>){
					if(/^$boundary/){
						$imagedata =~s/\x0D\x0A$//;
						last;
					}
					$imagedata .= $_;
				}
			}
			else{
				($dum, $name) = split(/name=/,$_);
				$name =~s /\x0D\x0A//;
				$name =~s /"//g;
				$dum = <STDIN>;
				$value = '';
				while(<STDIN>){
					last if(/^$boundary/);
					$value .= $_;
				}
				$value=~s/\,/&#44;/g;
				if($name eq "message"){
					if(!$tag){
						$value=~s/</&lt;/g;
						$value=~s/>/&gt;/g;
					}
					$value=~s/\x0D\x0A/<br>/g;
				}
				else{
					$value=~s/<//g;
					$value=~s/>//g;
					$value=~s/\x0D\x0A//g;
				}
				$FORM{$name} = $value;
			}
		} #while
	} #if
	else{
		if($ENV{'REQUEST_METHOD'} eq "POST"){
			if($ENV{'CONTENT_LENGTH'} > $maxsize){ &error("投稿量が多すぎます。"); }
			read(STDIN,$buff,$ENV{'CONTENT_LENGTH'});
		}
		else {$buff=$ENV{'QUERY_STRING'};}
		if($buff){ #5
			@pairs=split(/&/,$buff);
			foreach $pair (@pairs){
				($name,$value)=split(/=/,$pair);
				$value=~tr/+/ /;
				$value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
				$value=~s/\,/&#44;/g;
				$value=~s/<//g;
				$value=~s/>//g;
				$value=~s/\x0D\x0A//g;
				if($name eq "number"){ push(@delnum,$value); }
				$FORM{$name}=$value;
			}
		} #5
	} #else
}

$FORM{'name'}=~s/\://g;
$FORM{'home'}=~s/http\:\/\///g;
if($jcode_on){
	require "jcode.pl";
	jcode::convert(\$FORM{'name'},'sjis');
	jcode::convert(\$FORM{'message'},'sjis');
	jcode::convert(\$FORM{'subject'},'sjis');
}
if($ENV{'SCRIPT_NAME'}){ $c_name=$ENV{'SCRIPT_NAME'}; }
else{ $c_name="palcgi"; }
$passflag=0;

if($FORM{'mode'} eq "regist"){ &writebbs; }
elsif($FORM{'mode'} eq "enter"){ &checkpass($FORM{'pass'}); }
elsif($FORM{'mode'} eq "del"){
	if($FORM{'edt'} eq "削除"){ &del; }
	elsif($FORM{'edt'} eq "編集"){ &Edit; }
}
elsif($FORM{'mode'} eq "register"){ &register; }
elsif($FORM{'mode'} eq "iconview"){ &icon; }
elsif($FORM{'mode'} eq "howto"){ &howto; }
elsif($FORM{'mode'} eq "edit"){ &editregist; }
elsif($FORM{'mode'} eq "admin"){ &checkpass($FORM{'pass'}); }
else{ &html; }

sub html{
	my(
	$href,$href2,$real_w,$real_h,$c,$page_next,$page_back,$i,$start,$end,@all,
	$dmy,$table_d,$dummy,$head,$foorer,$table,$no,$resno,$name,$fukidashi,$subject,
	$date,$message,$icon,$weather,$color,$imgfile,$w,$h,$skinline,$footer,$ratio,$wh,
	$nextform,$backform
	);
	if($upimgdir_http){ $upimgdir=$upimgdir_http; }
	unless(open(HTML, $html)){&error("$htmlが開けません。ファイルを確認してください。");}
	if($cook_on){ &getcookie; }
	$skinline = join('',<HTML>);
	close(HTML);
	($head,$dummy) = split(/<!--msgstart-->/, $skinline);
	undef $skinline;
	if($head eq ""){ &error("スキンに&lt;!--msgstart--&gt;が書かれていません。"); }
	($table,$footer) = split(/<!--msgend-->/, $dummy);
	undef $dummy;
	if($footer eq ""){ &error("スキンに&lt;!--msgend--&gt;が書かれていません。"); }
	undef $skinline;
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$dummy=<FILE>;
	print <<EOM;
P3P: CP="ONLi COM CUR OUR"
Content-type: text/html

EOM
	print "<!-- Palskin(C)2002 CGI Pal http://www.cgipal.com -->\n";
	print $head;
	$start=$FORM{'page'}+1;
	$end=$FORM{'page'}+$pagemax;
	$i=0;
	while (<FILE>){
		($no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile,$w,$h)=split(/\,/,$_);
		$pic="";##
		$i++;
		if($start <= $i && $i <= $end){
			if($icon){ $icon="<img src=\"$icon\" border=\"0\" alt=\"\" ${iconsize}>"; }
			if($weather){ $weather="<img src=\"$weather\" border=\"0\" alt=\"\" ${weathersize} ${w_align}>"; }
			if($fukidashi){ $fukidashi="<img src=\"$fukidashi\" border=\"0\" alt=\"\" ${fukidashisize}>"; }
			if($imgfile){
				if($w && $h){
					$href="";
					$href2="";
					if($w > $wh_max || $h > $wh_max){
						$real_w=$w+40;
						$real_h=$h+40;
						if($w > $h){
							$ratio=$h/$w;
							$w=$wh_max;
							$h=int($w*$ratio);
						}
						else{
							$ratio=$w/$h;
							$h=$wh_max;
							$w=int($h*$ratio);
						}
						$href=qq(<a href="#" onclick="openwin('${upimgdir}$imgfile',${real_w},${real_h}); return false;">);
						$href2="</a>";
						if(!$i_enlarge){
							$href="";
							$href2="";
						}
						$pic="<br><span class=notes>クリックすると拡大します</span>";
					}
					$wh="width=\"$w\" height=\"$h\"";
				}
				$imgfile=qq(${href}<img src="${upimgdir}$imgfile" border="0" alt="" align="${i_align}" ${wh} ${img_style}>${href2});
#				$imgfile=qq(<table>\n<tr>\n<td width="110" style="padding:6px 5px 5px 5px">${href}<img src="${upimgdir}$imgfile" border="0" alt="" ${wh} ${img_style}>${href2}${pic}</td>\n);
#				$message=qq(<td valign="top" style="padding:6px 10px 10px 5px">$message</td>\n</tr>\n</table>\n);
			}
			else{
				$message=qq($message\n);
			}

			$table_d=$table;
			$table_d =~ s/<!--icon-->/$icon/;
			$table_d =~ s/\#color/$color/;
			$table_d =~ s/<!--weather-->/$weather/;
			$table_d =~ s/<!--fukidashi-->/$fukidashi/;
			$table_d =~ s/<!--subject-->/$subject/;
			$table_d =~ s/<!--upfile-->/$imgfile/;
			$table_d =~ s/<!--message-->/$message/;
			$table_d =~ s/<!--name-->/$name/;
			$table_d =~ s/<!--date-->/$date/;
			print $table_d;
		}
	}#foreach
	close FILE;
	if($cook_on){ $footer=~s/\#pass/$COOKIE{'pass'}/si; }
	$footer=~s/(<form.*?\#backpage.*?<\/form>)/<!--backform-->/si;
	$backform=$1;
	$footer=~s/(<form.*?\#nextpage.*?<\/form>)/<!--nextform-->/si;
	$nextform=$1;
	$page_next=$FORM{'page'}+$pagemax;
	$page_back=$FORM{'page'}-$pagemax;
	if($page_back>=0){
		$backform=~s/\#backpage/$page_back/;
		$footer=~s/<!--backform-->/$backform/;
	}
	else{ $footer=~s/<!--backform-->//; }
	if($page_next<$i){
		$nextform=~s/\#nextpage/$page_next/;
		$footer=~s/<!--nextform-->/$nextform/;
	}
	else{ $footer=~s/<!--nextform-->//; }
	print $footer;
	exit;
}

sub icon{
	my($i,$skinline,$dummyhead,$dummy,$form,$bodytag,$head,$op,@icons,@namae);
	unless(open(HTML, $a_html)){&error("$htmlが開けません。ファイルを確認してください。");}
	$skinline = join('',<HTML>);
	close(HTML);
	($dummyhead,$dummy) = split(/<!--formstart-->/, $skinline);
	undef $skinline;
	($form,$dummy) = split(/<!--formend-->/, $dummy);
	undef $dummy;
	if($dummyhead=~/(<body.*?>)/i){ $bodytag=$1; }
	$dummyhead =~ s/<\/HEAD>/<\/head>/;
	($head,$dummy) = split(/<\/head>/, $dummyhead);
	undef $dummy;
	$head.="</head>";
	$head.=$bodytag;
	if($form=~/<select name="icon".*?>(.*?)<\/select>/si){ $op=$1; }
	@icons=($op=~/<option value=(.*?)>/gi);
	@namae=($op=~/<option.*?>(.*?)<\/option>/gi);
	if(!$skin_use){
		&header;
		print "<body>\n";
	}
	else{
	print <<EOM;
Content-type: text/html

$head
EOM
	}
	print <<EOM;
<br>
<div align=center>
<form>
<input type="button" value="閉じる" onclick="window.close()">
</form>
</div>
<table align="center">
EOM
	$i=0;
	foreach(@icons){
		s/ //g;
		s/"//g;
		s/selected//i;
		if($_ ne ""){
			print "<tr>\n";
			print "<td><img src=\"$_\" alt=\"\"${iconsize}></td><td>$namae[$i]</td>\n";
			print "</tr>\n";
		}
		$i++;
	}
	print "</table>\n";
	print "</body>\n";
	print "</html>\n";
	exit;
}

sub howto{
	my($li,$li2);
	if($tag){ $li='<li>タグを使うことができますが、閉じ忘れに注意して記入してください。</li>'; }
	else{ $li="<li>タグは一切使えません</li>"; }
	if($inlink){ $li2='<li>記事中のURLは自動でリンクされます</li>'; }
	else{ $li2=""; }
	if(!$skin_use){
		&header;
		print "<body>\n";
	}
	else{
		my($skinline,$dummyhead,$dummy,$bodytag,$head);
		unless(open(HTML, $html)){ &error("$htmlが開けません。ファイルを確認してください。"); }
		$skinline = join('',<HTML>);
		close(HTML);
		($dummyhead,$dummy) = split(/<!--formstart-->/, $skinline);
		undef $skinline;
		undef $dummy;
		if($dummyhead=~/(<body.*?>)/i){ $bodytag=$1; }
		$dummyhead =~ s/<\/HEAD>/<\/head>/;
		($head,$dummy) = split(/<\/head>/, $dummyhead);
		undef $dummy;
		$head.="</head>";
		$head.=$bodytag;
		print <<EOM;
Content-type: text/html

$head
EOM
	}
	print <<EOM;
<br>
<div align=center>
<form>
<input type="button" value="閉じる" onclick="window.close()">
</form>
</div>
<ul>
<li>最大${max}件まで登録できます。古いものから削除されます。</li>
$li
<li>不適当とみなした投稿は削除することがあります。</li>
<li>適当に改行して投稿してください。全角の場合は改行しなくても構\いません。</li>
<li>投稿時にパスワード(英数8字以内)を入力しておくと、自分の投稿を削除することができます。</li>
<li>半角カナは使わないでください。</li>
$li2
</ul>
</body>
</html>
EOM
	exit;
}

sub getcookie{
	my($name,$value,$pair,@pairs,$cookies);
	$cookies=$ENV{'HTTP_COOKIE'};
	@pairs=split(/;/,$cookies);
	foreach $pair(@pairs){
		($name, $value)=split(/=/,$pair);
		$name=~s/ //g;
		$DUMMY{$name}=$value;
	}
	$DUMMY{$c_name} =~ s/\+/ /g;
	$DUMMY{$c_name}=~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
	@pairs=split(/\,/,$DUMMY{$c_name});
	foreach $pair(@pairs){
		($name, $value)=split(/\:/,$pair);
		$COOKIE{$name}=$value;
	}
}

sub writebbs{
	my(
	$pro,$imgfile_d,$imgfile,$imgfilename,$name,$message,$dmy,$no2,$resno2,$coded,@all,
	@new,@newnew,$no,$timer,$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,
	$head,@week,@waweek,$date,$tmp,$ran,$w,$h,$pass,$hm,$delline
	);

	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	if($FORM{'message'} eq "<br>"){ &error("本文が記入されていません。"); }

	if($tag){
		foreach(@avoid){
			if($FORM{'message'} =~/$_/i){ &error("禁止タグが含まれています。"); }
		}
	}

	if($FORM{'subject'} eq "" && $titlealt){ $FORM{'subject'}=$titlealt; }
	$timer=time;
	if($imagedata){
		$pro=$$;
		$imgfile="$timer$pro$ext";
		$imgfilename = $upimgdir.$imgfile;
		unless(open(IMAGE,">$imgfilename")){ &error("画像のアップロードに失敗しました"); }
		binmode(IMAGE);
		binmode(STDOUT);
		print IMAGE $imagedata;
		close(IMAGE);
	}
	undef $imagedata;
	($w,$h)=&getsize($ext,$imgfilename);
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	@all=<FILE>;
	close(FILE);
	$head=shift(@all);
	($no,$pass)=split(/\,/,$head);
	if($no eq ""){ $no=0; }
	$no++;
	($dmy,$name,$dmy,$dmy,$dmy,$message)=split(/\,/,$all[0]);
	if($name eq $FORM{'name'} && $message eq $FORM{'message'}){
		if($imgfilename && -e $imgfilename){ unlink("$upimgdir$imgfilename") or exit; }
		undef @all;
		&html;
	}

	&gethost;

	if($inlink){
		$FORM{'message'} =~s/(http:[\w\/\.\-\_\:\~\&\?\+\=\#\%]+)/<a href=\"$1\" target=\"$l_target\">$1<\/a>/g;
		$FORM{'message'} =~ s/([\w\-\_]+)\@([\w\.\-\_]+)/<a href=\"mailto:$1\@$2\">$1\@$2<\/a>/g;
	}
	($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)=localtime($timer);
	$mon++;
	$min=sprintf("%02d",$min);
	$year=$year+1900;
	@week=('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	@waweek=('日','月','火','水','木','金','土');
	if($jikan){
		if($hizuke){ $hm=" $hour:$min"; }
		else{ $hm=" $hour時$min分"; }
	}
	else{ $hm=""; }
#	if($hizuke){ $date="$year/$mon/$mday($week[$wday])$hm"; }
	if($hizuke){ $date="$year/$mon/$mday"; }
	else{ $date="$year年$mon月$mday日($waweek[$wday])$hm"; }
	$tmp="$no,$FORM{'name'},$FORM{'fukidashi'},$FORM{'subject'},$date,$FORM{'message'},$FORM{'icon'},$FORM{'weather'},$FORM{'color'},$imgfile,$w,$h,$host,\n";
	unshift(@all,$tmp);
	@new=@all;
	undef @all;
	if(@new > $max){
		$delline = pop(@new);
		($dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$imgfile_d)=split(/\,/, $delline);
		if($imgfile_d){
			if(-e "$upimgdir$imgfile_d"){ unlink("$upimgdir$imgfile_d") or exit; }
		}
	}
	unshift(@new,"$no,$pass,\n");
	unless(open(FILE, ">$logfile")){ &error("$logfileに書き込みできません。パーミッションを確認してください。"); }
	print FILE @new;
	undef @new;
	close(FILE);

#	&html;
	&back;
}

sub getsize{
	my($w,$h,$size,$t,$m,$c,$l,$i,$mark,$code,$len);
	if($_[0] eq ".gif"){
		open(GIF, "$_[1]") || return(0,0);
		seek(GIF, 6, 0);
		read(GIF, $size, 4);
		close(GIF);
		($w,$h)=unpack("vv",$size);
		return($w,$h);
	}
	elsif($_[0] eq ".jpg"){
		open(JPEG, "$_[1]") || return(0,0);
		binmode JPEG;
		read JPEG, $b, 2;
		$i=0;
		while(1){
			if($i>10){
				$w=0;
				$h=0;
				last;
			}
			read JPEG, $b, 4;
			($mark, $code, $len) = unpack("a a n", $b);
			if($mark ne "\xFF"){
				$w=0;
				$h=0;
				last;
			}
			elsif((ord($code) >= 0xC0) && (ord($code) <= 0xC3)){
				read JPEG, $b, 5;
				($h, $w) = unpack("xnn", $b);
				last;
			}
			else{ read JPEG, $b, ($len - 2); }
			$i++;
		}
	    close JPEG;
	    return($w, $h);
	}
}

sub gethost{
	$r_host=$ENV{'REMOTE_HOST'};
	$addr=$ENV{'REMOTE_ADDR'};
	if($r_host eq "" || $r_host eq $addr){ $r_host=gethostbyaddr(pack("C4", split(/\./, $addr)),2) || $addr; }
	$host=$r_host;
}

sub checkpass{
	my($pass,$head,$no);
	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	&passcheck($_[0]);
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$head=<FILE>;
	close(FILE);
	($no,$pass)=split(/\,/,$head);
	if($pass eq ""){ #if($pass
		if($_[0] eq $passwd){
			if($FORM{'mode'} eq "enter"){ &Form($_[0]);	}
			else{ &admin; }
		}
		else{ &error("初回入室パスワードが違います。"); }
	} #if($pass
	else{
		&matchpass($_[0],$pass);
		if($passflag){
			if($FORM{'mode'} eq "enter"){ &Form($_[0]);	}
			else{ &admin; }
		}
		else{ &error("パスワードが違います。"); }
	}
}

sub passcheck{
	if($_[0] eq ""){ &error("パスワードを入力してください。"); }
	elsif($_[0]=~/\W/){ &error("パスワードは英数字を入力してください。"); }
}

sub register{
	my(@all,$pass,$no,$coded);
	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	&passcheck($FORM{'newpass'});
	$coded=&encode($FORM{'newpass'});
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	@all=<FILE>;
	close(FILE);
	($no,$pass)=split(/\,/,$all[0]);
	$all[0]="$no,$coded,\n";
	unless(open(FILE, ">$logfile")){ &error("$logfileに書き込みできません。パーミッションを確認してください。"); }
	print FILE @all;
	close(FILE);
	&admin;
}

sub encode{
	my(@saltset,$salt,$newcode);
	@saltset=('a'..'z','A'..'Z','0'..'9');
	srand;
	$salt=$saltset[int(rand(@saltset))].$saltset[int(rand(@saltset))];
	eval{ $newcode=crypt($_[0],$salt); };
	if($@){ &error("暗号化の関数がサポートされていないのでこのサーバーでは使えません。"); }
	if($newcode=~/^\$1\$/){ $newcode=crypt($_[0],'$1$'); }
	return $newcode;
}

sub matchpass{
	my($pass,$coded)=@_;
	my($salt);
	if($coded=~/^\$1\$/){
		if(crypt($pass,'$1$') eq $coded){ $passflag=1; }
	}
	else{
		$salt=substr($coded,0,2);
		if(crypt($pass,$salt) eq $coded){ $passflag=1; }
	}
}

sub del{
	my(@data,$head,$flag,$no,$resno,$line,@new,$dum,@delimg,$imgfile_d,$dmy);

	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	if($FORM{'number'} eq ""){ &error("チェックを入れてください。"); }
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$head=<FILE>;
	while (<FILE>){
		$flag=0;
		($no,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$dmy,$imgfile_d)=split(/\,/,$_);
		foreach $line(@delnum){
			if($no == $line){
				push(@delimg,$imgfile_d);
				$flag=1;
				last;
			}
		}
		if($flag==0){ push(@new,$_); }
	}
	close(FILE);
	undef @data;
	unshift(@new,$head);
	unless(open(FILE, ">$logfile")){ &error("$logfileに書き込みできません。パーミッションを確認してください。"); }
	print FILE @new;
	undef @new;
	close(FILE);
	if($delimg[0]){
		foreach(@delimg){
			if(-e "$upimgdir$_"){ unlink("$upimgdir$_") or exit; }
		}
	}

	undef @new;
	&admin;
}

sub Edit{
	my(
	$weather,@data,$temp,$head,$dummy,$skinline,$no,$name,$fukidashi,$subject,$date,$message,$icon,$color,$imgfile,
	$input
	);
	if($FORM{'number'} eq ""){ &error("チェックを入れてください。"); }
	if($delnum[1]){ &error("編集の場合はチェックは1つだけにしてください。"); }
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$head=<FILE>;
	while(<FILE>){
		$subject="";
		($no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile)=split(/\,/,$_);
		if($no == $delnum[0]){ last; }
	}
	close FILE;
	unless(open(HTML, $a_html)){ &error("$htmlが開けません。ファイルを確認してください。"); }
	$skinline = join('',<HTML>);
	close(HTML);
	($head,$dummy) = split(/<!--formend-->/, $skinline);
	undef $skinline;
	undef $dummy;
	$message=~ s/<br>/\x0D/g;
	$head =~s/(<textarea.*?>)<\/textarea>/$1$message<\/textarea>/i;
	$temp="\n<input type=\"hidden\" name=\"editnum\" value=\"$delnum[0]\">";
	$head =~ s/<input type="hidden" name="mode" value="regist">/<input type="hidden" name="mode" value="edit">$temp/i;

	if($subject){
		$head=~s/(<input type="text" name="subject".*?>)/<!--input-->/i;
		$input=$1;
		$input=~s/value=""/value="$subject"/i;
		$head=~s/<!--input-->/$input/i;
	}

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

EOM
	print $head;
	print "</body>\n";
	print "</html>\n";
	exit;
}

sub editregist{
	my($head,$flag,@new,@data,$no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$host,$imgfile,$w,$h);

	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$head=<FILE>;
	while(<FILE>){
		($no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile,$w,$h,$host)=split(/\,/,$_);
		if($no == $FORM{'editnum'}){ $_="$no,$FORM{'name'},$FORM{'fukidashi'},$FORM{'subject'},$date,$FORM{'message'},$FORM{'icon'},$FORM{'weather'},$FORM{'color'},$imgfile,$w,$h,$host,\n"; }
		push(@new,$_);
	}
	close FILE;
	unshift(@new,$head);
	unless(open(FILE, ">$logfile")){ &error("$logfileに書き込みできません。パーミッションを確認してください。"); }
	print FILE @new;
	undef @new;
	close(FILE);

	&admin;
}

sub setcookie{
	my($timer,@week,$secg, $ming, $hourg, $mdayg, $mong, $yearg, $wdayg, $ydayg, $isdstg,@month,$date_gmt,$cook);

	$timer=time;
	@week=('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	($secg, $ming, $hourg, $mdayg, $mong, $yearg, $wdayg, $ydayg, $isdstg)=gmtime($timer+$c_valid*24*60*60);
	@month=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	$date_gmt=sprintf("%s, %02d\-%s\-%04d %02d:%02d:%02d GMT",$week[$wdayg],$mdayg,$month[$mong],$yearg+1900,$hourg,$ming,$secg);
	$cook="pass:$_[0]";
	$cook =~ s/([^\w\=\& ])/'%' . unpack("H2", $1)/eg;
	$cook =~ tr/ /+/;
	print "Set-Cookie: $c_name=$cook; expires=$date_gmt\n";
}

sub Form{
	my($tmppass);

	unless(open(HTML, $a_html)){ &error("$a_htmlが開けません。ファイルを確認してください。"); }
	if($cook_on){
		if($FORM{'pass'}){ $tmppass=$FORM{'pass'}; }
		else{ $tmppass=$FORM{'newpass'}; }
		&setcookie($tmppass);
	}

	print <<EOM;
P3P: CP="ONLi COM CUR OUR"
Content-type: text/html

EOM
	while(<HTML>){
		s/#pass/$_[0]/;
		print $_;
	}
	close(HTML);
	exit;
}

sub admin{
	my($dummy,$no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile,$w,$h,$host);

	if($ENV{'REQUEST_METHOD'} ne "POST"){ &error("不正なアクセスです。"); }
	&header;

#<p>&lt;&lt;<a href="$script">最新情報にもどる</a></p>
#<p>&lt;&lt;<a href="javascript:void(0)" onclick="opener.location.reload();window.close();">ウィンドウを閉じる</a></p>
	print <<EOM;
<body>
<table width=500 align="center"> 
<tr valign="top">
<form method="POST" action="whatsnew.cgi">
<td width="50%">
<input type="submit" value="×ウィンドウを閉じる" onclick="opener.location.reload();window.close();">
</form>
</td>
<form method="POST" action="whatsnew.cgi">
<td align="right" width="50%">
<input type="hidden" name="mode" value="enter">
<input type="hidden" name="pass" value="$passwd">
<input type="submit" value="&gt;&gt;入力画面にもどる">
</td>
</form>
</tr>
</table>

<table width=500 align="center"> 
<tr>
<td bgcolor="#f3f3f3" align=center>
<b>記事の削除と編集</b>
</td>
</tr>
<tr>
<td><br>
記事を削除するときは、チェックボックスに印をつけて
削除ボタンを押してください。(複数選択可。親記事を
削除すると、レスも削除されます。) 記事の編集をするときは、
一つだけチェックを入れて編集ボタンを押してください。入力フォームが
出ますので、それで編集して送信ボタンを押してください。
</td>
</tr>
</table>
<br>
<br>
<form action="$script" method="POST">
<table align="center">
<tr>
<td>
<input type="hidden" name="mode" value="del">
<input type="submit" class="bt" name="edt" value="削除">
<input type="submit" class="bt" name="edt" value="編集">
</td>
</tr>
</table>
<br>
<br>
EOM

	unless(open(FILE, $logfile)){ &error("$logfileが開けません。ファイルを確認してください。"); }
	$dummy=<FILE>;
	while(<FILE>){
		($no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile,$w,$h,$host)=split(/\,/,$_);
		print <<EOM
<table width="500" cellpadding=3 align=center style="border-style:solid;border-color:#999999;border-width:1px">
<tr>
<td width="20"><input type="checkbox" name="number" value="$no"></td>
<td width="480">
NO.${no}*<br>
DATE: ${date}<br>
HOST: $host<br>
TITLE: $subject<br><br>
MESSAGE:<br>
$message
</td>
</tr>
</table>
<br>
<br>
EOM

	}
	close FILE;
	print <<EOM;
</form>
<table width=500 align="center">
<tr>
<td align=center bgcolor="#f3f3f3" >
<b>管理用パスワードの登録</b>
</td>
</tr>
<tr>
<td><br>
管理画面を呼び出すときのパスワードを登録します。
パスワードを登録あるいは変更するときは、下の入力フォームに新しい
パスワード(英数8字以内)を入力して、登録ボタンを押します。(画面は変わりませんが、
エラーが出なければ登録されています。)
</td>
</tr>
</table>
<br>
<form action="$script" method="POST">
<table align="center"><tr><td>
<input size="8" type="text" name="newpass" maxlength="8"><input type="hidden" name="mode" value="register">
<input type="submit" class="bt" value="登録"></form>
</td></tr></table>
<br>
</form>
</body>
</html>
EOM
	exit;
}

sub header{
	print <<EOM;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title></title>
<style type="text/css">
<!--
body{
color: ${t_color};
background-color: ${b_color};
}
p,td,li,div{
font-size: ${t_size};
}
a{
color: ${l_color};
text-decoration:none
}
input{border-style:solid;border-color:#999999;border-width:1px}
-->
</style>
</head>
EOM
}

sub error{
	&header;
	print <<EOM;
<body>
<br>
<br>
<p align="center"><font color="#ff0000">* ERROR *</font><br><br>
EOM
	print"$_[0]\n";
#<p align="center"><a href="${script}?">もどる</a></p>
	print <<EOM;
</p>
<p align="center"><a href="master_news.htm">もどる</a></p>
</body>
</html>
EOM
	exit;
}
exit;


sub back{
	my($dummy,$no,$name,$fukidashi,$subject,$date,$message,$icon,$weather,$color,$imgfile,$w,$h,$host);
	&header;

	print <<EOM;
<body>
<div align="center">
<p><b>書き込みが完了しました。</b><br>
ホームページを<a href="javascript:void(0)" onclick="opener.location.reload()">リロード（更新）</a>して確認してください。</p>
<p><a href="javascript:void(0)" onclick="opener.location.reload();window.close();">ウィンドウを閉じる</a></p>
</div>
</body>
</html>
EOM
	exit;
}
