#!/usr/local/bin/perl ############################################################################### # (SS)C-BOARD v3.3.8 2002.04.25 by N.Hirai / ssc-board@skullysoft.com # # C-BOARDのオリジナルは t_kimata氏が開発されました、当バージョンは # スカリーソフト( http://www.skullysoft.com/ )により、不具合の修正等を行った改 # 造版です。 # 当バージョンのライセンスはオリジナルと準拠します。 # 著作権はオリジナルソース部分が T.Kimata 氏、改造部分は改造者(複数)にありま # す。 # # オリジナルのライセンスは↓の通りですが、作者への直接の問い合わせは厳禁としま # す。 ############################################################################### # Copyright (C) 2000 T.Kimata # 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; } #── CMT出力 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 { #── バージョン情報 $::VERSION = '3.3.10'; #── 初期化 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; #── 管理人チェック(セットアップ用ではない) (($::FORM{'name'} eq $CNF::master{'name'}) && ($::FORM{'key'} eq $CNF::master{'key'})) && ($::FLAG{'master'} = 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'},'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; } $::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(\"指定されたID($::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 { #── 掲示板IDを確定 &::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; #── POSTデータ読み込み &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 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}; } #┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #┃ POSTデータ読み込み #┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 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 = ""); 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.3 2002/05/15 09:30:00 N.Hirai Exp $;