;#####################
;# perl Library mycgi
;#####################
package mycgi;

use strict;
use Jcode;
use CGI;
use DBI;

use LWP;
use LWP::Simple;
use HTTP::Request::Common;
use HTTP::Cookies;
use MIME::Base64;


#デバッグ関係変数
my $Debug = 0;

#===============================================
# 文字の正規表現
# http://www.din.or.jp/~ohzaki/perl.htm#Character
#===============================================
# 半角スペース
my $space = '\x20';

# 全角スペース
my $Zspace = '(?:\xA1\xA1)'; # EUC-JP
my $Zspace_sjis = '(?:\x81\x40)'; # SJIS

# 全角数字 [０-９]
my $Zdigit = '(?:\xA3[\xB0-\xB9])'; # EUC-JP
my $Zdigit_sjis = '(?:\x82[\x4F-\x58])'; # SJIS

# 全角大文字 [Ａ-Ｚ]
my $Zuletter = '(?:\xA3[\xC1-\xDA])'; # EUC-JP
my $Zuletter_sjis = '(?:\x82[\x60-\x79])'; # SJIS

# 全角小文字 [ａ-ｚ]
my $Zlletter = '(?:\xA3[\xE1-\xFA])'; # EUC-JP
my $Zlletter_sjis = '(?:\x82[\x81-\x9A])'; # SJIS

# 全角アルファベット [Ａ-Ｚａ-ｚ]
my $Zalphabet = '(?:\xA3[\xC1-\xDA\xE1-\xFA])'; # EUC-JP
my $Zalphabet_sjis = '(?:\x82[\x60-\x79\x81-\x9A])'; # SJIS

# 全角ひらがな [ぁ-ん]
my $Zhiragana = '(?:\xA4[\xA1-\xF3])'; # EUC-JP
my $Zhiragana_sjis = '(?:\x82[\x9F-\xF1])'; # SJIS

# 全角ひらがな(拡張) [ぁ-ん゛゜ゝゞ]
my $ZhiraganaExt = '(?:\xA4[\xA1-\xF3]|\xA1[\xAB\xAC\xB5\xB6])'; # EUC-JP
my $ZhiraganaExt_sjis = '(?:\x82[\x9F-\xF1]|\x81[\x4A\x4B\x54\x55])'; # SJIS

# 全角カタカナ [ァ-ヶ]
my $Zkatakana = '(?:\xA5[\xA1-\xF6])'; # EUC-JP
my $Zkatakana_sjis = '(?:\x83[\x40-\x96])'; # SJIS

# 全角カタカナ(拡張) [ァ-ヶ・ーヽヾ]
my $ZkatakanaExt = '(?:\xA5[\xA1-\xF6]|\xA1[\xA6\xBC\xB3\xB4])'; # EUC-JP
my $ZkatakanaExt_sjis = '(?:\x83[\x40-\x96]|\x81[\x45\x5B\x52\x53])'; # SJIS

# 半角カタカナ [ヲ-゜]
my $Hkatakana = '(?:\x8E[\xA6-\xDF])'; # EUC-JP
my $Hkatakana_sjis = '[\xA6-\xDF]'; # SJIS

# EUC-JP文字
my $ascii = '[\x00-\x7F]'; # 1バイト EUC-JP文字
my $twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'; # 2バイト EUC-JP文字
my $threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト EUC-JP文字
my $character = "(?:$ascii|$twoBytes|$threeBytes)"; # EUC-JP文字

# EUC-JP文字(機種依存文字・未定義領域・3バイト文字を含まない)
my $character_strict = '(?:[\x00-\x7F]|' # ASCII
  . '\x8E[\xA1-\xDF]|' # 半角カタカナ
  . '[\xA1\xB0-\xCE\xD0-\xF3][\xA1-\xFE]|' # 1,16-46,48-83区
  . '\xA2[\xA1-\xAE\xBA-\xC1\xCA-\xD0\xDC-\xEA\xF2-\xF9\xFE]|' # 2区
  . '\xA3[\xB0-\xB9\xC1-\xDA\xE1-\xFA]|' # 3区
  . '\xA4[\xA1-\xF3]|' # 4区
  . '\xA5[\xA1-\xF6]|' # 5区
  . '\xA6[\xA1-\xB8\xC1-\xD8]|' # 6区
  . '\xA7[\xA1-\xC1\xD1-\xF1]|' # 7区
  . '\xA8[\xA1-\xC0]|' # 8区
  . '\xCF[\xA1-\xD3]|' # 47区
  . '\xF4[\xA1-\xA6])'; # 84区

# EUC-JP未定義文字(機種依存文字・3バイト文字を含む)
my $character_undef = '(?:[\xA9-\xAF\xF5-\xFE][\xA1-\xFE]|' # 9-15,85-94区
  . '\x8E[\xE0-\xFE]|' # 半角カタカナ
  . '\xA2[\xAF-\xB9\xC2-\xC9\xD1-\xDB\xEB-\xF1\xFA-\xFD]|' # 2区
  . '\xA3[\XA1-\xAF\xBA-\xC0\xDB-\xE0\xFB-\xFE]|' # 3区
  . '\xA4[\xF4-\xFE]|' # 4区
  . '\xA5[\xF7-\xFE]|' # 5区
  . '\xA6[\xB9-\xC0\xD9-\xFE]|' # 6区
  . '\xA7[\xC2-\xD0\xF2-\xFE]|' # 7区
  . '\xA8[\xC1-\xFE]|' # 8区
  . '\xCF[\xD4-\xFE]|' # 47区
  . '\xF4[\xA7-\xFE]|' # 84区
  . '\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト文字

# SJIS文字
my $oneByte_sjis = '[\x00-\x7F\xA1-\xDF]'; # 1バイト SJIS文字
my $twoBytes_sjis =
  '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; # 2バイト SJIS文字
my $character_sjis = "(?:$oneByte_sjis|$twoBytes_sjis)"; # SJIS文字

# SJIS文字(機種依存文字・未定義領域を含まない)
my $character_sjis_strict = '(?:[\x00-\x7F\xA1-\xDF]|' # ASCII，半角カタカナ
  . '[\x89-\x97\x99-\x9F\xE0-\xE9][\x40-\x7E\x80-\xFC]|' # 17-46,49-82区
  . '\x81[\x40-\x7E\x80-\xAC\xB8-\xBF\xC8-\xCE\xDA-\xE8\xF0-\xF7\xFC]|' # 1,2区
  . '\x82[\x4F-\x58\x60-\x79\x81-\x9A\x9F-\xF1]|' # 3,4区
  . '\x83[\x40-\x7E\x80-\x96\x9F-\xB6\xBF-\xD6]|' # 5,6区
  . '\x84[\x40-\x60\x70-\x7E\x80-\x91\x9F-\xBE]|' # 7,8区
  . '\x88[\x9F-\xFC]|' # 15,16区
  . '\x98[\x40-\x72\x9F-\xFC]|' # 47,48区
  . '\xEA[\x40-\x7E\x80-\xA4])'; # 83,84区

# SJIS未定義文字(機種依存文字を含む)
my $character_sjis_undef =
  '(?:[\x85-\x87\xEB-\xFC][\x40-\x7E\x80-\xFC]|' # 9-14,85-120区
  . '\x81[\xAD-\xB7\xC0-\xC7\xCF-\xD9\xE9-\xEF\xF8-\xFB]|' # 1,2区
  . '\x82[\x40-\x4E\x59-\x5F\x7A-\x7E\x80\x9B-\x9E\xF2-\xFC]|' # 3,4区
  . '\x83[\x97-\x9E\xB7-\xBE\xD7-\xFC]|' # 5,6区
  . '\x84[\x61-\x6F\x92-\x9E\xBF-\xFC]|' # 7,8区
  . '\x88[\x40-\x7E\x80-\x9E]|' # 15,16区
  . '\x98[\x73-\x7E\x80-\x9E]|' # 47,48区
  . '\xEA[\xA5-\xFC])'; # 83,84区

# iモード対応 絵文字
my $iPictograph_base = '(?:\xF8[\x9F-\xFC]|' # 基本絵文字(SJIS)
  . '\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0])';
my $iPictograph_ext = '(?:\xF9[\xB1-\xFC])'; # 拡張絵文字(SJIS)
my $iPictograph =
  '(?:$iPictograph_base|$iPictograph_ext)'; # iモード対応 絵文字(SJIS)

#改行コードを統一する
sub ChangeCRLF
{
# $target = "\n", "\r\n", "\r", "<BR>\n", ""
	my ($s, $target) = @_;
	$s =~ s/\x0D\x0A|\x0D|\x0A/$target/g;
	return $s;
}

#数値を3桁ごとにカンマで区切る
sub AddComma3
{
	my $s = @_;
	1 while($s =~ s/^([-+]?\d+)(\d{3})/$1,$2/);
	return $s;
}

# $num を四捨五入して小数点以下 $decimals桁にする
sub round {
  my ($num, $decimals) = @_;
  my ($format, $magic);
  $format = '%.' . $decimals . 'f';
  $magic = ($num > 0) ? 0.5 : -0.5;
  sprintf($format, int(($num * (10 ** $decimals)) + $magic) /
                   (10 ** $decimals));
}

# $num を切り上げて小数点以下 $decimals桁にする
sub ceil {
  my ($num, $decimals) = @_;
  my ($format, $tmp1, $tmp2);
  $format = '%.' . $decimals . 'f';
  $tmp1 = $num * (10 ** $decimals);
  $tmp2 += $tmp1 <=> ($tmp2 = int($tmp1));
  sprintf($format, $tmp2 / (10 ** $decimals));
}

# HTMLタグの正規表現 $tag_regex
my $tag_regex_ = q{[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$(?!\n))}; #'}}}};
my $comment_tag_regex =
    '<!(?:--[^-]*-(?:[^-]+-)*?-(?:[^>-]*(?:-[^>-]+)*?)??)*(?:>|$(?!\n)|--.*$)';
my $tag_regex = qq{$comment_tag_regex|<$tag_regex_};

# $uri が正しい URI か判定する
sub CheckURI
{
	my $uri = @_;

my $digit = q{[0-9]};
my $upalpha = q{[A-Z]};
my $lowalpha = q{[a-z]};
my $alpha = qq{(?:$lowalpha|$upalpha)};
my $alphanum = qq{(?:$alpha|$digit)};
my $hex = qq{(?:$digit|[A-Fa-f])};
my $escaped = qq{%$hex$hex};
my $mark = q{[-_.!~*'()]};
my $unreserved = qq{(?:$alphanum|$mark)};
my $reserved = q{[;/?:@&=+$,]};
my $uric = qq{(?:$reserved|$unreserved|$escaped)};
my $fragment = qq{$uric*};
my $query = qq{$uric*};
my $pchar = qq{(?:$unreserved|$escaped|} . q{[:@&=+$,])};
my $param = qq{$pchar*};
my $segment = qq{$pchar*(?:;$param)*};
my $path_segments = qq{$segment(?:/$segment)*};
my $abs_path = qq{/$path_segments};
my $uric_no_slash = qq{(?:$unreserved|$escaped|} . q{[;?:@&=+$,])};
my $opaque_part = qq{$uric_no_slash$uric*};
my $path = qq{(?:$abs_path|$opaque_part)?};
my $port = qq{$digit*};
my $IPv4address = qq{$digit+\\.$digit+\\.$digit+\\.$digit+};
my $toplabel = qq{(?:$alpha|$alpha(?:$alphanum|-)*$alphanum)};
my $domainlabel = qq{(?:$alphanum|$alphanum(?:$alphanum|-)*$alphanum)};
my $hostname = qq{(?:$domainlabel\\.)*$toplabel\\.?};
my $host = qq{(?:$hostname|$IPv4address)};
my $hostport = qq{$host(?::$port)?};
my $userinfo = qq{(?:$unreserved|$escaped|} . q{[;:&=+$,])*};
my $server = qq{(?:(?:$userinfo\@)?$hostport)?};
my $reg_name = qq{(?:$unreserved|$escaped|} . q{[$,;:@&=+])+};
my $authority = qq{(?:$server|$reg_name)};
my $scheme = qq{$alpha(?:$alpha|$digit|[-+.])*};
my $rel_segment = qq{(?:$unreserved|$escaped|} . q{[;@&=+$,])+};
my $rel_path = qq{$rel_segment(?:$abs_path)?};
my $net_path = qq{//$authority(?:$abs_path)?};
my $hier_part = qq{(?:$net_path|$abs_path)(?:\\?$query)?};
my $relativeURI = qq{(?:$net_path|$abs_path|$rel_path)(?:\\?$query)?};
my $absoluteURI = qq{$scheme:(?:$hier_part|$opaque_part)};
my $URI_reference = qq{(?:$absoluteURI|$relativeURI)?(?:#$fragment)?};

my $pattern = $URI_reference;

	return 1 if $uri =~ /^$pattern$/o;
	return 0;
}

# $http が正しい http URL か判定する
sub CheckHTTPURL
{
	my $http = @_;

my $digit = q{[0-9]};
my $upalpha = q{[A-Z]};
my $lowalpha = q{[a-z]};
my $alpha = qq{(?:$lowalpha|$upalpha)};
my $alphanum = qq{(?:$alpha|$digit)};
my $hex = qq{(?:$digit|[A-Fa-f])};
my $escaped = qq{%$hex$hex};
my $mark = q{[-_.!~*'()]};
my $unreserved = qq{(?:$alphanum|$mark)};
my $reserved = q{[;/?:@&=+$,]};
my $uric = qq{(?:$reserved|$unreserved|$escaped)};
my $query = qq{$uric*};
my $pchar = qq{(?:$unreserved|$escaped|} . q{[:@&=+$,])};
my $param = qq{$pchar*};
my $segment = qq{$pchar*(?:;$param)*};
my $path_segments = qq{$segment(?:/$segment)*};
my $abs_path = qq{/$path_segments};
my $port = qq{$digit*};
my $IPv4address = qq{$digit+\\.$digit+\\.$digit+\\.$digit+};
my $toplabel = qq{(?:$alpha|$alpha(?:$alphanum|-)*$alphanum)};
my $domainlabel = qq{(?:$alphanum|$alphanum(?:$alphanum|-)*$alphanum)};
my $hostname = qq{(?:$domainlabel\\.)*$toplabel\\.?};
my $host = qq{(?:$hostname|$IPv4address)};
my $http_URL = qq{http://$host(?::$port)?(?:$abs_path(?:\\?$query)?)?};

my $pattern = $http_URL;

	return 1if $http =~ /^$pattern$/;
	return 0;
}

# ftp URL の正規表現 $ftp_URL_regex
sub CheckFTPURL
{
	my $ftp = @_;
	
my $digit = q{[0-9]};
my $alpha = q{[a-zA-Z]};
my $alphanum = q{[a-zA-Z0-9]};
my $hex = q{[0-9A-Fa-f]};
my $escaped = qq{%$hex$hex};
my $uric = q{(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]} . qq{|$escaped)};
my $fragment = qq{$uric*};
my $query = qq{$uric*};
my $pchar = q{(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]} . qq{|$escaped)};
my $segment = qq{$pchar*};
my $ftptype = q{[AIDaid]};
my $path_segments = qq{$segment(?:/$segment)*(?:;type=$ftptype)?};
my $abs_path = qq{/$path_segments};
my $port = qq{$digit*};
my $IPv4address = qq{$digit+\\.$digit+\\.$digit+\\.$digit+};
my $toplabel = qq{$alpha(?:} . q{[-a-zA-Z0-9]*} . qq{$alphanum)?};
my $domainlabel = qq{$alphanum(?:} . q{[-a-zA-Z0-9]*} . qq{$alphanum)?};
my $hostname = qq{(?:$domainlabel\\.)*$toplabel\\.?};
my $host = qq{(?:$hostname|$IPv4address)};
my $hostport = qq{$host(?::$port)?};
my $user = q{(?:[-_.!~*'()a-zA-Z0-9;&=+$,]|} . qq{$escaped)*};
my $password = $user;
my $userinfo = qq{$user(?::$password)?};
my $server = qq{(?:$userinfo\@)?$hostport};
my $authority = qq{$server};
my $scheme = q{ftp};
my $net_path = qq{//$authority(?:$abs_path)?};
my $hier_part = qq{$net_path(?:\\?$query)?};
my $absoluteURI = qq{$scheme:$hier_part};
my $URI_reference = qq{$absoluteURI(?:#$fragment)?};
my $ftp_URL_regex = q{\b} . $URI_reference;

	return 1if $ftp =~ /^$ftp_URL_regex$/;
	return 0;
}

# $email が正しいメールアドレス(From用、"T. Kamiya <tkamiya@..>"もOK)か判定する
sub CheckEMailAddress
{
	my $email = @_;
	
my $esc         = '\\\\';
my $Period      = '\.';
my $space       = '\040';
my $tab         = '\t';
my $OpenBR      = '\[';
my $CloseBR     = '\]';
my $OpenParen   = '\(';
my $CloseParen  = '\)';
my $NonASCII    = '\x80-\xff';
my $ctrl        = '\000-\037';
my $CRlist      = '\n\015';
my $qtext       = qq/[^$esc$NonASCII$CRlist\"]/;
my $dtext       = qq/[^$esc$NonASCII$CRlist$OpenBR$CloseBR]/;
my $quoted_pair = qq<${esc}[^$NonASCII]>;
my $ctext       = qq<[^$esc$NonASCII$CRlist()]>;
my $Cnested     = qq<$OpenParen$ctext*(?:$quoted_pair$ctext*)*$CloseParen>;
my $comment     =
    qq<$OpenParen$ctext*(?:(?:$quoted_pair|$Cnested)$ctext*)*$CloseParen>;
my $X           = qq<[$space$tab]*(?:${comment}[$space$tab]*)*>;
my $atom_char   = qq/[^($space)<>\@,;:\".$esc$OpenBR$CloseBR$ctrl$NonASCII]/;
my $atom        = qq<$atom_char+(?!$atom_char)>;
my $quoted_str  = qq<\"$qtext*(?:$quoted_pair$qtext*)*\">;
my $word        = qq<(?:$atom|$quoted_str)>;
my $domain_ref  = $atom;
my $domain_lit  = qq<$OpenBR(?:$dtext|$quoted_pair)*$CloseBR>;
my $sub_domain  = qq<(?:$domain_ref|$domain_lit)$X>;
my $domain      = qq<$sub_domain(?:$Period$X$sub_domain)*>;
my $route       = qq<\@$X$domain(?:,$X\@$X$domain)*:$X>;
my $local_part  = qq<$word$X(?:$Period$X$word$X)*>;
my $addr_spec   = qq<$local_part\@$X$domain>;
my $route_addr  = qq[<$X(?:$route)?$addr_spec>];
my $phrase_ctrl = '\000-\010\012-\037';
my $phrase_char =
   qq/[^()<>\@,;:\".$esc$OpenBR$CloseBR$NonASCII$phrase_ctrl]/;
my $phrase      =
    qq<$word$phrase_char*(?:(?:$comment|$quoted_str)$phrase_char*)*>;
my $mailbox     = qq<$X(?:$addr_spec|$phrase$route_addr)>;

	return 1 if $email =~ /^$mailbox$/o;
	return 0;
}

# メールアドレス(addr-spec)のみの正規表現 $mail_regex
sub CheckEMailAddrSpec
{
	my $email = @_;
	
my $esc         = '\\\\';
my $Period      = '\.';
my $space       = '\040';
my $OpenBR      = '\[';
my $CloseBR     = '\]';
my $NonASCII    = '\x80-\xff';
my $ctrl        = '\000-\037';
my $CRlist      = '\n\015';
my $qtext       = qq/[^$esc$NonASCII$CRlist\"]/;
my $dtext       = qq/[^$esc$NonASCII$CRlist$OpenBR$CloseBR]/;
my $quoted_pair = qq<${esc}[^$NonASCII]>;
my $atom_char   = qq/[^($space)<>\@,;:\".$esc$OpenBR$CloseBR$ctrl$NonASCII]/;
my $atom        = qq<$atom_char+(?!$atom_char)>;
my $quoted_str  = qq<\"$qtext*(?:$quoted_pair$qtext*)*\">;
my $word        = qq<(?:$atom|$quoted_str)>;
my $domain_ref  = $atom;
my $domain_lit  = qq<$OpenBR(?:$dtext|$quoted_pair)*$CloseBR>;
my $sub_domain  = qq<(?:$domain_ref|$domain_lit)>;
my $domain      = qq<$sub_domain(?:$Period$sub_domain)*>;
my $local_part  = qq<$word(?:$Period$word)*>;
my $addr_spec   = qq<$local_part\@$domain>;
my $mail_regex  = $addr_spec;

	return 1 if($email =~ /^$mail_regex$/o);
	return 0;
}

#===============================================
# 暗号化関係
#===============================================
my $salt = ".b";

sub crypt
{
	my ($str) = @_;
	my $ostr = crypt($str,$salt);
	$ostr =~ s/[&+?=]/@/g;
	return $ostr;
}

sub IsAllowedIPAddress
{
	my ($IPAddress, @allowed) = @_;
	
	foreach my $exp (@allowed) {
		return 1 if($IPAddress =~ /$exp/i);
	}
	return 0;
}

#==========================================
# require "mycgi.pl";
# print &mycgi'InitHTML('Welcome to our HP');
#==========================================

sub PrintHTMLHeader
{
	my($CharSet) = (@_);
	if($CharSet eq '') {
		$CharSet = 'x-sjis';
	}
	print "Content-type: text/html; charset=$CharSet\n\n";
}

sub InitHTML
{
	my($WebTitle, $CharSet, $LinkTarget) = (@_);
	
	if($WebTitle eq ''){
		$WebTitle = "No title";
	}
	if($CharSet eq '') {
		$CharSet = 'x-sjis';
	}
	if($LinkTarget eq '') {
		$LinkTarget = '_blank';
	}

	&PrintHTMLHeader($CharSet);

	print "<!DOCTYPE PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n";
	print "<html>\n";
	print "<head>\n";
	print "	<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$CharSet\">\n";
	print "	<title>$WebTitle</title>\n";
	print " <base target=\"$LinkTarget\">\n";
	print "</head>\n";

	print "<body>\n";
}

sub EndHTML
{
	print "</body>\n";
	print "</html>\n";
}

sub GetHTMLParagraph
{
	my ($str) = (@_);
	$str =~ /^([\w\W\n]*?)(<p [\w\W]*?<\/p>)([\w\W]*)$/mi;
	my $line = $1;
	my $paragraph = $2;
	my $len = length($line) + length($paragraph);
	my $content = substr($str, $len);

#	print "strlen: " . length($str) . "  " . $len . "  " . length($content) . "\n";
#	print "str1:  ". substr($str, 0, 200) . "\n";
#	print "line1: $line\n";
#	print "para1: $paragraph\n";
#	my $cont1 = substr($content, 0, 200);
#	print "cont1: $cont1\n";

	return ($line, $paragraph, $content);
}

sub DequoteXML
{
	my ($str,$DoDecode) = (@_);
	
	$str =~ s/<[\w\W]*?>//gmi;
	$str =~ s/\n//gm;
	if($DoDecode) {
		$str =~ s/&quot;/\"/gmi;
#		$str =~ s/&lt;/\</gmi;
#		$str =~ s/&gt;/\>/gmi;
		$str =~ s/&nbps;/ /gmi;
	}
	return $_[0] = $str;
}


sub GetIPAddress
{
	my($ip) = (@_);
	$ip = $ENV{'REMOTE_ADDR'};
	return $ip;
}


sub IsJapanese
{
	my($str) = (@_);
	Jcode::convert(\$str, 'euc');
	if($str =~ /[\x8E\xA1-\xFE]/) {
		return 1;
	}
	return 0;
}


#==========================================
# Decode / Encode
#==========================================

sub MySQLQuote
{
	my($str,$mysqlcharcode) = (@_);
	
#print "s: $str<br>\n";
	Jcode::convert(\$str, $mysqlcharcode)
		if($mysqlcharcode ne '');
	$str =~ s/\\/\\\\/g; # \
##	$str =~ s/\c[/\\\c[/g; # ESC
#	$str =~ s/\//\\\//g; # \
	$str =~ s/\"/\\\"/g;
#	$str =~ s/\'/\\\'/g;
#	$str =~ s/\:/\\\:/g;
#	$str =~ s/\(/\\\(/g;
#	$str =~ s/\)/\\\)/g;
##	$str =~ s/\[([^\c[])/\\\[\1/g;
#	$str =~ s/\[/\\\[/g;
##	$str =~ s/\]/\\\]/g;
#print "s: $str<br>\n";
	return $str;
}

sub RegExpQuote
{
	my($str) = (@_);

	$str =~ s/\\/\\\\/g;
	$str =~ s/\//\\\//g;
	$str =~ s/\(/\\\(/g;
	$str =~ s/\)/\\\)/g;
	$str =~ s/\[/\\\[/g;
	$str =~ s/\]/\\\]/g;
	$str =~ s/\^/\\\^/g;
	$str =~ s/\$/\\\$/g;
	$str =~ s/\*/\\\*/g;
	$str =~ s/\?/\\\?/g;
	$str =~ s/\+/\\\+/g;
	$str =~ s/\./\\\./g;
	return $str;
}

sub URLEncode
{
	my ($s) = (@_);
	$s =~ s/([^\w ])/'%' . unpack('H2', $1)/eg;
	$s =~ tr/ /+/;
	return $s;
}

sub URLDecode
{
	my ($s2) = (@_);
#print "s0: $s2<br>\n";
	$s2 =~ tr/+/ /;
	$s2 =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
#print "s1: $s2<br>\n";
	return $s2;
}

#16進コード
sub StrToHex
{
	my ($s) = @_;
	
	$s =~ s/(.)/'\\x' . uc unpack('H2', $1)/eg;
	return $s;
}

sub RecoverHTMLChar
{
	my ($s, $charset) = @_;
	
	$s =~ s/&#([0-9]+);/pack('I', $1)/eg;
	Jcode::convert(\$s, $charset)
		if($charset ne '');
	return $s;
}

sub StringToHex
{
    my ($s) = @_;
    $s = '='.unpack("H2",$s);
    tr/a-f/A-F/;
    return $s;
}

sub QPEncode
{
	my ($string) = (@_);

	$string =~ s/=/=3D/g;
	$string =~ s/\t$/=09/;
	$string =~ s/ $/=20/;
	$string =~ s/([^!-" \t])/&StringToHex($1)/eg;
	return $string;
}

sub QPDecode
{
	my ($string) = (@_);

	$string =~ s/=\r\n//g;
	$string =~ s/=\n//g;
	$string =~ s/=\r//g;
	$string =~ s/=([0-9a-z]{2})/pack("C",hex($1))/gei;
	return $string;
}


my $Base64Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
                  'abcdefghijklmnopqrstuvwxyz'.
                  '0123456789+/'; # and '='
my $Base64Pad = '=';

# b64decodesub -- takes some characters in the base64 alphabet and
# returns the raw bytes that they represent.
sub Base64DecodeSub
{
    local ($_) = @_[0];
             
    # translate each char to a value in the range 0 to 63
    eval qq{ tr!$Base64Alphabet!\0-\77!; };
    # keep 6 bits out of every 8, and pack them together
    $_ = unpack('B*', $_); # look at the bits
    s/(..)(......)/$2/g;   # keep 6 bits of every 8
    s/((........)*)(.*)/$1/; # throw away spare bits (not multiple of 8)
    $_ = pack('B*', $_);   # turn the bits back into bytes
    $_; # return
}

sub Base64Decode2
{
	my ($str) = (@_);

	my $leftover = '';

	# ignore illegal characters
	$str =~ s/[^$Base64Alphabet]//go;
	# insert the leftover stuff from last time
	$str = $leftover . $str;
	# if there are not a multiple of 4 bytes, keep the leftovers for later
	$str =~ m/^((....)*)/; 
	$str = $&; 
	$leftover = $';
	# turn each group of 4 values into 3 bytes
	$str =~ s/(....)/&Base64DecodeSub($1)/eg;
	# special processing at EOF for last few bytes
	if (eof)
	{
		$str .= &Base64DecodeSub($leftover); 
		$leftover = '';
	}
	# output it
	
	return $str;
}

sub Base64Decode
{
	return decode_base64($_[0]);
}

sub Base64Encode
{
	return encode_base64($_[0]);
}

#==========================================
# Directory
#==========================================

my $DirectorySeparator = "\\";

sub ConvertDirectorySeparator
{
	my ($path, $src, $target, $DoTerminate) = (@_);

	$src = &RegExpQuote($src);
#	$target = &RegExpQuote($target);

	$_[0] =~ s/^\s*//;
	$_[0] =~ s/\s*$//;
	if($_[0] eq '') {
		return $_[0];
	}
#print "str   :" . $_[0] . "<br>\n";
#print "src   :$src<br>\n";
#print "target:$target<br>\n";
	$_[0] =~ s/$src/$target/g;
#print "str2  :" . $_[0] . "<br>\n";
	my $RegTarget = &RegExpQuote($target);
	if($DoTerminate) {
		unless($_[0] =~ /$RegTarget$/) {
			$_[0] .= $target;
		}
	}
	else {
		if($_[0] =~ /$RegTarget$/) {
			$_[0] =~ s/$target$//;
		}
	}
#print "str3  :" . $_[0] . "<br>\n";
	return $_[0];
}

sub MakePath
{
	my ($dir, $fname, $separator, $DoTerminate) = (@_);

	my $RegSep = &RegExpQuote($separator);
	my $IsHeadSep = 0;
#	$IsHeadSep = 1 if($dir =~ /^\//);
#print "MakePath:dir  : $dir\n";
#print "MakePath:fname: $fname\n";

	$fname =~ s/^\///;

	if($dir =~ /$RegSep$/) {
		$dir .= $fname;
	}
	else {
		$dir .= $separator . $fname;
	}
	if($DoTerminate) {
		unless($dir =~ /$RegSep$/) {
			$dir .= $separator;
		}
	}
	else {
		if($dir ne '/' and $dir =~ /$RegSep$/) {
			$dir =~ s/$RegSep$//;
		}
	}
#	if($IsHeadSep) {
#		$dir = "/$dir" unless($dir =~ /\//);
#	}
#print "path: $dir\n";
	return $dir;
}

sub ReduceDirectory {
	my ($dir) = (@_);
	
	my $IsHeadSep = 0;
	my $IsLastSep = 0;
	$IsHeadSep = 1 if($dir =~ /^\//);
	$IsLastSep = 1 if($dir =~ /\/$/);

	my @d = split(/\//, $dir);
	my @d2;
	for(my $i = 0 ; $i < @d ; $i++) {
		next if($d[$i] eq '.');
		if($d[$i] eq '..') {
			pop(@d2);
			next;
		}
		push(@d2, $d[$i]);
	}

	if($IsHeadSep) {
		$dir = '/';
	}
	else {
		$dir = '';
	}

	foreach my $dd (@d2) {
		if($dir eq '') {
			$dir = $dd;
			next;
		}
		next if($dd eq '');
		$dir = &MakePath($dir, $dd, "/", 0);
	}
	$dir = &MakePath($dir, "/", "/", 0) if($IsLastSep);

	return $_[0] = $dir;
}

sub CreateDirecotry
{
	my ($dir, $dirsep) = @_;

	my $directorysep = $DirectorySeparator;
	$directorysep = $dirsep;

	$dir =~ s/\\/\//g;

if($Debug) {
	print "CreateDirectory: $dir\n";
}
#	my $IsHeadSep = 0;
#	$IsHeadSep = 1 if($dir =~ /^\//);

	my $IsRelative = 1;
	$IsRelative = 0 if($dir =~ /^[A-Za-z]:\// or $dir =~ /^\//);
#print "IsRelative: $IsRelative\n";
	my @eachpath = split(/\//, $dir);
	
	my $i = 0;
	my $path = "";
	if($eachpath[$i] =~ /^[A-Za-z]:/) {
		$path = $eachpath[$i];
		$i++;
	}
	$path .= $directorysep unless($IsRelative);

	for( ; $i < @eachpath ; $i++) {
		$path .= $eachpath[$i] . $directorysep;
if($Debug) {
	print "path: $path\n";
}
		next if(-d $path);
		if(-f $path) {
			print "Can not create [$path]: $path is a file.\n";
			return;
		}
if($Debug) {
	print "    Create $path [$directorysep]\n";
}
		mkdir($path);
	}
}

sub MakeRelativePath
{
	my ($SourceURL, $ParentURL, $Separator) = (@_);

	$Separator = $DirectorySeparator if($Separator eq '');
	my $HeadLevel = 2;
	$HeadLevel = 3 if($SourceURL =~ m|://|);

if($Debug) {
	print "*SourceURL: $SourceURL\n";
	print "*ParentURL: $ParentURL\n";
	print "*Separator: $Separator\n";
}
	my $RegSeparator = &RegExpQuote($Separator);
	my @EachSourceStr = split(/$RegSeparator/, $SourceURL);
	my @EachParentStr = split(/$RegSeparator/, $ParentURL);
	my $pt = 0;
	for(my $i = 0 ; $i < @EachSourceStr ; $i++) {
if($Debug) {
	print "  es[$i]: ", lc $EachSourceStr[$i], "\n";
	print "  ep[$i]: ", lc $EachParentStr[$i], "\n";
}

		if(lc $EachSourceStr[$i] ne lc $EachParentStr[$i]) {
			$pt = $i;
			last;
		}
		$pt = $i;
	}
if($Debug) {
	print "PT: $pt\n";
}
#絶対パスしかない場合
	return "" if(($EachSourceStr[0] =~ /^\w:/ and $pt < $HeadLevel) or
		     ($EachSourceStr[0] !~ /^\w:/ and $pt < $HeadLevel-1) );

	my $TotalLevel = @EachParentStr - $pt - 1;
if($Debug) {
	print "TotalLevel: $TotalLevel\n";
}

	my $RelPath = '';
	for(my $i = 0 ; $i < $TotalLevel ; $i++) {
		$RelPath = &MakePath($RelPath, "..", $Separator, 0);
	}
	for(my $i = $pt ; $i < @EachSourceStr ; $i++) {
		$RelPath = &MakePath($RelPath, $EachSourceStr[$i], $Separator, 0);
	}
if($Debug) {
	print "*RelPath: $RelPath\n";
}

	return $RelPath;
}

sub CopyFile
{
	my ($infile, $outfile) = (@_);
	
	open(IN, "<$infile") or return -1;
	open(OUT, ">$outfile") or return -2;
	my @content = <IN>;
	print OUT @content;
	close(OUT);
	close(IN);
}

sub DelSpace
{
	my ($s) = @_;
	
	$s =~ s/^\s*//;
	$s =~ s/\s*$//;
	return $_[0] = $s;
}

sub DelQuote
{
	my ($s) = @_;
	
	chomp($s);
	$s =~ s/^\s*//;
	$s =~ /^(.)(.*)(.)$/;
	my $firstchar = $1;
	my $restchar  = $2;
	my $lastchar  = $3;
	if($firstchar eq '"' and $lastchar eq '"') {
		return $restchar
	}
	return $restchar
		if($firstchar eq '\'' and $lastchar eq '\'');
	return $_[0];
}

#==========================================
# require "mycgi.pl";
#
# &mycgi'PrintWithReplaced($infile, $outfile, "{EMail}", $a, "{Code}", $b);
#           ex. $infile = '-', 'a.in', $outfile="> a.out", ">> a.append", ">-"
#==========================================
sub PrintWithReplaced
{
	my $narg = @_;
	my @a = @_;
	my $infile = $a[0];
	my $outfile = $a[1];
	my($org,$target);

#print "narg: $narg : infile: $infile<br>\n";
	open(INFILE, $infile) or die "$infile: $!";
	open(OUTFILE, $outfile) or die "$outfile: $!";
	my($line);
	while(defined($line = <INFILE>)){
		for(my $i = 2 ; $i < $narg ; $i += 2){
if($Debug) {
	print "change($i):<br>\n";
	# [" . $a[$i] . "] to [" . $a[$i+1] . "]<br>\n";
}
			$line =~ s/$a[$i]/$a[$i+1]/g;
		}
		print OUTFILE $line;
	}
	close(INFILE);
	close(OUTFILE);
}

#==========================================
# require "mycgi.pl";
#
# &mycgi'PrintStringWithReplaced($str, $outfile, "{EMail}", $a, "{Code}", $b);
#           ex. $infile = '-', 'a.in', $outfile="> a.out", ">> a.append", ">-"
#==========================================
sub PrintStringWithReplaced
{
	my $narg = @_;
	my @a = @_;
	my $str = $a[0];
	my $outfile = $a[1];
	my($org,$target);

	open(OUTFILE, $outfile) or die "$outfile: $!";
	for(my $i = 2 ; $i < $narg ; $i += 2){
		$str =~ s/$a[$i]/$a[$i+1]/g;
	}
	print OUTFILE $str;
	close(OUTFILE);
}

#==========================================
# &mycgi'ConvertString($str, "{EMail}", $a, "{Code}", $b);
#==========================================
sub ConvertString
{
	my $narg = @_;
	my @a = @_;
	my $str = $a[0];

	for(my $i = 1 ; $i < $narg ; $i += 2){
		$str =~ s/$a[$i]/$a[$i+1]/g;
	}
	return $_[0] = $str;
}

sub IsValidPassword
{
	my ($password) = (@_);
	if($password =~ /^[a-zA-Z0-9_]+$/){
		return 1;
	}
	return 0;
}

sub IsValidEMailAddress
{
	my ($email) = (@_);
	if($email =~ /^[a-zA-Z0-9._\-+\%\$#!&~]+@[a-zA-Z0-9._\-+]+$/){
		return 1;
	}
	return 0;
}

sub BuildDateString
{
	my ($time) = (@_);
	
	my ($sec, $min, $hour, $mday, $mon, $year,
	        $wday, $yday, $isdst) = localtime($time);
	$year += 1900;
	$mon++;
	my $str = sprintf("%02d/%02d/%02d %02d:%02d:%02d", 
			$year, $mon, $mday, $hour, $min, $sec);
	return $str;
}

sub GetFileSize
{
	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
		$atime,$mtime,$ctime,$blksize,$blocks)
			= stat($_[0]);
	return $size;
}

sub GetWriteDate
{
	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
		$atime,$mtime,$ctime,$blksize,$blocks)
			= stat($_[0]);
	return $mtime;
}

#==========================================
# DB subroutines
#==========================================
sub OpenDB
{
	my ($DBServer, $DBUser, $DBPassword, $DBName) = @_;
	my $db;
	my $sth;
	
	$db = DBI->connect('DBI:mysql:'.$DBName.':'.$DBServer, $DBUser, $DBPassword);
	if(!$db){
		print "Unable to connect to $DBName<br>\n";
		return 0;
	}
	$sth = $db->prepare("use $DBName;\n");
	my $result = $sth->execute;
	if(!$result){
		print "use: SQL execution error<br>\n";
		return 0;
	}

#print "db:$db $sth<br>\n";
	return ($db,$sth);
}

sub CloseDB
{
	my ($db, $sth) = @_;

	$sth->finish;
	$db->disconnect;
}

sub DBExecute
{
	my ($db, $sth, $command) = @_;

	$sth = $db->prepare($command);
	my $ret = $sth->execute;
	return ($sth,$ret);
}


#===============================================
# HTML / Cookie関係
#===============================================

my %COOKIE;

my $CGIFiles = "(\.cgi|\.pl|\.php)[^/]*\$";
my @IndexFiles = ("index.html", "index.htm", "Index.html", "Index.htm",
		  "Default.htm", "Default.html", "default.htm", "default.html");


#
# Cookieの値を読み出す
#
sub getCookie {
    my($xx, $name, $value);
    foreach my $xx (split(/; */, $ENV{'HTTP_COOKIE'})) {
        ($name, $value) = split(/=/, $xx);
        $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
        $COOKIE{$name} = $value;
    }
}

#
# Cookieに値を書き込むためのSet-Cookie:ヘッダを生成する
#
sub setCookie {
    my($tmp, $val);
    $val = $_[1];
    $val =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
    $tmp = "Set-Cookie: ";
    $tmp .= "$_[0]=$val; ";
    $tmp .= "expires=Tue, 1-Jan-2030 00:00:00 GMT;";
    return($tmp);
}

#
# Cookieを削除するためのSet-Cookie:ヘッダを生成する
#
sub clearCookie {
    my $tmp = "Set-Cookie: ";
    $tmp .= "$_[0]=xx; ";
    $tmp .= " expires=Tue, 1-Jan-1980 00:00:00 GMT;";
    return($tmp);
}

sub ConvertHTMLToFullURL
{
	my ($Content, $SourceURL, $Debug) = (@_);
	my $res;
	my $ConvContent;
	
	$res = $Content;
	$ConvContent = "";
	while(1) {
		my $count = 
		($res =~ /^(.*?)(\<a\s+href=\")(.*?)(\".*?\>)(.*?)(\<\/a.*?\>)(.*)$/si);
		if($count == 0) {
			$ConvContent .= $res;
			last;
		}
		my $header  = $1;
		my $tag1    = $2;
		my $linkurl = $3;
		my $tag2    = $4;
		my $linkstr = $5;
		my $tag3    = $6;
		$res     = $7;
if($Debug) {
	print "    URL: $linkurl\n";
}
		my $convurl = &ConvertURLtoFullURL($linkurl, $SourceURL);
if($Debug) {
	print "ConvURL: $convurl\n";
}
		$ConvContent .= "$1$2$convurl$4$5$6";
	}

	$res = $ConvContent;
	$ConvContent = "";
	while(1) {
		my $count = 
			($res =~ /^(.*?(background|image|src)\s*=\s*\")(.*?)(\".*)$/si);
			if($count == 0) {
			$ConvContent .= $res;
			last;
		}
		my $header  = $1;
		my $linkurl = $3;
		$res        = $4;
if($Debug) {
	print "    URL: $linkurl\n";
}
		my $convurl = &ConvertURLtoFullURL($linkurl, $SourceURL);
if($Debug) {
	print "ConvURL: $convurl\n";
}
		$ConvContent .= "$1$convurl";
	}

	return $_[0] = $ConvContent;;
}

sub ConvertURLtoFullURL
{
	my ($linkurl, $url) = (@_);
	my $convurl;

	return $linkurl if($linkurl =~ /:\/\//i);

	my $protocol;
	my $server;
	my $directory;
	my $filename;
#	$url =~ /^(.*?:\/\/)([^\/]+?)([^\?\&]*?)([^\/]*?)$/i;
	$url =~ /^(.*?:\/\/)([^\/]+?)(\/|$)(.*?)([^\/]*?)$/i;
	$protocol  = $1;
	$server    = $2;
	$directory = "/$4";
	$filename  = $5;
	if($directory =~ /[\?\&]/) {
		$directory =~ /^(.*?)([\?\&].*$)/;
		$directory = $1;
		my $res1   = $2;
		$directory =~ /^(.*)\/([^\/]*?)$/;
		$directory = $1;
		my $res2   = $2;
		$filename = "$res2$res1$filename";
	}

#print "URL   : $url\n";
#print "pro   : $protocol\n";
#print "server: $server\n";
#print "dir   : $directory\n";
#print "file  : $filename\n";

	my $path;
	if($linkurl =~ /^\//) {
		$path = &MakePath($server, $linkurl, "/", 0);
	}
	else {
		$path = &MakePath($server, $directory, "/", 0);
		$path = &MakePath($path, $linkurl, "/", 0);
		&ReduceDirectory($path);
	}
#print "path: $path\n";
	$convurl = "$protocol$path";
	return $convurl;
}

sub GetURLwithoutFilePath {
	my ($url) = @_;

	my $ret;

#CGIの場合はそのままreturn
	return 1 if($url =~ /$CGIFiles/i or $url =~ /[\?\&]/);

	for(my $i = 0 ; $i < @IndexFiles ; $i++) {
		my $s = &MakePath($url, $IndexFiles[$i], "/", 0);
#print "url: $s\n";
		$ret = head($s);
#		$ret = get($s);
		if($ret) {
			$_[0] = $s;
			return $ret;
		}
	}
	return $ret;
}

sub DownloadFromURL
{
	my ($url) = @_;

	my $Content;
	my $agent     = LWP::UserAgent->new;
	my $newagent = 'Mozilla/4.7 [en]  (PalmOS)';
	$agent->agent($newagent);
	my $jar = $agent->cookie_jar(new HTTP::Cookies);

	my $request = HTTP::Request->new(GET => $url);
	my $response = $agent->request($request);
	unless($response->is_success) {
		my $s = $response->message;
		print "Error: $s!<br>\n";
		return -1;
	}

	$Content = $response->content;
	&ConvertHTMLToFullURL($Content, $url, 0);

	return $Content;
}

sub ExtractHTMLBody
{
	my ($Content) = @_;
	
	$Content =~ /\<body.*?\>(.*)\<\/body\>/si;
	return $1;
}

#==========================================
# 「Ultimate Perl」、ソシム発行
#==========================================

sub ReadFile
{
	my $fname = @_;
	
	open(FILE, "<$fname") or return -1;
	my $str = do { local $/; <FILE>; };
	close(FILE);
	
	return $str;
}

#12文字ごとにファイルを読み込み、" "で区切って返す
sub ReadFixedColumnFile
{
	my $fname = @_;
	
	open(FILE, "<$fname") or return -1;
	local $/ = \12;
	local $\ = "\n";
	my $str = "";
	while(<FILE>) {
		$str .= " $_";
	}
	close(FILE);
	return $str;
}

#リストをタブ区切りで出力
sub PrintWithTab1
{
	my @list = @_;
	local ($") = "\t";
	print "@list\n";
}
sub PrintWithTab1
{
	my @list = @_;
	local ($,) = "\t";
	print @list . "\n";
}

#文字列を固定長で区切る
sub SplitToFixedStrs
{
	my $s = @_;
	my @list;
	$s =~ s/(.{1,8})/push(@list,$1)/eg;
	return @list;
}

#括弧で囲まれた部分をきちんと抽出
sub ExtractByParentheses
{
	my $str = @_;
	my $balance;
	$balance = qr/\([^()]*(?:(??{$balance})[^()]*)*\)/;
	
	my $ret = "";
	while($str =~ /($balance)/g) {
		$ret .= "$1\n";
	}
	return $ret;
}

#クレジットカードの番号をチェック
sub CheckCreditCardNumber
{
	$_ = shift @_;
	s/[ -]//g && split //;
	return "Wrong number" 
		if(/\D/ || (length) |~ /^1[356]$/);
	
	my $x;
	map {
		$x = 0;
		map { $x += $_ } split //, $_[$_]*2;
		$_[$_] = $x;
	} map {
		$_%2 ?() : $_;
	} (length)%2..(length)-1;
	$x = 0;
	map { $x += $_ } @_;
	return $x % 10 ?
		"Wrong nubmer" :
		"Correct number";
}

#タグの外側だけを置換
sub ReplaceHTMLBodyOnly
{
	my ($str, $source, $target) = @_;
	$str =~ s/((?:\G|>)[^<]*?)$source/$1$target/g;
	return $str;
}

#OSの判定
sub GetOSName
{
	reuturn $^O;
}

#Configの表示
sub PrintConfig
{
	use Config;
	for my $key (keys(%Config)) {
		print "$key : $Config{$key}\n";
	}
}

#コマンドをサブルーチンでつかう
#sub AUTOLOAD
#{
#	my $program = $AUTOLOAD;
##パッケージ名をはずす
#	$program =~ s/.*:://;
#	qx/$program @_/;
#}

#関数のオーバーライド
#use subs qw(lc uc);　など

#データ中のHTMLタグを無力化
sub InvalidateHTMLTags
{
	my ($input) = @_;
	$input =~ s/&/&amp;/g;
	$input =~ s/</&lt;/g;
	$input =~ s/>/&gt;/g;
	$input =~ s/"/&quot;/g;
	$input =~ s/'/&#39;/g;
	return $input;
}

#URLから危険な要素を排除
sub GetSafeURL
{
	my $url = @_;
	return '' if($url =~ m|[^;/?:@&=+\$,A-Za-z0-9\-_.!~*'()%]|);
	if($url =~ /^([A-Za-z][A-Za-z0-9+\-.]*):/) {
		my $scheme = lc($1);
		my $allowed = 0;
		$allowed = 1 if($scheme eq 'http');
		$allowed = 1 if($scheme eq 'https');
		$allowed = 1 if($scheme eq 'mailto');
		return '' if(not $allowed);
	}
	$url =~ s/&/&amp;/g;
	$url =~ s/'/&#39;/g;
	return $url;
}

#ファイル名のチェック（ヌル文字がある場合、ディレクトリィトラバーサルがある場合は０
sub CheckSecureFileName
{
	my $fname = @_;

	return 0 if($fname =~ <\.\./>);
	return 0 if($fname =~ /\0/);

	return 1;
}

#タイムアウトの設定
#alarm(20); #20秒
#SIG{ALRM} = 'time_out';
#sub time_out {
#	print "Time out\n";
#	return;
#}

1;