#!/usr/local/bin/perl
###############################################################################
# (SS)C-BOARD v3.5.4    2003.09.01        by N.Hirai / ssc-board@skullysoft.com
# 
# C-BOARDのオリジナルは t_kimata氏が開発されました、当バージョンは
# スカリーソフト( http://www.skullysoft.com/ )により、不具合の修正等を行った
# 改造版です。
# 当バージョンのライセンスはオリジナルと準拠します。
# 著作権はオリジナルソース部分が T.Kimata 氏、改造部分は改造者（複数）にありま
# す。
#
# オリジナルのライセンスは↓の通りですが、作者への直接の問い合わせは厳禁としま
# す。
###############################################################################
# Copyright (C) 2000 T.Kimata <t_kimata@nk.rim.or.jp>
# http://www.nk.rim.or.jp/~t_kimata/cgi/
# 
# All rights reserved.
# 
# This software is provided 'as-is', without any express or implied warranty.
# In no event will the authors be held liable for any damages arising from the
# use of this software.
# 
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:
# 
# 1. The origin of this software must not be misrepresented; you must not claim
# that you wrote the original software. If you use this software in a product,
# an acknowledgment in the product documentation would be appreciated but is
# not required.
# 
# 2. Altered source versions must be plainly marked as such, and must not be
# misrepresented as being the original software.
# 
# 3. This notice may not be removed or altered from any source distribution.
###############################################################################
#
# 「トクトク」等、ヘッダーをフィルタリングするサーバーの場合はコメントアウト
# （この場合、処理の都合上キャッシュ等の機能が使えなくなります）
# $::SYS{'liar'} = 1;
#───────────────────────────────────────
#
# カレントディレクトリの移動（IIS, mod_perl用）
# BEGIN {
#     chdir 'c:/www/develop/c-board/c-board';
# }
#───────────────────────────────────────

#── 初期化
&::init;

#── アクセス権チェック
if ($CNF::permission{'bse'}{'mode'}) {
	require './cmd/prm.pl'; &PERMISSION::check('bse');
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃■コマンド解釈
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#── 携帯関連
if ($::FLAG{'mobile'}{'mode'} && (($::FORM{'cmd'} eq 'nmb')
 || ($::FORM{'cmd'} eq 'tpc') || ($::FORM{'cmd'} eq 'one'))) {
	&MOBILE::view;
}
elsif ($::FLAG{'mobile'}{'mode'} && ($::FORM{'cmd'} eq 'dln')) {
	&MOBILE::delete_input; 
}
elsif ($::FLAG{'mobile'}{'mode'} && !length($::FORM{'cmd'})
 && (index($ENV{'PATH_INFO'}, '/e_') != 0)) {
	&MOBILE::menu; 
}

#── 記事表示関連
elsif (($::FORM{'cmd'} eq 'one') || ($::FORM{'cmd'} eq 'ntr')
 || ($::FORM{'cmd'} eq 'tre') || ($::FORM{'cmd'} eq 'thr')
 || ($::FORM{'cmd'} eq 'all') || ($::FORM{'cmd'} eq 'tpc')
 || ($::FORM{'cmd'} eq 'nmb')) {
	require './cmd/msg.pl'; &MESSAGE::view;
}

elsif ($::FORM{'cmd'} eq 'jmp') { require './cmd/msg.pl'; &MESSAGE::jump;	}
elsif ($::FORM{'cmd'} eq 'msd') { require './cmd/msg.pl'; &MESSAGE::data;	}

#── 投稿関連
elsif ($::FORM{'cmd'} eq 'pst') { require './cmd/pst.pl'; &POST::write;		}
elsif ($::FORM{'cmd'} eq 'psn') { require './cmd/pst.pl'; &POST::input;		}

#── 検索関連
elsif ($::FORM{'cmd'} eq 'srn') { require './cmd/src.pl'; &SEARCH::input;	}
elsif ($::FORM{'cmd'} eq 'src') { require './cmd/src.pl'; &SEARCH::result;	}

#── カスタマイズ（訪問者）関連
elsif ($::FORM{'cmd'} eq 'csn') { require './cmd/cst.pl'; &CUSTOM::input;	}
elsif ($::FORM{'cmd'} eq 'cst') { require './cmd/cst.pl'; &CUSTOM::write;	}

#── メール認証関連
elsif ($::FORM{'cmd'} eq 'mbn') { require './cmd/mmb.pl'; &MEMBER::input;	}
elsif ($::FORM{'cmd'} eq 'mbr') { require './cmd/mmb.pl'; &MEMBER::regist;	}
elsif ($::FORM{'cmd'} eq 'mlw') { require './cmd/mmb.pl'; &MEMBER::write;	}

#── 過去ログインデックス
elsif ($::FORM{'cmd'} eq 'log') { require './cmd/log.pl'; &LOG::index;		}

#── 匿メール関連
elsif ($::FORM{'cmd'} eq 'hmn') { require './cmd/hml.pl'; &HIDDEN_MAIL::input;	}
elsif ($::FORM{'cmd'} eq 'hml') { require './cmd/hml.pl'; &HIDDEN_MAIL::send;	}

#── 削除関連
elsif ($::FORM{'cmd'} eq 'dlm') { require './cmd/msg.pl'; &MESSAGE::delete;	}

#── 閲覧数カウント・未読管理処理関連
elsif ($::FORM{'cmd'} eq 'rdw') { require './cmd/rad.pl'; &READ::write;		}

#── 管理者用ツール関連
elsif ($::FORM{'cmd'} eq 'lgn') { require './cmd/lgn.pl'; &LOGIN::input;	}
elsif ($::FORM{'cmd'} eq 'lgw') { require './cmd/lgn.pl'; &LOGIN::write;	}
elsif ($::FORM{'cmd'} eq 'stn') { require './cmd/stp.pl'; &SETUP::input;	}
elsif ($::FORM{'cmd'} eq 'stp') { require './cmd/stp.pl'; &SETUP::write;	}
elsif ($::FORM{'cmd'} eq 'syn') { require './cmd/sty.pl'; &STYLE::input;	}
elsif ($::FORM{'cmd'} eq 'sty') { require './cmd/sty.pl'; &STYLE::write;	}
elsif ($::FORM{'cmd'} eq 'mmn') { require './cmd/mst.pl'; &MASTER::manage;	}
elsif ($::FORM{'cmd'} eq 'bck') { require './cmd/mst.pl'; &MASTER::backup;	}
elsif ($::FORM{'cmd'} eq 'mdl') { require './cmd/mst.pl'; &MASTER::delete;	}
elsif ($::FORM{'cmd'} eq 'mdn') { require './cmd/mst.pl'; &MASTER::edit_input;	}
elsif ($::FORM{'cmd'} eq 'mdt') { require './cmd/mst.pl'; &MASTER::edit;	}
elsif ($::FORM{'cmd'} eq 'plt') { require './cmd/plt.pl'; &PALLET::view;	}
elsif ($::FORM{'cmd'} eq 'mnb') { require './cmd/mnb.pl'; &BOARD::manage;	}
elsif ($::FORM{'cmd'} eq 'mkb') { require './cmd/mnb.pl'; &BOARD::make;		}
elsif ($::FORM{'cmd'} eq 'dlb') { require './cmd/mnb.pl'; &BOARD::delete;	}
elsif ($::FORM{'cmd'} eq 'rst') { require './cmd/rst.pl'; &RESTORE::execution;	}

#── ランキング関連
elsif ($::FORM{'cmd'} eq 'rnr') { require './cmd/rnk.pl'; &RANK::read;		}
elsif ($::FORM{'cmd'} eq 'rnf') { require './cmd/rnk.pl'; &RANK::frequency;	}
elsif ($::FORM{'cmd'} eq 'rnk') { require './cmd/rnk.pl'; &RANK::keyword;	}

#── アクセスログ・カウンタ関連
elsif ($::FORM{'cmd'} eq 'csd') { require './cmd/ces.pl'; &ACCESS::data;	}
elsif ($::FORM{'cmd'} eq 'csx') { require './cmd/ces.pl'; &ACCESS::xml;		}
elsif ($::FORM{'cmd'} eq 'csw') { require './cmd/ces.pl'; &ACCESS::write;	}
elsif ($::FORM{'cmd'} eq 'csv') { require './cmd/ces.pl'; &ACCESS::view;	}
elsif ($::FORM{'cmd'} eq 'csl') { require './cmd/ces.pl'; &ACCESS::log;		}
elsif ($::FORM{'cmd'} eq 'csp') { require './cmd/ces.pl'; &ACCESS::applet;	}

#── キーワード関連
elsif ($::FORM{'cmd'} eq 'kyv') { require './cmd/kyw.pl'; &KEYWORD::view;	}
elsif ($::FORM{'cmd'} eq 'kys') { require './cmd/kyw.pl'; &KEYWORD::search;	}

#── ＣＭＴ出力
elsif (exists $::FORM{'point'}) {
	require './cmd/cmt.pl'; $::FLAG{'incm'} = 1; &CMT::view;
}

#── その他各種出力関連
elsif ($::FORM{'cmd'} eq 'mge') { &BASE::output('image');			}
elsif ($::FORM{'cmd'} eq 'fle') { &BASE::output('file');			}
elsif ($::FORM{'cmd'} eq 'mgv') { require './cmd/mge.pl'; &IMAGE::view;		}
elsif ($::FORM{'cmd'} eq 'lct') { &BASE::location;				}
elsif ($::FORM{'cmd'} eq 'css') { &BASE::css;					}
elsif ($::FORM{'cmd'} eq 'jar') { &BASE::jar;					}
elsif ($::FORM{'cmd'} eq 'qvh') { require './cmd/qua.pl'; &AQUA::view_hue;	}
elsif ($::FORM{'cmd'} eq 'xms') { require './cmd/xsl.pl'; &XSL::message;	}
elsif ($::FORM{'cmd'} eq 'xcs') { require './cmd/xsl.pl'; &XSL::access;		}
elsif ($::FORM{'cmd'} eq 'xrs') { require './cmd/xsl.pl'; &XSL::rss;		}
elsif ($::FORM{'cmd'} eq 'nvv') { require './cmd/env.pl'; &ENV::view;		}
elsif ($::FORM{'cmd'} eq 'smv') { require './cmd/smr.pl'; &SUMMARY::view;	}
elsif ($::FORM{'cmd'} eq 'rss') { require './cmd/rss.pl'; &RSS::view;		}
elsif (($::FORM{'cmd'} eq 'mji') || (index($ENV{'PATH_INFO'}, '/e_') == 0)) {
	require './cmd/mji.pl'; &EMOJI::view;
}

# HELP
elsif ($::FORM{'cmd'} eq 'hlp') { require './cmd/hlp.pl'; &HLP::view; }

#── 記事表示
else {
	require './cmd/msg.pl';
	$::FORM{'cmd'} = $::COOKIE{'default'}; &MESSAGE::view;
}
exit;
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

package main;

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   初期化
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub init {
	#── バージョン情報
	$::C_BOARD_LINK = 'http://www.skullysoft.com/';
	$::VERSION = '3.5.4';
	$::VERSION_LINK = 'http://www.skullysoft.com/';
	
	#── 初期化
	undef %::FORM; undef %::FLAG; undef %::COOKIE;

	#── 動作モード
	$::FLAG{'debug'} = 0; # （0: 通常モード 1:追跡モード 2:開発モード）

	#── 既知のロックモード
	$::FLAG{'lock'}{'mode'} = [qw(dbg ces pst msg slg rad stp)];

	#── mod_perl用（「Location」の時も「200」･･･）
	(index($ENV{'GATEWAY_INTERFACE'}, 'CGI-Perl/') == 0)
		&& !$ENV{'PERL_SEND_HEADER'}
		&& (print ($ENV{'SERVER_PROTOCOL'} || 'HTTP/1.0'), "200 OK\n");

	#── 時間をセット
	$::FLAG{'time'} = time();

	#── プラットフォームをセット
	&::set_platform;

	#── デバッグ用
	($::FLAG{'debug'} == 2) && &::debug_init;

	#── ライブラリを読み込む
	do './cmd/bse.pl'; do './config.cgi';
	$::FLAG{'base'} = '.';

	#── リクエストを読み込む
	&::read_request;

	#── スキンを設定
	&::skin;

	#── クッキーを処理
	&::cookie;
	
	#── 管理人チェック（セットアップ用ではない）
	require './cmd/etc.pl';
	((&ETC::name_matching($::FORM{'name'},$CNF::master{'name'},$CNF::master{'mode'}))
		&& ($::FORM{'key'} eq $CNF::master{'key'})) && ($::FLAG{'master'} = 1);
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   プラットフォームをセット
#┃   ※先頭一致 "== 0" 、部分一致 "!= -1"
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub set_platform {
	($^O eq 'MSWin32') && ($::FLAG{'mswin'} = 1);
	$ENV{'HTTP_USER_AGENT'} =~ s/\s+/ /g;
	if (index($ENV{'HTTP_USER_AGENT'}, 'DoCoMo') == 0) {
		$::FLAG{'mobile'}{'imode'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'J-PHONE') == 0) {
		$::FLAG{'mobile'}{'jsky'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'Vodafone') == 0) {
		$::FLAG{'mobile'}{'jsky'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'SoftBank') == 0) {
		$::FLAG{'mobile'}{'jsky'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'},'KDDI') == 0) {
		$::FLAG{'mobile'}{'hdml'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'UP.Browser') == 0) {
		$::FLAG{'mobile'}{'hdml'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'ASTEL') == 0) {
		$::FLAG{'mobile'}{'astel'} = 1;
	}
	elsif (index($ENV{'HTTP_USER_AGENT'}, 'DDIPOCKET') != -1) {
		$::FLAG{'mobile'}{'imode'} = 1;
	}
	$::FLAG{'mobile'} && ($::FLAG{'mobile'}{'mode'} = 1);
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   クッキーを処理
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub cookie {
	&CGI::read_cookie($CNF::cookie{'name'});
	map($::COOKIE{$_} ||= $CNF::view{'page'}{$_}{'number'} || 10,
		qw(all mbl tpc tre thr nmb));
	$::COOKIE{'mmn'} = $CNF::view{'page'}{'mmn'}{'number'};
	$::COOKIE{'default'} ||= $CNF::view{'default'}{'mode'};
	length($::COOKIE{'number'})
		or ($::COOKIE{'number'} = $CNF::view{'number'}{'mode'});
	length($::COOKIE{'read'})
		or ($::COOKIE{'read'} = $CNF::view{'read'}{'mode'});
	$::COOKIE{'new'} ||= $CNF::view{'new'}{'day'};
	$::COOKIE{'user_id'} ||= &COMMON::make_id;
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   クライアントに合ったスキンを設定
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub skin {
	if ($::FLAG{'mobile'}{'hdml'}) {
		do './cmd/hdm.pl'; $::FLAG{'template'} = './style/hdml';
		*BASE::init = *MOBILE::init; # !
	}
	elsif ($::FLAG{'mobile'}{'mode'}) {
		do './cmd/mbl.pl'; $::FLAG{'template'} = './style/mobile';
	}
	elsif (length($CNF::skin{'type'}) && -e "./style/$CNF::skin{'type'}") {
		$::FLAG{'template'} = "./style/$CNF::skin{'type'}";
	}
	else { $::FLAG{'template'} = "./style";}
	do "$::FLAG{'template'}/bse.txt";
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   設定ファイルを読み込む
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub read_cnf {
	($::FLAG{'read_cnf'} || $::FORM{'id'} !~ /^\w+$/) && return;
	-e "$CNF::place{'data'}{'path'}/$::FORM{'id'}/config.cgi"
		or &::error(\"指定されたＩＤ($::FORM{'id'})の掲示板は存在しません。");
	$::FLAG{'base'} = "$CNF::place{'data'}{'path'}/$::FORM{'id'}";
	untie %CNF::post; untie %CNF::mail; untie %CNF::tag; untie %CNF::upload;
	untie %CNF::mobile; do "$::FLAG{'base'}/config.cgi";
	$::FLAG{'read_cnf'} = 1;
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   送信データ読み込み
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub read_request {
	#── 掲示板ＩＤを確定
	&::read_request_sub(\$ENV{'QUERY_STRING'}); &::read_cnf;

	#── 投稿メソッドチェック
	(($::FORM{'cmd'} eq 'pst') || ($::FORM{'cmd'} eq 'hml'))
		&& !$::FLAG{'mobile'}{'mode'} && &::error(\'投稿メソッドが不正です。');

	#── 日本語等が含まれる可能性がない時
	(($ENV{'REQUEST_METHOD'} eq 'POST') || ($::FORM{'cmd'} eq 'src')
	 || ($::FORM{'cmd'} eq 'mbr') || ($::FORM{'cmd'} eq 'pst')
	 || ($::FORM{'cmd'} eq 'kys')) or return;

	#── ＰＯＳＴデータ読み込み
	&::read_post_request;

	#── データを%::FORMに読み込む
	sub read_request_sub {
		my $r_buffer = shift;
		foreach (split(/[&;]/, ${$r_buffer})) {
			my($name, $value) = split(/=/, $_, 2);
			  &CGI::url_decode(\$value);
			  $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
			(($name ne 'id') && defined $::FORM{$name})
				? ($::FORM{$name} .= "\t$value")
				: ($::FORM{$name} = $value);
		}
	}
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   デバッグ用の初期化
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub debug_init {
	eval('$::FLAG{\'start\'} = [(times)[0, 1]]');
	length($ENV{'HTTP_USER_AGENT'}) && return;
	$ENV{'HTTP_USER_AGENT'} ||= 'Mozilla/4.0 (Win98)';
	$ENV{'QUERY_STRING'} ||= "cmd=$ARGV[0];id=test";
	# and more...
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   下準備
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BEGIN {
	require './lib/cmn.pl'; require './lib/cgi.pl';
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   後始末
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
END {
	map(&::unlock($_), keys %{$::FLAG{'lock'}});
}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   オートローダー
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sub AUTOLOAD {
	$::FLAG{'autoload'}++ && exit; # 無限ループ防止
	eval <<'__SUB__';
#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   ロック
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	sub lock {
		my $mode = shift;
		if (length($mode) == 3) {
			grep($mode eq $_, @{$::FLAG{'lock'}{'mode'}})
				or &::error(\'未知のロックモードです。');
			my $time = time(); my $try = $CNF::lock{'try'}{'number'};
			my $lock = "$CNF::place{'data'}{'path'}/$mode\_lock_$time";
			while ($try--) {
				if (rename("$CNF::place{'data'}{'path'}/$mode\_lock", $lock)) {
					return($::FLAG{'lock'}{$mode} = $lock);
				}
				select(undef, undef, undef, 0.05);
			}
			opendir(DIR, $CNF::place{'data'}{'path'}) or return(0);
			my $old_lock = (grep(/^$mode\_lock_\d+$/, readdir(DIR)))[0];
			closedir(DIR); $old_lock or return(0);
			my $old_time = ($old_lock =~ /^$mode\_lock_(\d+)$/)[0];

			if ((($time - $old_time) > 10)
			 && rename("$CNF::place{'data'}{'path'}/$old_lock", $lock)) {
				return($::FLAG{'lock'}{$mode} = $lock);
			}
			else {
				return(0);
			}
		}
		else {	# キャッシュファイル用
				# なるべく衝突を減らすために、ファイルごとにロックする

			#── ロックが古い場合は解除（問題）
			((-M "$CNF::place{'data'}{'path'}/$mode\_lock") * 288 > 1)
				&& &::unlock($mode);

			#── ロック
			my $try = $CNF::lock{'try'}{'number'};
			if ($CNF::lock{'mode'}) {
				while (!symlink($$,
				                "$CNF::place{'data'}{'path'}/$mode\_lock")) {
					--$try or return(0); select(undef, undef, undef, 0.05);
				}
			}
			else {
				while (!mkdir("$CNF::place{'data'}{'path'}/$mode\_lock",
				              0666)) {
					--$try or return(0); select(undef, undef, undef, 0.05);
				}
			}
			$::FLAG{'lock'}{$mode} = 1;
			
			return(1);
		}
	}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   ロック解除
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	sub unlock {
		my $mode = shift;
		if (length($mode) == 3) {
			exists $::FLAG{'lock'}{$mode} or return;
			rename($::FLAG{'lock'}{$mode},
			       "$CNF::place{'data'}{'path'}/$mode\_lock");
		}
		else {	# キャッシュファイル用
			$CNF::lock{'mode'}
				? unlink("$CNF::place{'data'}{'path'}/$mode\_lock")
				: rmdir("$CNF::place{'data'}{'path'}/$mode\_lock");
		}
		delete $::FLAG{'lock'}{$mode};
	}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   ＰＯＳＴデータ読み込み
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	sub read_post_request{
		require './lib/str.pl';

		#── あらかじめ投稿データの大きさをチェック
		($ENV{'CONTENT_LENGTH'}
		  > (($CNF::upload{'size'}{'max'} * $CNF::upload{'enable'}{'number'})
			  + $CNF::post{'body'}{'max'} + 20480))
			&& &::error(\'投稿データが大きすぎます。');

		#── 読み込み
		if ($ENV{'REQUEST_METHOD'} eq 'POST') {
			if ((index($ENV{'CONTENT_TYPE'}, 'multipart/form-data') == 0)) {
				require './cmd/mlf.pl'; &MULTIPART::read;
			}
			else {
				my $buf; read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
				&::read_request_sub(\$buf);
			}
			&::read_cnf;
		}

		my $code = &STRING::code(\$::FORM{'kanji'}); delete $::FORM{'kanji'};
		foreach (keys %::FORM) {
			$::FORM{$_} =~ s/\r\n/\n/g; $::FORM{$_} =~ s/\r/\n/g;
			if (($::FORM{'cmd'} ne 'stp') && ($::FORM{'cmd'} ne 'sty')) {
				$::FORM{$_} =~ s/\t/　　　　/g; $::FORM{$_} =~ s/  /　/g;
			}
			&STRING::etc2sjis(\$::FORM{$_}, $code);
		}
		&STRING::undef_table;
	}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   デバッグ用情報を記録
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	sub debug {
		my $name = shift; my $r_value = shift;
		&::lock('dbg') or return;
		open(DBG, "+>>./$CNF::place{'data'}{'path'}/debug.cgi") or return;
		print DBG '━' x 38, "\n■$name\n${$r_value}\n"; close(DBG);
		&::unlock('dbg');
	}

#┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#┃   エラー表示
#┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	sub error {
		my $r_error = shift;
		(++$::FLAG{'error'} > 25) && exit; my($file, $line) = (caller)[1, 2];
		my $caller = "［$file($line)］";
		($::FLAG{'debug'} == 2) or ($caller = "<!-- $caller -->");
		if ($::FLAG{'file'}) {
			foreach (@{$::FLAG{'file'}}) {
				unlink("$CNF::place{'file'}{'path'}/${$_}{'name'}");
			}
			undef $::FLAG{'file'};
		}
		$::FLAG{'template'} or &::skin;
		do "$::FLAG{'template'}/ror.txt";
		if ($::FLAG{'http_header'}) { &DESIGN::small_error($r_error, $caller);}
		else {
			select(STDOUT); &BASE::head2('ror');
			&DESIGN::error($r_error, $caller); &BASE::foot2('ror'); exit;
		}
	}
__SUB__
	length($@) && die $@; my $name = ($AUTOLOAD =~ /^main::(.+)$/)[0];
	if (!defined &{$name}) {
		&::error(\"定義されていない関数($AUTOLOAD)が呼ばれました。"); exit;
	}
	goto &{'main::' . $name};
}

# $Id: c-board.cgi,v 2.2 2003/06/17 10:00:00 N.Hirai Exp $;
