package tdllib; # ###################################################################### ### ### ### CGI辞書システム T-Dictionary Ver.0.92 ### [6/8] 汎用ライブラリ (tdlib.pl) ### (c) 1996-2002 Takahiro Nishida ### http://www.mytools.net/ ### ### ###################################################################### # ### 変数設定部 (詳細は上記ページをご覧下さい) ###################### # データディレクトリ(basedir) のパス $basedir = "."; # 戻り先URL $backurl = "http://your.homepage/"; # 管理者メールアドレス $admin_email = "your\@email.address"; # 漢字コード $code = "sjis"; # HTMLディレクトリ $htmldir = "./html"; # CGI URL $cgiurl = "http://your.homepage/cgi-bin/dictionary"; # HTML URL $htmlurl = "http://your.homepage/cgi-bin/dictionary/html"; # 時間補正(単位:時間) $time_fix = 0; # 新着扱いする日数 $new_date = 60; # ファイル1つあたりの最大サイズ(KByte) $MAX_FILE_SIZE = 300; # 全ファイルの最大サイズ(KByte) $MAX_FILE_TOTAL_SIZE = 10240; # ユーザによるファイル登録の可否(0->不可、1->可) $ENABLE_FILE = 1; # ユーザによる画像登録の可否(0->不可、1->可) $ENABLE_IMAGE = 1; # 単語の下に表示するコメントの最大件数 $MAX_COMMENTS = 5; # 全コメント表示時の最大件数 $MAX_ALL_COMMENTS = 100; # クッキーの有効期限(日) $COOKIE_EXPIRE_TIME = 30; # クッキーの名前(1サーバに複数入れる場合は換える) $cookie_name = "tdictionary"; ### 変数設定部 (ここまで)########################################### # MKDIR時のパーミッション指定 $MKDIR_PARMISSION = 0705; # エラーコード番号を表示するか(1->する、0->しない) $SHOW_ERROR_CODE = 1; # エラーの詳細を表示するか(1->する、0->しない) $SHOW_ERROR_DETAIL = 0; # crypt用のsalt $CRYPT_SALT = "My"; require './jcode.pl'; require './cgi-lib.pl'; $verno = "0.92b.03"; $lockfile = "$basedir/lockdir/tb.lock"; $tmpdir = "$basedir/lockdir"; $filedir = "$htmldir/files"; $fileurl = "$htmlurl/files"; $imgdir = "$htmldir/images"; $imgurl = "$htmlurl/images"; $cgi_lib'maxdata = $MAX_FILE_SIZE * 1024; $cgi_lib'writefiles = $tmpdir; $cgi_lib'filepre = "tdf"; $datdic = "$basedir/tdddic.txt"; $datgnr = "$basedir/tddgnr.txt"; $datcom = "$basedir/tddcom.txt"; $datlog = "$basedir/tddlog.txt"; $datreg = "$basedir/tddreg.txt"; $datusr = "$basedir/tddusr.txt"; $tpladm = "$basedir/tdtadm.htm"; $tplusr = "$basedir/tdtusr.htm"; $tplcom = "$basedir/tdtcom.htm"; ################################### 基礎関数 ################################### ########## 入力の受け取り sub parseform{ &ReadParse(\%F, \%F_CFN, \%F_CT, \%F_SFN); } ########## 入力の受け取り(file対応) sub parseformfile{ local($formname, $dirbase, $dirname, $filename) = @_; local($b_dname, $fcname, $fsname, $fpname, $ffname, $fsize); ### ベースディレクトリがなければ即エラー (-d $dirbase) || &error("LL-0011", 1, "ベースディレクトリが存在しません:$dirbase"); $fcname = $F_CFN{$formname}; $fsname = $F_SFN{$formname}; ### ディレクトリがなければディレクトリ作成 $b_dname = $dirbase . "/"; @dirs = split(/[\\\/]/, $dirname); foreach(@dirs){ $b_dname .= $_; (-d $b_dname) || (mkdir($b_dname, $MKDIR_PARMISSION)) || &error("LL-0012", 1, "ディレクトリが作成できません", "ディレクトリ名:$dirname"); $b_dname .= "/"; } ### 登録時のファイル名(パスなし) @bufs = split(/[\\\/]/, $fcname); $ffname = $bufs[$#bufs]; ### ファイル名が指定されていなかったらそれをファイル名に ($filename) || ($filename = $ffname); # 格納フルパスファイル名 $fpname = "$b_dname$filename"; ### リネーム rename($fsname, $fpname) || &error("LL-0013", 1, "ファイル名を変更できません", "$fsname → $fpname"); ### ファイルサイズ(小数点2桁) $fsize = -s $fpname; $fsize = sprintf("%03d", int($fsize * 100 / 1024)); substr($fsize, -2, 0) = "."; # &tdllib'error("EX-0000", 0, "FSNAME:$fsname, FPNAME:$fpname, FFNAME:$ffname, FSIZE:$fsize"); ### 登録時のファイル名を戻す ($ffname, $fsize); } ########## 入力ファイルの拡張子取得 sub get_formfile_ext{ local($formname) = @_; ($ext) = $F_CFN{$formname} =~ m|\.(\w+)$|; $ext; } ########## 画像の存在チェック sub img_check{ local($wid) = @_; (-f "$imgdir/$wid.gif") && (return "gif"); (-f "$imgdir/$wid.jpg") && (return "jpg"); (-f "$imgdir/$wid.png") && (return "png"); (-f "$imgdir/$wid.GIF") && (return "GIF"); (-f "$imgdir/$wid.JPG") && (return "JPG"); (-f "$imgdir/$wid.PNG") && (return "PNG"); return 0; } ########## 日本語のデコード sub decode{ local($w, $frag) = @_; # $w =~ tr/+/ /; # $w =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $w =~ s/\t//g; unless($frag){ $w =~ s/</g; $w =~ s/>/>/g; $w =~ s/"/"/g; $w =~ s/'/'/g; } # $w =~ s/\(/(/g; # $w =~ s/\)/)/g; # $w =~ s/\*/*/g; # $w =~ s/\?/?/g; # $w =~ s/\[/[/g; # $w =~ s/\\/\/g; # $w =~ s/\]/]/g; # $w =~ s/\{/{/g; # $w =~ s/\|/|/g; # $w =~ s/\}/}/g; $w =~ s/\cM//g; $w =~ s/\n{2,}/
/g;
$w =~ s/\n/
/g;
&jcode'convert(*w, $code);
$w;
}
########## タグを殺す
sub killtag{
local($w) = @_;
$w =~ s/</g;
$w =~ s/>/>/g;
$w =~ s/"/"/g;
$w =~ s/'/'/g;
$w;
}
########## タグを改行に変更
sub tag_to_return{
local($w) = @_;
$w =~ s/
/\r\n/g;
$w =~ s/
/\r\n\r\n/g;
$w;
}
########## 現在の時刻を得る
sub get_time{
local($tsec, $format) = @_;
($tsec) || ($tsec = time() + 60 * 60 * $time_fix);
local($sec, $min, $hour, $mday, $mon, $year) = localtime($tsec);
$mon++;
$year += 1900;
($format) || return sprintf("%04d/%02d/%02d", $year, $mon, $mday);
($format == 1) && return sprintf("%04d%02d%02d%02d%02d%02d", $year, $mon, $mday, $hour, $min, $sec);
($format == 2) && return sprintf("%04d/%02d/%02d %02d:%02d", $year, $mon, $mday, $hour, $min);
($format == 3) && return sprintf("%02d/%02d %02d:%02d", $mon, $mday, $hour, $min);
($format == 4) && return $tsec;
($format == 5) && return sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
}
########## ファイルを開いて、中身を配列に代入する
sub openfile{
local ($filename, *bufs, $frag) = @_;
(-f $filename) || ($frag) || &error("LL-0002", 1, "ファイルが存在しません。", "ファイル名:$filename");
open(FILE, "$filename") || ($frag) || &error("LL-0003", 1, "ファイルを読み込みモードで開くことができません。", "ファイル名:$filename");
@bufs = $errorbuf");
}
### ディレクトリ削除と作成(失敗しても無視)
elsif($G_MFT[$_] eq "MD"){
rmdir($G_NFN[$_]);
}
elsif($G_MFT[$_] eq "DD"){
mkdir($G_NFN[$_], $MKDIR_PARMISSION);
}
}
}
########## システムで一意なIDの生成
sub make_new_id {
local($idate, $ips, $isn);
$idate = sprintf("%010d", &get_time(0, 4)); # 秒時間10桁
$ips = sprintf("%02d", $$ % 100); # プロセス番号の下二桁
$isn = sprintf("%02d", ++$sequence_no); # 実行中で一意な値
return $idate.$ips.$isn;
}
########## コピーライト
sub copyright{
"
" : "";
print "Content-type: text/html\n\n";
print "
$detail
$actmsg
";
}
# &tdllib'error("LL-9999", 1, "Debug:$rename_success_no", $errorbuf);
### rename作業
for(0..$#G_OFN){
if($G_MFT[$_] eq "F"){
(-f $G_OFN[$_]) || &error("LL-0023", 1, "致命的エラー", "rename元ファイルが見つからない ($ofn -> $nfn)");
(-f $G_NFN[$_]) && &error("LL-0024", 1, "致命的エラー", "rename先に別のファイルが存在する ($ofn -> $nfn)");
rename($G_OFN[$_], $G_NFN[$_]) || &error("LL-0034", 1, "致命的エラー", "rename失敗($G_OFN[$_] -> $G_NFN[$_])");
}
### ディレクトリ作成と削除(失敗しても無視)
elsif($G_MFT[$_] eq "MD"){
mkdir($G_NFN[$_], $MKDIR_PARMISSION);
}
elsif($G_MFT[$_] eq "DD"){
rmdir($G_NFN[$_]);
}
$rename_success_no = $_;
}
}
###### ロールバックの実行
sub rollback_filelist{
### リストが空なら実行しない
(@G_NFN) || return;
### リネームが一件も成功していなかったら実行しない
($rename_success_no > -1) || return;
### エラー表示用にリスト作成
$errorbuf = "Rename successed until No.$rename_success_no.
";
foreach(0..$#G_OFN){
$errorbuf .= "(No.$_) OLD:$G_OFN[$_] -> NEW:$G_NFN[$_]
";
}
### rename戻し作業(後ろから)
for($i = $rename_success_no; $i > -1; $i--){
if($G_MFT[$_] eq "F"){
rename($G_NFN[$i], $G_OFN[$i]) || &error("LL-0041", 1, "致命的エラー", "rename戻し失敗 (Rename-Back Failed at No.$_)。ファイルの整合性がとれない状態になっている恐れがあります。
";
}
########## ロック
sub lock{
$try = 3;
while(!(mkdir($lockfile, $MKDIR_PARMISSION))){
(--$try > 0) || &error("LL-0001", 0, "ロック中です。数秒待ってから再度実行してください。");
sleep(1);
}
}
########## ロック解除
sub unlock{
rmdir($lockfile);
}
########## 汎用エラーメッセージ
sub error{
local($code, $actflg, $msg, $detail) = @_;
### rename戻し(41を許すと永久ループの恐れ)
($code eq "LL-0041") || &rollback_filelist();
### 一時ファイルの消去(10と11を許すと永久ループの恐れ)
($code eq "LL-0010" || $code eq "LL-0011") || &cleanup_tmpfile();
$fmsg[0] = "ブラウザのBackを押して戻ってください。";
$fmsg[1] = "管理者に連絡してください。";
### 戻るor連絡
$actmsg = $fmsg[$actflg];
### コード非表示の場合は隠す
$code = ($SHOW_ERROR_CODE) ? "$code: " : "";
### 詳細非表示の場合は隠す
$detail = ($detail && $SHOW_ERROR_DETAIL) ? "$detail
Powered by T-Dictionary Ver.$verno
エラー発生
$code
$msg
管理者:$admin_email
※ ご一報の際にはサイトのURLと症状をお書き添え下さいますようお願いします。
";
print &tdllib'copyright;
print "";
local(@sts) = lstat($lockfile);
local($tn) = time();
($code eq "LL-0001") || &unlock; # ロック中以外はロック解除
($tn - $sts[9] < 15) || &unlock; # 約15秒以上ロックが続いてたら自動解除
exit;
}
1;