# 共通ライブラリ(処理系) # sub OpenFLock { # ファイルをロックします local(*LOCKFILE, $fOverWrite) = @_; # 引数(ファイルハンドル, 上書きモード時、真を指定) if ($USEFLOCK) { # 指定時 &SetFLock(LOCKFILE, 2, $fOverWrite); # ファイルをロックします } return ""; # 常に偽('') } sub CloseFLock { # ファイルをクローズして、ロック(してれば)解除します local(*LOCKFILE) = @_; # 引数(ファイルハンドル) close(LOCKFILE); return ""; # 常に偽('') } sub EmpFileChk { # ファイルが空の時のエラー処理 my($refData, $FilePath) = @_; # 引数(リファレンス、又は空の値, その空ファイルのパス) if (ref($refData) ne 'SCALAR' || $$refData eq "") { # スカラーリファレンスじゃない時(通常、故意エラー発生指定時)||リファレンスの内容が空の時 my($StrCallRoot) = ""; { my(@StrCallRoot) = (); my($i) = 0; while (my(@CallerInf) = caller($i++)) { push(@StrCallRoot, ${[&ExFind($CallerInf[1])]}[1] . "[$CallerInf[2]]"); } if (scalar(@StrCallRoot)) { $StrCallRoot = join('->', reverse(@StrCallRoot)); $StrCallRoot = "; CALLROOT: $StrCallRoot"; } # 追加CALLROOTがある時 } my $NowTime = (time + $DIFTIME); my $DelCountDownSec; if ($FilePath ne "") { $DelCountDownSec = ""; my $WaitSec = 86400; local(*FILE); if (defined(&MakeNewFile($EMPFILELISTFN, "", (my $fOpen = open(FILE, "<$EMPFILELISTFN")), $fFLock))) { if (!$fOpen) { $fOpen = open(FILE, "<$EMPFILELISTFN"); } if ($fOpen) { &OpenFLock(FILE); my $fFind; my @FileList = grep { chomp($_); if ($_ ne "") { my @SepData = split(/\t/, $_); if ($SepData[0] eq $FilePath) { $DelCountDownSec = $SepData[1]; $fFind = 1; } if ($SepData[1] <= $NowTime - $WaitSec && !(-s $SepData[0])) { unlink($SepData[0]); if ($SepData[0] eq $FilePath) { $DelCountDownSec = undef(); } ""; } else { 1; } } else { ""; } } ; if (!$fFind) { push(@FileList, "$FilePath\t$NowTime"); $DelCountDownSec = $NowTime; } if ($DelCountDownSec ne "") { $DelCountDownSec += $WaitSec; } &CloseFLock(FILE); if (scalar(@FileList)) { if (open(FILE, ">$EMPFILELISTFN")) { &OpenFLock(FILE, 1); print FILE join("\n", @FileList); &CloseFLock(FILE); } } else { unlink($EMPFILELISTFN); } } } } $ERR_CODE = "SAMETIME($NowTime)$StrCallRoot"; if ($FilePath ne "") { $ERR_CODE .= "; EMPFILE: \"$FilePath\""; } # エラーコードを格納する &ViewFormErr("$BBSTITLENAME " . '<エラー:同時にアクセスした可能性があります>' . "", "", ( 'エラー
' . '同時にアクセスした可能性があります。
' . 'しばらくしてからアクセスして下さい。
' . ((defined($DelCountDownSec)) ? '
<管理人の方へ>
' . 'もし、この状態が長期間続く場合、"' . (&ExFind($FilePath))[2] . '"ファイルの中身が、
○空の場合:このファイルと"' . (&ExFind($EMPFILELISTFN))[2] . '"ファイルを削除して下さい。
○それ以外:このファイルのパーミッションは正しいですか?
読み書き可能なパーミッションである必要があります。
' . (($DelCountDownSec ne "") ? '尚、' . &GetTimeF($DelCountDownSec, "") . 'までに対処しなかった場合は、自動的にこのファイルを削除して復旧させます。
' : "") : "") ) , $BBSPageNum); # エラーメッセージフォーム表示 } return; } # アクセスログファイルの分割 sub DivideLogFile { # 引数(ログファイル名, 分割サイズ) my(@GetRet) = &FileReNameFS($_[0], (time + $DIFTIME), $_[1]); my(@FileNameInf) = &ExFind((($GetRet[1] ne "") ? $GetRet[0] : $_[0])); if ($FileNameInf[0] ne '.') { local(*FILE); if (open(FILE, ">>$FILE_LOG_LIST")) { &OpenFLock(FILE); print FILE "$FileNameInf[1]\n"; &CloseFLock(FILE); return 1; } else { return; } } return ""; } # 書込み者のアクセスログの保存 sub AccessLog { # 引数(モード,始めに挿入したい文字列)、戻り値(無し) # 設定モード→'1'は全て取得、'2'は主要なのだけ取得、'0'は取得しない my($GetENVMode, $InsertStr) = @_; if (!$GetENVMode) { # モードが指定されて無い時 return ""; # 偽('')で戻る } # 指定ファイルサイズを超えた時、リネームする &DivideLogFile($FILE_LOG_ACS, $LOGLIMITFILESIZE[0]); # 時間情報文字列生成 my($time) = &GetTimeF((time + $DIFTIME), $STRTIMEF_LOG); local(*ALF); # ログ保存 if ($GetENVMode eq 'StrOnly') { # 挿入文字列オンリーモードの時 if (open(ALF, ">>$FILE_LOG_ACS")) { &OpenFLock(ALF); print ALF "$time\t$InsertStr\n"; &CloseFLock(ALF); } } else { my(@HostInf); # ホスト情報 if ($USEGETHOSTINF) { @HostInf = &GetHostInf($ENV{'REMOTE_ADDR'}, 2); } # ホスト情報取得許可時、取得 if ($GetENVMode == 1) { # 全取得モードの時 my($HostInfF) = ""; # ホスト情報書式 { my $fFind = ""; foreach (@HostInf) { if ($_ ne "") { $fFind = 1; last; } } # ホスト情報が1つでも格納されていたら if ($fFind) { $HostInfF = "REMOTE_HOSTINF:\t$HostInf[0],$HostInf[1],$HostInf[2],$HostInf[3] : " . join(' : ', @HostInf[4 .. $#HostInf]) . "\n"; } # 書式化(REMOTE_HOSTINF: name,aliases,addrtype,length,xxx.xxx.xxx.xxx:xxx.xxx.xxx.xxx:…\n) } if (open(ALF, ">>$FILE_LOG_ACS")) { &OpenFLock(ALF); print ALF $CONSTANT{'String'}{'Separator'}{'Log'} . "\n"; print ALF "$time\t$InsertStr\n"; # 現在の時間挿入\t挿入文字列挿入 foreach (sort keys %ENV) { print ALF "$_:\t$ENV{$_}\n"; } # 全ての環境変数挿入 print ALF "- ADDITION -\n"; # おまけの区切り挿入 print ALF $HostInfF; # ホスト情報(おまけ) print ALF "filename:\t\"$DataOut{'UpFileDataFN'}\"\n"; # アップファイル名(おまけ)挿入 print ALF "Content-Type:\t$DataOut{'UpFileDataFT'}\n"; # アップファイルタイプ(おまけ)挿入 print ALF "fmes:\t$DataOut{'fmes'}\n"; # fmes(おまけ1)挿入 print ALF "fmode:\t$DataOut{'fmode'}\n"; # fmode(おまけ2)挿入 print ALF "JsInf:\t$DataOut{'JsInf'}\n"; # JsInf(おまけ3)挿入 print ALF $CONSTANT{'String'}{'Separator'}{'Log'} . "\n"; &CloseFLock(ALF); } } elsif ($GetENVMode == 2) { # 簡易モードの時 my(@HostInfF) = ("", ""); # ホスト情報書式 if ($HostInf[0] ne "") { $HostInfF[0] = $HostInf[0]; } # ホスト名存在時 else { $HostInfF[0] = $ENV{'REMOTE_HOST'}; } if ($HostInf[4] ne "") { $HostInfF[1] = join(' : ', @HostInf[4 .. $#HostInf]); } # IPアドレス存在時 else { $HostInfF[1] = $ENV{'REMOTE_ADDR'}; } if (open(ALF, ">>$FILE_LOG_ACS")) { &OpenFLock(ALF); print ALF "$time\t$InsertStr\t$HostInfF[0] : $HostInfF[1]\t$ENV{'HTTP_X_FORWARDED_FOR'}\t$ENV{'HTTP_USER_AGENT'}\t$DataOut{'UpFileDataFN'}\t$DataOut{'fmes'}\t$DataOut{'fmode'}\t$DataOut{'JsInf'}\n"; &CloseFLock(ALF); } } } return ""; # それ以外(通常ない)偽('')で戻る } # 削除&編集データなどをログに保存する sub SaveDelLog { # 引数(削除データ,挿入したい文字列)、戻り値(未定義値) my($DelData, $InsertStr) = @_; # 引数の取得 if ($F_GETLOG_DELEDT == 0) { # 削除&編集のログを取得モードじゃない時 return; # なにもせずに戻る } # 指定ファイルサイズを超えた時、リネームする &DivideLogFile($FILE_LOG_DEL, $LOGLIMITFILESIZE[1]); # 行末の改行の取り除き(あれば) chomp($DelData); # ログ保存 local(*DELLOG); if (open(DELLOG, ">>$FILE_LOG_DEL")) { # 削除されるデータをファイルに保存 &OpenFLock(DELLOG); print DELLOG &GetTimeF((time + $DIFTIME), $STRTIMEF_LOG); print DELLOG "\t"; print DELLOG $InsertStr; print DELLOG "\t"; print DELLOG $DelData; print DELLOG "\n"; &CloseFLock(DELLOG); } return; } # 送信データ全体をログに保存する(追加保存)(通常エラー時使用) sub SaveErrLog { # 引数(無し)戻り値(成功時:真(1)、失敗時:偽(''))(グローバル%DataOut使用) # 指定ファイルサイズを超えた時、リネームする &DivideLogFile($FILE_LOG_ERR, $LOGLIMITFILESIZE[2]); # ログ保存 local(*SAVEDATA); if (open(SAVEDATA, ">>$FILE_LOG_ERR")) { &OpenFLock(SAVEDATA); print SAVEDATA $CONSTANT{'String'}{'Separator'}{'Log'} . "\n"; # 区切り線 my($Time) = (time + $DIFTIME); # 時間を取得 my($TimeF) = &GetTimeF($Time, $STRTIMEF_LOG); # 書式化された時間を取得 print SAVEDATA "TIME:\t$TimeF($Time)\n"; # 現在の時間の挿入 foreach (sort keys %DataOut) { # デコードされた送信データを全て保存 if ($_ =~ /^UpFileData(_\d+)?$/) { # キーが'UpFileData(_X)?'(ファイル)の時 my $MltLabel = $1; if ($DataOut{"UpFileData${MltLabel}FN"} ne "") { # ファイル入力欄が無記入じゃ無い時 my $UpFileName; { my $FileEx = scalar(&ExFind($DataOut{"UpFileData${MltLabel}FN"})); if ($FileEx ne "") { $FileEx = ".$FileEx" } $UpFileName = "$ERR_LOGFBFN$Time$MltLabel$FileEx$ExData"; } if (ref($DataOut{"UpFileData$MltLabel"}) eq 'SCALAR') { if (rename(${$DataOut{"UpFileData$MltLabel"}}, $UpFileName)) { ${$DataOut{"UpFileData$MltLabel"}} = $UpFileName; } } else { # アップされたデータをファイルに書き込む(あれば) local(*FILE); if (open(FILE, ">$UpFileName")) { &OpenFLock(FILE, 1); # 上書きモード binmode(FILE); print FILE $DataOut{"UpFileData$MltLabel"}; # ファイルを保存する &CloseFLock(FILE); } } } } else { # それ以外(テキスト系の時) print SAVEDATA "$_:\t$DataOut{$_}\n"; # ログを保存 } } &CloseFLock(SAVEDATA); } return 1; # 真(1)を戻します } sub GetDatImgReSize { # データ解析版画像縮小サイズ取得(引数の''と'0'は等価として扱われる) my(@ImgSize) = @_; # 引数(横サイズ[0], 縦サイズ[1], 制限横サイズ[2], 制限縦サイズ[3]) if ($ImgSize[0] && $ImgSize[1] && $ImgSize[2] && $ImgSize[3]) { # 全て指定時 if ($ImgSize[0] > $ImgSize[2] || $ImgSize[1] > $ImgSize[3]) { # リサイズすべき時 my(@Rate) = ($ImgSize[0] / $ImgSize[2], $ImgSize[1] / $ImgSize[3]); # 縮小率を格納 my(@ImgReSize); if ($Rate[0] > $Rate[1]) { @ImgReSize = ($ImgSize[2], int($ImgSize[1] / $Rate[0])); } elsif ($Rate[0] < $Rate[1]) { @ImgReSize = (int($ImgSize[0] / $Rate[1]), $ImgSize[3]); } else { @ImgReSize = ($ImgSize[2], $ImgSize[3]); } return ($ImgReSize[0], $ImgReSize[1]); } } if ($ImgSize[0] && $ImgSize[1]) { # リサイズ未処理時&&サイズが指定時 return ($ImgSize[0], $ImgSize[1]); } return ("", ""); } sub ReplaceLabel { # ラベルを置き換える my($refStrMdl, $refStrEx) = @_; # 引数(対象文字列, 変換文字列(ラベル, 文字列リファ)ハッシュリファレンスリスト) # ラベル変換クロージャ生成 my($refStrExLabel) = sub { my($StrA, $StrL, $Label, $Mode, $StrR, $StrN, $refStr) = @_; # 引数(全パターン, 文字列左, ラベル, モード, 文字列右, 未存在時文字列, 変換文字列(ラベル, 文字列リファ)ハッシュリファレンスリスト) foreach (keys %$refStr) { if ($Label eq $_) { # ラベル一致時 if (${$$refStr{$_}} ne "") { # データ存在時 if ($Mode eq '_IJS') { # '_IJS'モード return $StrL . &DataDec::DecInJsStr($$refStr{$_}) . $StrR; } else { # モードなし return "$StrL${$$refStr{$_}}$StrR"; } } else { # データ存在時 return $StrN; } } } return $StrA; # ラベル不一致時(元に戻す) }; my($Label) = join('|', keys %$refStrEx); my($i) = 0; while($$refStrMdl =~ s/(\t([^\t]*)\t($Label)(_IJS)?<$i>\t([^\t]*)\t([^\t]*)\t)/&$refStrExLabel($1, $2, $3, $4, $5, $6, $refStrEx)/eg) { $i++ } $$refStrMdl =~ s/(\t([^\t]*)\t($Label)(_IJS)?\t([^\t]*)\t([^\t]*)\t)/&$refStrExLabel($1, $2, $3, $4, $5, $6, $refStrEx)/eg; return 1; # 戻り値(常に1) } sub MakeDLTag { # 情報を引数に与えると拡張子に応じてTABLEを作りそれを返す my($refStrMdl, $refDataKind, $FilePath, $FileSize, $Width, $Height, $refLViewFs, $refLImgSUp, $refLImgSDat, $refLImgSJs, %StrAddLabel) = @_; # 引数(雛型のリファレンス, 表示制限情報, ファイルパス, ファイルサイズ, 横サイズ, 縦サイズ, \表示可能最大ファイルサイズ, [最大画像サイズ(アップ制限版)(横サイズ,縦サイズ)], [最大画像サイズ(データ解析版)(横サイズ,縦サイズ)], [最大画像サイズ(JavaScript版)(横サイズ,縦サイズ)], 追加(ラベル, 文字列)) # 拡張子に応じて対応 if ($FilePath ne "") { # パスがある時、即ちファイルがある時 if ($FileSize ne "") { # ファイルサイズ指定がある時 $FileSizeF = &Ceilf($FileSize, @STRFILESIZEFMT); # 指定書式に変換 } else { # ファイルサイズ指定が空の時 $FileSizeF = '?'; # ファイルサイズを?にする } my($FileEx) = &ExFind($FilePath); # パスから拡張子を取得 my(@ImgReSize) = &GetDatImgReSize($Width, $Height, $$refLImgSDat[0], $$refLImgSDat[1]); # 画像サイズ情報取得 foreach (@$refStrMdl) { my $fFind = ""; foreach (@{$$_[0]}) { if (lc($_) eq lc($FileEx) || $_ eq '*' || $_ eq '**') { $fFind = 1; last; } } if ($fFind) { # 拡張子一致時 if (${$$_[0]}[0] ne '**' && !$F_OVERUPIMGSIZEERR && (($$refLImgSUp[0] ne "" && $$refLImgSUp[0] < $Width) || ($$refLImgSUp[1] ne "" && $$refLImgSUp[1] < $Height))) { # 全ての拡張子以外&&エラーキャンセル指定時&&制限サイズより上の時 next; } if (!$F_JUSTIMGSIZE) { @ImgReSize = ("", ""); } my(@ImgRate) = ((($Width && $ImgReSize[0] ne "") ? $ImgReSize[0]/$Width : ""), (($Height && $ImgReSize[1] ne "") ? $ImgReSize[1]/$Height : "")); foreach (\$ImgRate[0], \$ImgRate[1]) { if ($$_ eq "") { next; } $$_ = $$_ * 100; $$_ = int($$_); if (!$$_) { $$_ = 1; } elsif ($$_ > 100) { $$_ = 100; } } my $StrMdl = ""; # 雛型格納 if (!exists(${$OWNERPASS[0]}{$DataOut{'passown'}})) { # 管理人パス未指定 if ($HIDDENUPFILE) { # ○強制非表示モード $StrMdl = (($#{$$_[1]} >= 4 && ${$$_[1]}[4] ne "") ? ${$$_[1]}[4] : $TABLEFILEMDLLVF[4]); } else { my $fFind = ""; foreach (@VIEWUPFILEINF) { if ($$_[0] eq $$refDataKind[0] && $$_[1] eq $$refDataKind[1] && $$_[2] eq $$refDataKind[2]) { $fFind = 1; last; } } if ($USEVIEWUPFILEMODE && $fFind) { # 表示制限モード時&&表示制限拡張子一致時 my $fFind = ""; foreach (@LIMITEXVUPFILE) { if (lc($_) eq lc($FileEx) || $_ eq '*') { $fFind = 1; last; } } if ($fFind) { # 表示制限拡張子一致時 if ($USEVIEWUPFILEMODE == 1) { # ○非表示(リンクあり)モード $StrMdl = (($#{$$_[1]} >= 1 && ${$$_[1]}[1] ne "") ? ${$$_[1]}[1] : $TABLEFILEMDLLVF[1]); } elsif ($USEVIEWUPFILEMODE == 2) { # ○非表示(リンクなし)モード $StrMdl = (($#{$$_[1]} >= 2 && ${$$_[1]}[2] ne "") ? ${$$_[1]}[2] : $TABLEFILEMDLLVF[2]); } } } # ○ファイルサイズオーバーモード if ($StrMdl eq "" && $$refLViewFs ne "" && ${$$_[1]}[3] ne "" && $FileSize ne "" && $$refLViewFs < $FileSize) { # 表示制限雛型未格納時&&制限指定時&&空以外&&ファイルサイズ指定がある時&&指定ファイルサイズを超えた時 $StrMdl = (($#{$$_[1]} >= 3 && ${$$_[1]}[3] ne "") ? ${$$_[1]}[3] : $TABLEFILEMDLLVF[3]); } } } if ($StrMdl eq "") { # ○通常表示モード||表示制限雛型未格納時 $StrMdl = (($#{$$_[1]} >= 0) ? ${$$_[1]}[0] : $TABLEFILEMDLLVF[0]); } my(%ExStr) = ('FILEPATH',\$FilePath, 'FILEEX',\$FileEx, 'FILESIZE',\$FileSizeF, 'WIDTH',\$Width, 'HEIGHT',\$Height, 'REWIDTH',\$ImgReSize[0], 'REHEIGHT',\$ImgReSize[1], 'WIDTHRATE',\$ImgRate[0], 'HEIGHTRATE',\$ImgRate[1], 'MDL_L',\$STRDLTAGTABLE_L, 'MDL_R',\$STRDLTAGTABLE_R, 'IMGRESIZE',\&MakeJSImgReSize(@$refLImgSJs, '2')); foreach (keys %StrAddLabel) { $ExStr{$_} = \$StrAddLabel{$_}; } # 追加 &ReplaceLabel(\$StrMdl, \%ExStr); my(@FilePathC) = &ExFind($FilePath); return &SetVarJsInf(\$StrMdl, [$FilePathC[1]]); } } } # ファイルパスが無い時 return ""; # 空を返す } sub MakeIconTag { # アイコン表示タグを作りそれを返す my($IconID, $refTFileMdl) = @_; # 引数(アイコンID(配列番号), 雛型指定(省略時はデフォルトの雛型)) if (ref($refTFileMdl) ne 'ARRAY') { $refTFileMdl = \@TABLEFILEMDL_ICN; } return &MakeDLTag($refTFileMdl, ['i', ${$IconInf[$IconID]}[0], ""], ${$IconInf[$IconID]}[2], ${$IconInf[$IconID]}[7], ${$IconInf[$IconID]}[5], ${$IconInf[$IconID]}[6], \$LIMITVIEWFILESIZE[1], \@LIMITUPIMGSIZE_ICN, \@LIMITUPIMGRESIZE_ICN, \@LIMITPICSIZE_ICON, 'NUMBER',$IconID, 'NAME',((${$IconInf[$IconID]}[10] ne "") ? &GetNameKeisyou(\${$IconInf[$IconID]}[10], ['i'], ${$IconInf[$IconID]}[1], "", $IconInf[$IconID]) : ""), 'PVTNAME',((${$IconInf[$IconID]}[4] ne "" && ${$IconInf[$IconID]}[1] ne "") ? &GetNameKeisyou(\${$IconInf[$IconID]}[4], ['i'], ${$IconInf[$IconID]}[1], "", $IconInf[$IconID]) : ""), 'ICONNAME',${$IconInf[$IconID]}[3], 'ICONCOM',${$IconInf[$IconID]}[8]); } sub UpFileJudge { # アップされたファイルが適しているか判定する。 # ファイル入力欄が無記入かとうかのチェック if ($DataOut{'UpFileDataFN'} eq "") { # ファイル入力欄が無記入の場合(判定の必要無し) return ('.', 0); # 戻り値('.',0) } # アップされたファイルの0チェック if (!$DataOut{'UpFileDataFS'}) { # ファイルが空の時、又はパスが存在しない時 $ERR_CODE = 'FILE_EMPTY'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:ファイルが空か、又は存在しません>", "", ( 'エラー: アップ出来ません。
' .'ファイルが空か、又は存在しません。
' ), $BBSPageNum); } # グローバル変数の扱いに注意!! my($Mode) = @_; # モードは1はファイルサイズのみ、2は画像拡張子&ファイルのヘッダを判別(アイコン時使用) # モードによる振り分け my $tmpFileMaxSize = ""; # 最大ファイルサイズを格納する為の変数 my $refListEnableEx; # 判定用拡張子リストを格納する為の変数 my $refListDisableEx; # 判定用禁止拡張子リストを格納する為の変数(格納されなかった時は配列長はゼロのままになる) my $LimitExInf = ""; # 制限ファイル一覧リストのトップの説明を格納する為の変数 if ($Mode == 1) { # 通常モードの時 $tmpFileMaxSize = $FileMaxSize; $refListEnableEx = \@LIMITEX; $refListDisableEx = \@DISABLEEX; $LimitExInf = $WFLIMITEXINFL; } elsif ($Mode == 2) { # アイコンファイルモードの時 $tmpFileMaxSize = $IconFileMaxSize; $refListEnableEx = \@LIMITEXICON; @$refListDisableEx = (); $LimitExInf = $WFLIMITEXINFLREG; } elsif ($Mode == 3) { # BGSファイルモードの時 $tmpFileMaxSize = $BGSFILEMAXSIZE; $refListEnableEx = \@LIMITEXBGS; @$refListDisableEx = (); $LimitExInf = $WFLIMITEXINFLREG; } if ($tmpFileMaxSize eq "") { # ファイルサイズ制限指定ない時 $tmpFileMaxSize = ""; # 制限を無効にする } # データ情報取得処理 my $FileEx = scalar(&ExFind($DataOut{'UpFileDataFN'})); my $FileSize = $DataOut{'UpFileDataFS'}; if (!exists(${$OWNERPASS[0]}{$DataOut{'pass'}})) { # 管理人用パスワード以外時 # [0]ファイルサイズ判定処理 if ($tmpFileMaxSize ne "" && (($tmpFileMaxSize < $FileSize) ? 1 : 0)) { $ERR_CODE = 'FILE_SIZE(' . $FileSize . ')'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:ファイルサイズが大きすぎます>", "", ( 'エラー: アップ出来ません。
' .'ファイルサイズが大きすぎます。
ファイルサイズ:
' . $FileSize .' BYTE
' .'最大:
' . $tmpFileMaxSize .' BYTEまでです。
' ), $BBSPageNum); } # [1]ファイル拡張子判定処理 my $FileExLc = lc($FileEx); { my $fErr = ""; if (scalar(@$refListEnableEx)) { $fErr = 1; foreach (@$refListEnableEx) { if ($FileExLc eq lc($_)) { $fErr = 0; last; } } } else { $fErr = 0; } if (scalar(@$refListDisableEx)) { foreach (@$refListDisableEx) { if ($FileExLc eq lc($_)) { $fErr = 1; last; } } } if ($fErr) { # 拡張子に不正があった時 $ERR_CODE = 'FILE_EX(' . $FileEx . ')'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:アップ出来ません>", "", ( 'エラー: アップ出来ません。
' ."$FileExファイルは許可されていません。
" .('アップ可能なファイル一覧' . &MakeTagLimitExInf($LimitExInf, $refListEnableEx, $refListDisableEx) . 'を参照して下さい。
') ), $BBSPageNum); } } # [2]ファイルデータ判定処理 if (!$F_USEFALSEEX) { # 偽装拡張子未許可 my $fErr = ""; my($refResEx, $refResDifEx) = &GetKindFile(((ref($DataOut{'UpFileData'}) eq 'SCALAR') ? ${$DataOut{'UpFileData'}} : \$DataOut{'UpFileData'}), $UPLOADCASHSIZE, $USEFLOCK); if (scalar(@$refResEx)) { my %ExistsEx; foreach (@$refResEx) { $ExistsEx{$_} = 1; } if (scalar(@$refListEnableEx)) { $fErr = 1; foreach (@$refListEnableEx) { if (exists($ExistsEx{lc($_)})) { $fErr = 0; } } } else { $fErr = 0; } if (scalar(@$refListDisableEx)) { foreach (@$refListDisableEx) { if (exists($ExistsEx{lc($_)})) { $fErr = 1; } } } } foreach (@$refResDifEx) { if ($FileExLc eq $_) { $fErr = 1; } } if ($fErr) { $ERR_CODE = 'FILE_DATA(' . $FileEx . ')'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:アップ出来ません>", "", ( 'エラー: アップ出来ません。
' .'内容が' . $FileEx . 'ファイルではないか、もしくは禁止されているファイルです。
' .('アップ可能なファイル一覧' . &MakeTagLimitExInf($LimitExInf, $refListEnableEx, $refListDisableEx) . 'を参照して下さい。
') ), $BBSPageNum); # エラーメッセージフォーム表示 } } } return ($FileEx, $FileSize); # 戻り値(ファイルの拡張子, ファイルサイズ) } sub GetRNDIcon { # 呼び出せばランダムアイコンIDが戻る(引数:お名前)(グローバル@IconInf使用) ## ランダム処理に伴い前もって乱数の種をセットして下さい my($PriPass, $Mode) = @_; # 引数(アイコンパスワード, モード) my($IconID); # 戻り値となる my(@IconID); # アイコン適切なIDのリストを格納 foreach (@IconInf) { # @IconInfから不適切なアイコンを取り除く if (( ($Mode eq 'r' && ($$_[4] eq "" || $$_[1] eq "" || $$_[1] eq $PriPass)) # 全て指定&&(一般アイコン時||パスワード未存在時||パスワード一致時) || ($Mode eq 'rei' && ($$_[4] ne "" && $$_[1] ne "" && $$_[1] eq $PriPass)) # 専用指定&&(専用アイコン時&&パスワード存在時&&パスワード一致時) || ($Mode eq 'reo' && ($$_[4] eq "" || $$_[1] eq "")) # 一般指定&&(一般アイコン時||パスワード未存在時) ) && $$_[0] ne "0") { # &&ID0アイコン意外時 push(@IconID, $$_[0]); # 適切なアイコンIDを格納 } } $IconID = &GetRndItem(\@IconID); # 配列中の要素の1つをランダムに取得 if ($IconID eq "") { # 万が一空の時(通常登録アイコンがない時や又はあっても専用アイコンだけの時) $IconID = 0; # アイコン無しにする } return $IconID; } sub GetRNDTxtClr { # 呼び出せばランダム文字色が戻る ## ランダム処理に伴い前もって乱数の種をセットして下さい my($RTTxtClr); # 戻り値となる my($i) = 0; my(@tmpWFIMPTXTCLR); # 加工用 foreach (@WFIMPTXTCLR) { # 色が指定されているの時(@WFIMPTXTCLRはグローバルです) if ($_ ne "") { # 空じゃ無い時 $tmpWFIMPTXTCLR[$i] = $_; # 追加する $i++; } } $RTTxtClr = &GetRndItem(\@tmpWFIMPTXTCLR); # 配列中の要素の1つをランダムに取得 return $RTTxtClr; } sub GetAllMaxNum { # 全記事数を返します my($AllMaxNum) = ""; # 記事数を取得する為の変数 # オープンしてオープン失敗の時(ファイルが存在しない時)新規ファイルを生成 local(*FILENUM); if (&MakeNewFile($FILENUMFN, '0', open(FILENUM, "<$FILENUMFN"), $USEFLOCK)) { open(FILENUM, "<$FILENUMFN"); } # もし新規ファイルが生成された時はもう一度オープンする &OpenFLock(FILENUM); $AllMaxNum = ;# 一行読み取り &CloseFLock(FILENUM); &EmpFileChk(\$AllMaxNum, $FILENUMFN); # ファイルが空の時のエラー処理 return $AllMaxNum; } sub AddAllMaxNum { # 呼び出すと$FILENUMFNファイル内の数値を1つ上げてファイルに書き込をしてその数を返す(&GetAllMaxNum()使用) my($AllMaxNum) = &GetAllMaxNum(); # 全記事数を取得する local(*FILENUM); if (open(FILENUM, ">$FILENUMFN")) { &OpenFLock(FILENUM, 1); # 上書きモード print FILENUM ++$AllMaxNum; # 全記事数を1つ増やす &CloseFLock(FILENUM); } return $AllMaxNum; # 全記事数を返す } sub GetJudgeIconInf { # アイコンID('R'ランダムも含む)を与えると適切ならアイコンIDを返す my($IconID, $PriPass) = @_; # 引数取得(アイコンID(戻り値となる)、専用パスワード) # ランダムアイコン処理($IconIDが'R'の時) if ($IconID =~ /^r/) { # ランダムアイコンの時($IconIDが'r〜'の時) $IconID = &GetRNDIcon($PriPass, $IconID); # アイコンランダムIDを取得 } # 存在しないアイコンを選んだ時(通常、アイコンが削除される直前にページを開いた時など) if ($IconInfID{$IconID} eq "") { # アイコン情報が無い時 my($tmpStrErrInf) = 'エラー
'; $tmpStrErrInf .= 'そのアイコンは既に削除されています。
'; $ERR_CODE = "ICON_NOEXIST($IconID)"; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:そのアイコンは存在しません>", "", $tmpStrErrInf, $BBSPageNum); # エラーメッセージフォーム表示 } # 専用のアイコン処理 if (${$IconInf[$IconInfID{$IconID}]}[4] ne "" && ${$IconInf[$IconInfID{$IconID}]}[1] ne "" && ${$IconInf[$IconInfID{$IconID}]}[1] ne $PriPass && !exists(${$OWNERPASS[0]}{$PriPass})) { # 専用アイコン指定&&パスワード存在時&&パスワード不一致時&&管理人用パスワード以外時 if ($F_VIEWICONERR == 1) { # アイコンエラーページを表示させる設定の時 my($tmpStrErrInf) = 'エラー
'; $tmpStrErrInf .= &GetNameKeisyou(\${$IconInf[$IconInfID{$IconID}]}[4], ['i', 't'], ${$IconInf[$IconInfID{$IconID}]}[1], "", $IconInfID{$IconID}); $tmpStrErrInf .= '専用アイコンです。
'; $tmpStrErrInf .= '他のアイコンを選んで下さい。
'; $ERR_CODE = 'ICON_EXCLUSIVE(' . ${$IconInf[$IconInfID{$IconID}]}[0] . ')'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:" . &GetNameKeisyou(\${$IconInf[$IconInfID{$IconID}]}[4], ['i'], ${$IconInf[$IconInfID{$IconID}]}[1], "", $IconInfID{$IconID}) . "専用アイコンです>", "", $tmpStrErrInf, $BBSPageNum); # エラーメッセージフォーム表示 } else { $IconID = 0; # アイコン所有者じゃないのでアイコン無しにする。 } } return $IconID; } sub JudgeSameData { # 同一データの時、エラーメッセージ my($Path, $Mode) = @_; # 引数(ファイルパス, モード(真は判定、偽は生成)) if ($Path eq "" || $F_SWLMTSAMEDATA == 0) { return ""; } # 同一内容連続投稿禁止処理 local(*FILE); if ($Mode) { # ○判別 my($fOpen) = &MakeNewFile($Path, "\n", open(FILE, "<$Path"), $USEFLOCK); if (defined($fOpen)) { if ($fOpen) { if (!open(FILE, "<$Path")) { return; } } # もし新規ファイルが生成された時はもう一度オープンする &OpenFLock(FILE); my(%Data); my($fNoJust) = 1; # データが1つでも不一致時、真('1')になる(未処理時、真('1')) while (defined(my $tmpData = )) { chomp($tmpData); # 行末の改行の取り除き(あれば) if ($tmpData eq "") { next; } my(@SepData) = split(/\t/, $tmpData); $Data{$SepData[0]} = $SepData[1]; $fNoJust = ""; } &CloseFLock(FILE); if (!$fNoJust) { # 読み込んだ時 foreach (sort keys %Data) { if ($DataOut{$_} ne $Data{$_}) { $fNoJust = 1; last; } } } if (!$fNoJust) { $ERR_CODE = "SERIALWRITE_DATA($Path)"; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:同一内容連続投稿禁止>", "", 'エラー:同一内容の連続投稿は出来ません。
', 1); # エラーメッセージフォーム表示 } } else { return; } } else { # ○生成 my($fOpen) = &MakeNewFile($Path, "", open(FILE, ">$Path"), $USEFLOCK); if (defined($fOpen)) { if ($fOpen) { if (!open(FILE, ">$Path")) { return; } } # もし新規ファイルが生成された時はもう一度オープンする if (open(FILE, ">$Path")) { &OpenFLock(FILE, 1); # 上書きモード foreach (sort keys %DataOut) { if ($_ =~ /^UpFileData(_\d*)?$/) { next; } # ファイルデータの時は飛ばす print FILE "$_\t$DataOut{$_}\n"; } &CloseFLock(FILE); } } else { return; } } return 1; } sub ManageNewDataInf { # 新着投稿履歴情報処理 if (!$F_USENEWDATAINF) { return; } # 未許可時 my($refMode, $refAddData) = @_; # 引数(モード(取得:""|新規:[]|編集&削除:[NO,ID]), (取得:""|新規:[[追加データ], …]|編集:[[追加データ]]|削除:[])) if (ref($refMode) eq 'ARRAY') { # 保存モード if (scalar(@$refMode)) { # 編集 @NEWDATAINF = grep { if (($$refMode[0] eq "" || $$refMode[0] eq $$_[0]) && ($$refMode[1] eq "" || $$refMode[1] eq $$_[1])) { if (scalar(@$refAddData)) { my $i = 0; foreach my $AddDat (@{$$refAddData[0]}) { if (defined($AddDat)) { $$_[$i] = $AddDat; } $i++; } 1; } else { ""; } } else { 1; } } @NEWDATAINF; foreach (@NEWDATAINF) { $_ = join("\t", @$_); } if ((my $DummyNum = $NEWDATAINFNUM - scalar(@NEWDATAINF)) > 0) { push(@NEWDATAINF, ("") x $DummyNum); } } else { # 新規追加 undef(@NEWDATAINF); # クリア foreach (@$refAddData) { push(@NEWDATAINF, join("\t", @$_)); } } $refAddData = \@NEWDATAINF; $Mode = 'unshift'; } else { # 取得モード $refAddData = ""; $Mode = ""; } if (defined(@NEWDATAINF = &FileAddLineData($NEWDATAINFFN, $Mode, $refAddData, $NEWDATAINFNUM, $USEFLOCK))) { @NEWDATAINF = grep { if ($_ ne "") { $_ = [split(/\t/, $_)]; 1; } else { ""; } } @NEWDATAINF; } else { &EmpFileChk(\"", $NEWDATAINFFN); } return 1; # 戻り値(常に1) } sub SortNewDataInf { # 記事順情報処理('get'は必ず最初に1回呼び出して下さい) my($Mode, $FileNum) = @_; # 引数(モード('get','save','del'), ファイルナンバー('save'、'del'時必要)) my $SortMode = $MODE_SORTNEWDATA; my $AllMaxNum = $ALLDATANUM; my $LimitDataNum = (&GetPageInf(1, $VIEWDATANUM[0], $AllMaxNum, $MAXRSVDATANUM))[6]; if ($F_SAVESORTNEWDATA == 0 || !$AllMaxNum) { return; } my($MaxReserveDataNumC) = ""; # 置き換え最大記事数格納 my($SortNum) = 1; my($FilePath); foreach $FilePath ($SORTDATAINFNFN, $SORTDATAINFRFN) { my(@NewDataInf); # 保存データ格納 if ($FilePath eq "") { next; } local(*FILE); if (&MakeNewFile($FilePath, "0", open(FILE, "<$FilePath"), $USEFLOCK)) { open(FILE, "<$FilePath"); } # もし新規ファイルが生成された時はもう一度オープンする &OpenFLock(FILE); while (defined(my $Data = )) { chomp($Data); push(@NewDataInf, $Data); } &CloseFLock(FILE); if (!scalar(@NewDataInf)) { &EmpFileChk(\"", $FilePath); } # ファイルが空の時のエラー処理 my($NewDataInfDel) = shift(@NewDataInf); # 削除回数を保存 if ($Mode eq 'get' && (scalar(@NewDataInf) + $NewDataInfDel) != ($AllMaxNum - $LimitDataNum + 1)) { # 'get'時&&情報破損時 my($Regexp) = join('|', @NewDataInf); my(@NewDataInfMdl) = grep { $_ !~ /^($Regexp)$/; } ($LimitDataNum .. $AllMaxNum); # 雛型の情報未存在情報のみを取得 unshift(@NewDataInf, @NewDataInfMdl); # 追加 @NewDataInf = @NewDataInf[$#NewDataInf - ($AllMaxNum - $LimitDataNum) .. $#NewDataInf]; # 最大情報数に切り詰める $NewDataInfDel = 0; # 削除数をリセット &MakeNewFile($FilePath, (join("\n", ($NewDataInfDel, @NewDataInf)) . "\n"), "", $USEFLOCK); # 強制雛型生成 } elsif ($Mode eq 'save' || $Mode eq 'del') { # 保存モード||削除モード my($fJustData) = scalar(@NewDataInf); # データ一致時、真 my(@NewDataInfRm) = grep { $_ ne $FileNum; } @NewDataInf; # 指定ファイルナンバーの取除き(あれば) if ($fJustData == scalar(@NewDataInfRm)) { $fJustData = 1; } else { $fJustData = ""; } # データ一致フラグ格納 my($fSave) = ""; # 保存時、真 if ($Mode eq 'save') { # 保存モード if ($SortNum == 2) { # 新着ソート時 @NewDataInf = @NewDataInfRm; # コピー push(@NewDataInf, $FileNum); # 追加 $fSave = 1; # 保存 } elsif ($fJustData) { # データ新規追加時 push(@NewDataInf, $FileNum); # 追加 $fSave = 1; # 保存 } if ($fJustData && $MAXRESERVEDATANUM ne "" && $MAXRESERVEDATANUM < $AllMaxNum) { # 追加時&&指定時&&制限オーバー時 my($NewDataInfNum) = $#NewDataInf; # 記事数保存 @NewDataInf = grep { $_ >= ($LimitDataNum - $NewDataInfDel); } @NewDataInf; # 制限記事除去 if ($NewDataInfNum == $#NewDataInf) { $NewDataInfDel--; } # 削除数をデクリメント(制限記事が既に削除されている時) } } elsif ($Mode eq 'del') { @NewDataInf = @NewDataInfRm; # コピー $NewDataInfDel++; $fSave = 1; # 保存 } if ($fSave) { # 保存 &MakeNewFile($FilePath, (join("\n", ($NewDataInfDel, @NewDataInf)) . "\n"), "", $USEFLOCK); # 強制ファイル上書き } } # 削除回数の取除いた新着情報格納&&最大記事数格納 if ($SortMode == $SortNum) { # 格納すべき時 if (scalar(@NewDataInf)) { $MaxReserveDataNumC = scalar(@NewDataInf); if (!$MaxReserveDataNumC) { $MaxReserveDataNumC = 1; }; } @SORTDATAINF = @NewDataInf; undef(%SORTDATAINF); # 変数をクリアする my($i) = 0; foreach (@SORTDATAINF) { $SORTDATAINF{$_} = $i; $i++; } } $SortNum++; } if ($MaxReserveDataNumC ne "") { $MAXRSVDATANUM = $MaxReserveDataNumC; } # 最大記事数格納 return; # 戻り値(常に未定義値) } sub ManageDataSize { # データファイル等のデータ量を管理します if (!$USEDATASIZEMANAGER) { return; } # 無管理指定時 my(@refAddDataInf) = @_; # 引数(追加データサイズの入った配列(省略時は取得のみ)) my($fSet) = ""; # セットモード時、真 if (defined(@refAddDataInf)) { $fSet = 1; } # セットモード切り替え my(@refRTDataInf); # ロードデータ構造体生成(戻り値) foreach (&FileAddLineData($DATASIZEINFFN, "", "", 4, $USEFLOCK)) { my(@SepData) = split(/\t/, $_); my($i); for ($i = scalar(@SepData); $i < 7; $i++) { push(@SepData, "0"); } # データ数が足りない時ダミー補完 push(@refRTDataInf, \@SepData); } if (!defined(@refRTDataInf)) { &EmpFileChk(\"", $DATASIZEINFFN); } # ファイルが空の時のエラー処理 if ($fSet) { # セットモード時 my($i) = 0; for ($i = scalar(@refAddDataInf); $i < 4; $i++) { push(@refAddDataInf, []); } # データ数が足りない時ダミー補完 $i = 0; my(@LastDataInf) = (); # 前回のを保存 foreach (@refRTDataInf) { push(@LastDataInf, [@$_]); @$_ = &JoinLtoL($_, '+', $refAddDataInf[$i]); # 構造体同士の足し算 $i++; } foreach (\@LastDataInf, \@refRTDataInf) { splice(@$_, 1, 0, [&JoinLtoL($$_[1], '-', $$_[2])]); # 実質投稿数を追加 } my($StrErr) = ""; $i = 0; foreach (@LIMITFILESIZE) { if ($_ ne "" && ${$refRTDataInf[0]}[$i] > ${$LastDataInf[0]}[$i]) { # 制限が指定されている時&&前回のサイズより増えた時 if (${$refRTDataInf[0]}[$i] > $_) { if ($i) { $StrErr .= '; '; } $StrErr .= "[$i]: " . (${$refRTDataInf[0]}[$i] - $_) . "+$_"; } # 不正 } $i++; } if ($StrErr ne "") { # エラー $ERR_CODE = "DATASIZE_OVER($StrErr)"; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:最大容量を越えました>", "", "最大容量を越えました
", "1"); # エラーメッセージフォーム表示 } $i = 0; foreach (@LIMITFILEUPNUM) { if ($_ ne "" && ${$refRTDataInf[1]}[$i] > ${$LastDataInf[1]}[$i]) { # 制限が指定されている時&&前回の回数より増えた時 if (${$refRTDataInf[1]}[$i] > $_) { if ($i) { $StrErr .= '; '; } $StrErr .= "[$i]: " . (${$refRTDataInf[1]}[$i] - $_) . "+$_"; } # 不正 } $i++; } if ($StrErr ne "") { # エラー $ERR_CODE = "DATAUPNUM_OVER($StrErr)"; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:最大投稿数を越えました>", "", "最大投稿数を越えました
", "1"); # エラーメッセージフォーム表示 } my(@SaveDataInf); foreach (@refRTDataInf) { push(@SaveDataInf, join("\t", @$_)); } splice(@SaveDataInf, 1, 1); # 実質投稿数を削除 &FileAddLineData($DATASIZEINFFN, 'unshift', \@SaveDataInf, 4, $USEFLOCK); # セット @FILESIZEINF = @refRTDataInf; # グローバルを更新 } else { # ロードモード時 splice(@refRTDataInf, 1, 0, [&JoinLtoL($refRTDataInf[1], '-', $refRTDataInf[2])]); # 実質投稿数を追加 } return @refRTDataInf; # 戻り値(データサイズ情報) } sub DesStrReplace { # デザイン設定文字列の置き換えをします my($Label, $refRep, @refStr) = @_; # 引数(ラベル, 変換する文字列のリファレンス, 変換対象文字列のリファレンスのリスト) if (defined($$refRep)) { my($RepStrNum) = 0; # 変換回数 foreach (@refStr) { $RepStrNum += $$_ =~ s//$$refRep/; # 戻り値(変換時'1'、無変換時'') } return $RepStrNum; } else { return; } } sub JudgeAdmitUrl { # 正常なURLの時、真('1') my($refStr) = @_; # 引数(対象スカラーのリファレンス) # リンクセーフティーモード時 if ($F_SAFETYLINK == 1) { # レベル1 if ($$refStr =~ /\.(exe|scr|cgi|php\d*)[\/\?]/i) { return ""; } } elsif ($F_SAFETYLINK == 2) { # レベル2 if ($$refStr =~ /\.(exe|scr|cgi|php\d*)$|\.(exe|scr|cgi|php\d*)[\/\?]/i) { return ""; } } return 1; } sub JudgeLimitImgSize { # 制限サイズ以下の時、真('1') my($refData, $LWidth, $LHeight) = @_; # 引数(対象データのリファレンス, 制限横サイズ, 制限縦サイズ) my(@FileInf) = &GetImageFileInf($refData, $UPLOADCASHSIZE, $USEFLOCK); if (defined(@FileInf)) { # 画像ファイル時 # 画像サイズチェック if ($F_OVERUPIMGSIZEERR && (($LWidth ne "" && $LWidth < $FileInf[2]) || ($LHeight ne "" && $LHeight < $FileInf[3]))) { # エラー指定時&&制限サイズより上の時 $ERR_CODE = 'IMG_WIDTH(*.$FileInf[0],S$FileInf[1],W$FileInf[2],H$FileInf[3])'; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:画像サイズが大きすぎます>", "" , "エラー: アップ出来ません。
$FileInf[0]ファイル
幅:$FileInf[2]、高さ:$FileInf[3]
画像サイズが大きすぎます。
幅:$LWidth、高さ:$LHeight
以下にリサイズして下さい。" , 1); # エラーメッセージフォーム表示 } if ($F_SAVEMNGIMGINF == 0 || !$FileInf[2] || !$FileInf[2]) { $FileInf[2] = ""; $FileInf[3] = ""; } } else { return ("", ""); } return ($FileInf[2], $FileInf[3]); # 戻り値(横サイズ, 縦サイズ) } sub VarExAbsolutePath { # 相対パス(./)を絶対パス(ベース絶対パス)に変換 my($refData) = @_; # 引数(対象データリファレンス配列のリファレンス(ハッシュ時はキーは無変換)) my($RegAutoAbsPathC) = $REGAUTOABSPATH; # コピー &DecRegexpStr(\$RegAutoAbsPathC); # マッチングに都合の悪い文字を変換 my($refVar); foreach $refVar (@$refData) { if (ref($refVar) eq 'SCALAR') { $$refVar =~ s/$RegAutoAbsPathC/$DIRPATHWEB/go; } elsif (ref($refVar) eq 'ARRAY') { foreach (@$refVar) { $_ =~ s/$RegAutoAbsPathC/$DIRPATHWEB/go; } } elsif (ref($refVar) eq 'HASH') { foreach (keys %$refVar) { $$refVar{$_} =~ s/$RegAutoAbsPathC/$DIRPATHWEB/go; } } } return; } sub IjsEmpInpErr { # 必須項目未入力欄エラーインラインJavaScript文字列を返す my($refData, $refErrInf, $refInsertJS) = @_; # 引数(対象データ配列のリファレンス, 表示文字列のリファレンス(省略時は$WFJSEMPINPERRINF), 挿入JSのリファレンス[未エラーブロック内追加JS,真ブロック内追加JS,偽ブロック内追加JS](省略可)) my($JsEmpInpErr) = ""; # 戻り値。偽時未入力エラーJS情報(偽時未入力エラーJS, エラー時閉じJS) if (ref($refInsertJS) ne 'ARRAY') { $refInsertJS = [" ", " ", " "]; } if (ref($refErrInf) ne 'SCALAR') { $refErrInf = \$WFJSEMPINPERRINF; } # 省略時 if ($$refErrInf ne "" && scalar(@$refData)) { # 指定時 $JsEmpInpErr .= "if (fSendData) { return false; } "; $JsEmpInpErr .= "if (fNav_OS != 'Mac' || fNav_Br == 'IE') { "; $JsEmpInpErr .= "if (" . join(' && ', @$refData) . ") {$$refInsertJS[0] return BTNSendonClick(); } "; $JsEmpInpErr .= "else { if (confirm('" . &DataDec::DecInJsStr($refErrInf) . "')) {$$refInsertJS[1] return BTNSendonClick(); } else {$$refInsertJS[2] return false; } } "; $JsEmpInpErr .= "}"; } else { # 未指定時 $JsEmpInpErr .= "return BTNSendonClick();"; } return $JsEmpInpErr; } sub GetStatusDef { # ステータスIDとトータルポイントを渡すと、そのステータス定義情報を返す my($refStatI) = @_; # 引数([ステータスID,トータルポイント])。戻り値(ステータス定義情報) my($TtlPnt) = ""; # 最高トータルポイントを保存 my($JustStaDef); # 条件を満たした定義情報を格納 foreach (@STATUSDEF) { if ($$_[0] eq $$refStatI[0]) { # ID一致時 if (${$$_[1]}[0] ne "") { # ポイント指定時 if (${$$_[1]}[0] ne "" && ${$$_[1]}[0] <= $$refStatI[1]) { # 条件を満たした時 if ($TtlPnt eq "" || ${$$_[1]}[0] > $TtlPnt) { # 前回のポイントより大きかったら $TtlPnt = ${$$_[1]}[0]; $JustStaDef = $_; } } } else { # 無条件ステータス時 if (ref($JustStaDef) ne 'ARRAY') { $JustStaDef = $_; } # 未格納ならば↑にする(あれば) } } } if (ref($JustStaDef) eq 'ARRAY') { return @$JustStaDef; } # 一致定義情報存在時 return; # 一致定義情報未存在時 } sub GetNameKeisyou { # お名前に敬称を付けて返す my($refName, $refMode, $Pass, $refStrInsert, $refData) = @_; # 引数(お名前文字列のリファレンス(内容無変更保証), モード[種類,タグフラグ,オプション], パスワード, 挿入文字列リファ[左,右](あれば), [データ](あれば)) my($RTStr) = ""; # 戻り値 my($refStrInsertC) = [("", "")]; if (ref($refStrInsert) eq 'ARRAY') { $refStrInsertC = $refStrInsert; } if (ref($refMode) eq 'ARRAY') { my($refKeisyou); if (exists(${$OWNERPASS[1]}{$Pass})) { # 管理人用パスワード時 if ($$refMode[1] eq 't') { $refKeisyou = \@OWNERKEISYOUTAG; } # タグありモード else { $refKeisyou = \@OWNERKEISYOU; } # タグなしモード } elsif (exists(${$OWNERPASS[2]}{$Pass})) { # 副管理人用パスワード時 if ($$refMode[1] eq 't') { $refKeisyou = \@OWNERKEISYOUTAG1; } # タグありモード else { $refKeisyou = \@OWNERKEISYOU1; } # タグなしモード } else { # 一般訪問者時 if ($$refMode[1] eq 't') { $refKeisyou = \@KEISYOUTAG; } # タグありモード else { $refKeisyou = \@KEISYOU; } # タグなしモード } my($StrStaInf) = ""; # 投稿回数文字列格納 if ($$refMode[1] eq 't' && ($$refMode[0] eq 'd' || $$refMode[0] eq 's' || $$refMode[0] eq 'sl') && $Pass ne "") { # 適切なモード時&&パスワード存在時 my($refPrmGetStaDef); # &GetStatusDefに渡す引数を格納 if ($$refMode[0] eq 'd') { $refPrmGetStaDef = [@{${$$refData[14]}[0]}[0 .. 1]]; } # 記事モード時 elsif ($$refMode[0] eq 's'|| $$refMode[0] eq 'sl') { $refPrmGetStaDef = $refData; } # ステータスモード時 if (scalar(@$refPrmGetStaDef)) { my(@StatusDef); # 一致定義データを格納 @StatusDef = &GetStatusDef($refPrmGetStaDef); # 一致定義を取得 if (scalar(@StatusDef)) { my(@StrInsStatus) = (); my($i); for ($i = 0; $i < $#{$StatusDef[2]}; $i++) { if ($$refMode[0] eq 'sl') { # ステータス一覧モード if ($i == ($#{$StatusDef[2]} - 1)) { push(@StrInsStatus, "$STAF_STRSTANAMEATR[0]${$StatusDef[2]}[0]$STAF_STRSTANAMEATR[1]"); } else { push(@StrInsStatus, ""); } } else { # それ以外 push(@StrInsStatus, ((${$StatusDef[2]}[$i + 1] ne "") ? ${$StatusDef[2]}[$i + 1] : $$refKeisyou[$i])); } } # ↓敬称文字列格納 $refKeisyou = \@StrInsStatus; # ↓ステータス文字列格納 if ($F_STRMDLSTAINF && $$refMode[0] eq 'd' && ${${$$refData[14]}[0]}[0]) { # 表示指定時&&記事モード時&&ID0メンバ(&"")以外 $StrStaInf = $STRMDLSTAINF; # コピー &ReplaceLabel(\$StrStaInf, {'TTLPT',\${${$$refData[14]}[0]}[1], 'SAVENUM',\(${${$$refData[14]}[0]}[2] + 1), 'ID',\${$STATUSINFPRESTA{$Pass}}[0]}); } } } } my($NameC) = $$refName; # コピー if ($NameC =~ /^(\s| )*$/) { $NameC = $CMN_STREMPLINK; } # リンク出来ない時、指定文字に変換 $RTStr = "$$refKeisyou[0]$$refStrInsertC[0]$$refKeisyou[1]$NameC$$refKeisyou[2]$$refStrInsertC[1]$$refKeisyou[3]$$refKeisyou[4]$StrStaInf"; } return $RTStr; } sub GetDataFooter { # 記事のフッター部を出力する my($refData, $refMode) = @_; # 引数([記事データ], モード[種類,タグフラグ,オプション]) my($RTStr) = ""; # 戻り値 # ○表示環境変数&ユーザー追加入力フォームデータ処理 if ((scalar(@{$$refData[15]}) || scalar(@{$$refData[16]}) || scalar(@{$$refData[17]})) && $ADDINPUTVIEW ne "" && $$refMode[0] eq 'd') { # (表示環境変数存在時||記事オプション存在時||ユーザー追加入力フォームデータ存在時)&&表示指定時&&記事モード時 my($AddInputViewC) = $ADDINPUTVIEW; # コピー if (scalar(@{$$refData[15]})) { $AddInputViewC =~ s/\tENV_(\d+)\t/${$$refData[15]}[$1]/g; } else { $AddInputViewC =~ s/\tENV_\d+\t//g; } # 表示環境変数 if (scalar(@{$$refData[16]})) { my $refVModeStr = \((${$$refData[16]}[0]) ? $VIEWFROMAGENT[1] : $VIEWFROMAGENT[0]); $AddInputViewC =~ s/\tMODE_TEL\t/$$refVModeStr/g; } else { $AddInputViewC =~ s/\tMODE_TEL\t//g; } # 記事オプション if (scalar(@{$$refData[17]})) { $AddInputViewC =~ s/\tUSERINPUT_(\d+)\t/${$$refData[17]}[$1]/g; } else { $AddInputViewC =~ s/\tUSERINPUT_\d+\t//g; } # ユーザー追加入力フォームデータ $RTStr .= $AddInputViewC; } # ○ステータス情報処理 my($refStaData) = []; # ←↓初期値のダミー生成 my($refStrInsert) = [[(("") x 4)], [(("") x 4)]]; if ($$refMode[0] eq 'd') { # 記事モード時 $refStaData = $$refData[14]; $refStrInsert = \@BBSTABLEITEMINF; } if (ref(${$refStaData}[1]) ne 'ARRAY' || !scalar(@{${$refStaData}[1]}) || ref($refStrInsert) ne 'ARRAY') { return $RTStr; } # アイテム非表示時||引数不正 my(@StaDataC) = [[],[]]; foreach (@{${$refStaData}[1]}) { if ($$_[1] ne 'd') { push(@{$StaDataC[0]}, $_); } else { push(@{$StaDataC[1]}, $_); } } my(@StrItem) = (("") x 2); my($Mode) = 0; foreach (\@{$StaDataC[0]}, \@{$StaDataC[1]}) { my($i) = 0; foreach (@$_) { if (exists($STATUSDEFITEM{$$_[0]})) { $StrItem[$Mode] .= ${${$refStrInsert}[$Mode]}[1]; $StrItem[$Mode] .= ${${$STATUSDEFITEM{$$_[0]}}[0]}[0]; $StrItem[$Mode] .= ${${$refStrInsert}[$Mode]}[2]; if ($#{$StaDataC[$Mode]} != $i) { $StrItem[$Mode] .= ${${$refStrInsert}[$Mode]}[3]; } } $i++; } $Mode = 1; } $RTStr .= ${${$refStrInsert}[2]}[0]; my($fStrSep) = ""; for (my $i = 0; $i <= 1; $i++) { if ($StrItem[$i] ne "") { if ($fStrSep) { $RTStr .= ${${$refStrInsert}[2]}[1]; } # 区切り文字列挿入 $RTStr .= "${${$refStrInsert}[$i]}[0]$StrItem[$i]${${$refStrInsert}[$i]}[4]"; $fStrSep = 1; } } $RTStr .= ${${$refStrInsert}[2]}[2]; return $RTStr; } sub ManageStatus { # ステータス情報を管理します if (!$USESTATUSMANAGER || !scalar(%STATUSDEFGRP) || !scalar(@STATUSDEF)) { return; } # 無管理指定時||ステータス情報未定義時 my($refAddData) = @_; # 引数([追加データ](省略時は取得のみ)) # 現在のステータスIDを取得処理 my $refSetSelectedStatus = sub { my $refGetPass = \""; # \"Cookie(PASS)"を格納(内容は書き換え禁止) if (ref($refAddData) eq 'ARRAY' && $$refAddData[1] ne "") { # 引数データ(PASS)が存在 $refGetPass = \$$refAddData[1]; } elsif (exists($OutCookie{"${BASECOOKIENAME}Data"}) && ${$OutCookie{"${BASECOOKIENAME}Data"}}[6] ne "") { # OutCookie(PASS)が存在 $refGetPass = \${$OutCookie{"${BASECOOKIENAME}Data"}}[6]; } elsif (exists($InCookie{"${BASECOOKIENAME}Data"}) && ${$InCookie{"${BASECOOKIENAME}Data"}}[6] ne "") { # InCookie(PASS)が存在 $refGetPass = \${$InCookie{"${BASECOOKIENAME}Data"}}[6]; } if ($$refGetPass ne "" && exists($STATUSINFPRESTA{$$refGetPass})) { # PASSが存在&&現ステータス情報存在 $SELECTEDSTATUS = ${$STATUSINF[${$STATUSINFPRESTA{$$refGetPass}}[0]]}[0]; } else { # 判別不明(Cookie(STAID)にする) if (exists($OutCookie{"${BASECOOKIENAME}Sta"}) && ${$OutCookie{"${BASECOOKIENAME}Sta"}}[0] ne "") { $SELECTEDSTATUS = ${$OutCookie{"${BASECOOKIENAME}Sta"}}[0]; } elsif (exists($InCookie{"${BASECOOKIENAME}Sta"}) && ${$InCookie{"${BASECOOKIENAME}Sta"}}[0] ne "") { $SELECTEDSTATUS = ${$InCookie{"${BASECOOKIENAME}Sta"}}[0]; } } if (!$SELECTEDSTATUS || $SELECTEDSTATUS =~ /\D/ || !exists($STATUSDEFGRP{$SELECTEDSTATUS})) { $SELECTEDSTATUS = '0'; } # ID不正時(ID=0にする) }; &$refSetSelectedStatus(); # $SELECTEDSTATUSセット my $StatusID = $SELECTEDSTATUS; my $refStaData; # 処理結果一時格納 if (ref($refAddData) eq 'ARRAY') { # 引数指定時(保存時)(必ず取得してから呼び出し) # ↓ステータス情報が空の時、不参加ユーザー雛型生成 if (!scalar(@STATUSINF)) { # 現ステータス情報処理 &FileFormatDataManager($STATUSINFPRESFN, "", "\t", [ ["", "0", ""] ], "", "", $USEFLOCK); # ステータス情報処理 &FileFormatDataManager($STATUSINFFN, \@STATUSINF, "\t", [ ["0", ("") x 2, (time + $DIFTIME), "0", ("0") x (8 * 4)] ], "", "", $USEFLOCK); } my(@AddData) = (); # 追加保存データを格納 if (${$$refAddData[0]}[0] eq 's') { if (${$$refAddData[0]}[1] eq 'c') { # ステータス変更モード時(ここでID不正時処理をしておく) if (!$$refAddData[2] || $$refAddData[2] !~ /^\d+$/ || !exists($STATUSDEFGRP{$$refAddData[2]})) { $$refAddData[2] = '0'; } # ID不正時(ID=0にする) } @AddData = @$refAddData; } else { my(@AddDataC) = @$refAddData; # コピー my(@HeadInf) = splice(@AddDataC, 0, 3); # ヘッダー情報の取り出し if (!$StatusID || $HeadInf[1] eq "") { $StatusID = '0'; $HeadInf[1] = ""; $HeadInf[2] = ""; } # ID0||PASS""時(ID0&PASS=""&NAME=""にする) push(@AddData, $StatusID, $HeadInf[1], $HeadInf[2], (time + $DIFTIME), 0); # (0,1,2,3,4)ヘッダー情報(ID,PASS,NAME,TIME,TTLPT)追加 foreach ('dn','dr','i','b') { if ($_ eq ${$HeadInf[0]}[0]) { # 種類一致 push(@AddData, @AddDataC); my($i) = 0; foreach (@AddDataC) { if (($i % 4) && $_) { if (${$HeadInf[0]}[1] eq 'e' && ($i % 7) && ${$HeadInf[0]}[2] ne "" && ${$HeadInf[0]}[2] ne $HeadInf[1]) { # 編集時&&編集情報時&&編集後PASSが設定されていて&&編集後PASSが編集前PASS不一致 $AddData[4] += ${${$STATUSDEFGRP{$StatusID}}[2]}[$i - 1]; # 削除ポイントを加算する } else { $AddData[4] += ${${$STATUSDEFGRP{$StatusID}}[2]}[$i]; # 各モードの加算をする } } # トータルポイント追加(サイズ情報以外の時) $i++; } } else { push(@AddData, (('0') x scalar(@AddDataC))); } # 種類不一致 } if (${$HeadInf[0]}[1] eq 's') { # 投稿時のみ # ↓アイテムポイント追加('d'フラグが無い時) if (exists($STATUSINFPRESTA{$HeadInf[1]})) { # 定義時(備考:ここで未存在キーを使うと空のリファレンスが生成されてしまう為) foreach (@{${$STATUSINFPRESTA{$HeadInf[1]}}[1]}) { if ($$_[2] ne 'd' && exists($STATUSDEFITEM{$$_[0]})) { $AddData[4] += ${${$STATUSDEFITEM{$$_[0]}}[2]}[0]; } } } } } $refStaData = [\@AddData]; # 結果を保存 } # ステータス情報処理 my($ResultSta) = &FileFormatDataManager($STATUSINFFN, \@STATUSINF, "\t", $refStaData, sub { my($refSaveData, $refAddData, $refSaveInf, $refTemp) = @_; # 引数([保存データ(参照)], [追加データ], [保存情報], [テンポラリ変数]) if (ref($$refAddData[0]) eq 'ARRAY' && ${$$refAddData[0]}[0] eq 's') { if (${$$refAddData[0]}[1] eq 'c') { # ステータス変更モード時 if ($$refSaveData[0] eq $SELECTEDSTATUS && $$refSaveData[1] eq $$refAddData[1]) { # 変更前のステータスID一致&&パスワード一致 # ○↓チェンジポイント追加 if (exists($STATUSDEFGRP{$$refSaveData[0]}) && exists($STATUSINFPRESTA{$$refSaveData[1]})) { # グループIDが定義されている時&&現ステータス情報が定義されている時 if (${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[2] && ${$STATUSINF[${$STATUSINFPRESTA{$$refSaveData[1]}}[0]]}[0] ne $$refAddData[2]) { # チェンジポイント指定時&&ステータスIDが違う時 $$refSaveData[4] += ${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[2]; return 1; } } } if ($$refSaveInf[2] != $$refSaveInf[3]) { return ""; } else { return undef(); } } elsif (${$$refAddData[0]}[1] eq 'd') { # ステータス削除モード時 if ($$refSaveData[1] eq $$refAddData[1]) { undef($_[0]); $$refTemp[0] = 1; } if ($$refSaveInf[2] != $$refSaveInf[3]) { return ""; } else { if ($$refTemp[0]) { return 1; } else { return undef(); } } } else { # それ以外(通常実行されない) return undef(); # なにも処理しない } } for (0 .. 1) { if (($$refSaveData[0] eq $$refAddData[0] && $$refSaveData[1] eq $$refAddData[1]) || $_) { # (ステータスID一致&&パスワード一致)||最終行(forループ2周目) if ($_) { @$refSaveData = (@$refAddData[0 .. 2], (time + $DIFTIME), 0, (0) x (scalar(@$refAddData) - 5)); } # 最終行(ダミー雛型生成) my(@SaveData) = (); push(@SaveData, $$refAddData[0], $$refAddData[1], ((defined($$refAddData[2])) ? $$refAddData[2] : $$refSaveData[2]), $$refAddData[3], &JoinLtoL([@$refSaveData[4 .. $#$refSaveData]], '+', [@$refAddData[4 .. $#$refAddData]])); if (exists($STATUSDEFGRP{$$refSaveData[0]})) { # グループIDが定義されている時 # ○↓時間オーバーポイント追加 if (${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[0] && ${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[1]) { $SaveData[4] += (int(((time + $DIFTIME) - $$refSaveData[3]) / ${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[0])) * ${${$STATUSDEFGRP{$$refSaveData[0]}}[1]}[1]; } my($i) = 0; foreach (@$refSaveData[5 .. $#$refSaveData]) { # ↓○サイズ系トータルポイント追加処理 if (!($i % 4) && ${${$STATUSDEFGRP{$$refSaveData[0]}}[2]}[$i]) { # 4の倍数時(ファイルサイズ系)&&ファイルサイズ指定されてる時 $SaveData[4] += int(($$refAddData[5 + $i] + ($_ % abs(${${$STATUSDEFGRP{$$refSaveData[0]}}[2]}[$i]))) / ${${$STATUSDEFGRP{$$refSaveData[0]}}[2]}[$i]); # ((('追加サイズ' + ('元サイズ'と'定義倍数サイズ(正)'の余り)) / '定義倍数サイズ'))の小数点切り捨て } $i++; } } @$refSaveData = @SaveData; # 書き換え if ($_) { @$refAddData = @$refSaveData; } # 最終行(追加データ書き換え) else { return 1; } # 最終行以外(終了シグナルを返す) } else { if ($$refSaveInf[2] != $$refSaveInf[3]) { last; } # 最終行以外 } } return ""; # ループ持続 } , [], $USEFLOCK); if (!defined($ResultSta)) { &EmpFileChk(\"", $STATUSINFFN); } # ファイルが空の時のエラー処理 @STATUSINF = grep { exists($STATUSDEFGRP{$$_[0]}) } @STATUSINF; # 定義されてない要素を除去 my($StaNPUserN) = ""; # ステータス情報内(不参加ユーザー)配列番号を格納(未発見時"") my($StaNum) = 0; # ステータス番号を保存 foreach (@STATUSINF) { if ($$_[1] eq "") { $StaNPUserN = $StaNum; } # 不参加ユーザー時、その番号を保存 push(@$_, [splice(@$_, 5)]); # データ部のリファレンス化 my(@AddStaInf); my($i); for ($i = 0; $i < 8; $i++) { push(@AddStaInf, (${$$_[5]}[$i] + ${$$_[5]}[$i + 8])); # 新規&返信データ生成 } unshift(@{$$_[5]}, @AddStaInf); # 新規&返信データ追加 if (exists($STATUSDEFGRP{$$_[0]}) && ${${$STATUSDEFGRP{$$_[0]}}[1]}[0] != 0 && ${${$STATUSDEFGRP{$$_[0]}}[1]}[1]) { # 時間オーバーポイント追加 $$_[4] += (int(((time + $DIFTIME) - $$_[3]) / ${${$STATUSDEFGRP{$$_[0]}}[1]}[0])) * ${${$STATUSDEFGRP{$$_[0]}}[1]}[1]; } $StaNum++; } if ($StaNPUserN ne "") { push(@STATUSINF, splice(@STATUSINF, $StaNPUserN, 1)); } # 不参加ユーザー、末尾に移動 # 現ステータス情報処理 # # # my($refPreStaData); # 処理結果一時格納 if (ref($refAddData) eq 'ARRAY') { # 引数指定時(保存時)(必ず取得してから呼び出し) if (${$$refAddData[0]}[0] eq 's') { $refPreStaData = [\@$refAddData]; } else { # 現ステータス情報処理 my(@StatusDef); # 一致定義データを格納 if ($$refAddData[1] ne "") { # パスワードが存在 if (exists($STATUSINFPRESTA{$$refAddData[1]})) { @StatusDef = &GetStatusDef([${$STATUSINF[${$STATUSINFPRESTA{$$refAddData[1]}}[0]]}[0], ${$STATUSINF[${$STATUSINFPRESTA{$$refAddData[1]}}[0]]}[4]]); # 一致定義を取得 } else { @StatusDef = &GetStatusDef([$StatusID, 0]); # 初期一致定義を取得(通常ない) } } my($StaDefItem) = ""; # アイテムデータを格納 while (${$StatusDef[3]}[0] =~ /([ad])(\d+)/g) { if (exists($STATUSDEFITEM{$2})) { $StaDefItem .= "|$1$2"; } # 書式(|(a|d)(ID)) } $refPreStaData = [[($$refAddData[1], $StatusID, $StaDefItem)]]; # 結果を保存 } } my(%PreStaData); my(@PreStaData); my($ResultPreSta) = &FileFormatDataManager($STATUSINFPRESFN, \@PreStaData, "\t", $refPreStaData, sub { my($refSaveData, $refAddData, $refSaveInf, $refTemp) = @_; # 引数([保存データ(参照)], [追加データ], [保存情報], [テンポラリ変数]) if (ref($$refAddData[0]) eq 'ARRAY' && ${$$refAddData[0]}[0] eq 's') { if (${$$refAddData[0]}[1] eq 'c') { # ステータス変更モード時 if ($$refSaveData[0] eq $$refAddData[1] && $$refSaveData[1] ne $$refAddData[2]) { $$refSaveData[1] = $$refAddData[2]; return 1; } } elsif (${$$refAddData[0]}[1] eq 'd') { # ステータス削除モード時 if ($$refSaveData[0] eq $$refAddData[1]) { undef($_[0]); return 1; } } else { # それ以外(通常実行されない) return undef(); # なにも処理しない } if ($$refSaveInf[2] != $$refSaveInf[3]) { return ""; } else { return undef(); } } for (0 .. 1) { if ($$refSaveData[0] eq $$refAddData[0] || $_) { # パスワード一致||最終行(forループ2周目) if ($_) { @$refSaveData = (@$refAddData[0 .. 1], ""); } # 最終行(ダミー雛型生成) # アイテム処理 my(@AddItem) = (); my(@SaveItem) = (); $$refSaveData[2] = "|$$refSaveData[2]"; while ($$refAddData[2] =~ /\|([ad])(\d+)/g) { push(@AddItem, [$1, $2, (time + $DIFTIME)]); } # 分離 while ($$refSaveData[2] =~ /\|(\d+)_(\d+)(_([a-zA-Z]+)?)?(_([a-zA-Z]+)?)?/g) { push(@SaveItem, [$1, $2, ((defined($4)) ? $4 : "")]); } # 分離($6'v'は削除) # ○↓削除期限切れアイテム処理 @SaveItem = grep { (exists($STATUSDEFITEM{$$_[0]}) && ($$_[$#$_] ne 'd' || ${${$STATUSDEFITEM{$$_[0]}}[1]}[1] eq "" || (((time + $DIFTIME) - $$_[1]) < ${${$STATUSDEFITEM{$$_[0]}}[1]}[1]))) } @SaveItem; # 存在アイテム&&(削除アイテム以外||再取得無期限アイテム||削除期限内アイテム)のみにする my(%Exists); for (@SaveItem) { $Exists{$$_[0]} = 1; } # 同じアイテム判別用ハッシュ my($Item); foreach $Item (@AddItem) { # ○↓追加アイテム処理 if ($$Item[0] eq 'a') { if (!exists($Exists{$$Item[1]})) { push(@SaveItem, [@$Item[1 .. $#$Item], "", 'v']); } } # 追加指定を追加(同じ物がなければ)(未表示フラグ追加) } undef(%Exists); # ○↓削除アイテム処理 for (@AddItem) { if ($$_[0] eq 'd') { $Exists{$$_[1]} = 1; } } # 'd'指定判別用ハッシュ foreach (@SaveItem) { if ($$_[2] ne 'd' && (exists($Exists{$$_[0]}) || (!exists($STATUSDEFITEM{$$_[0]}) || (${${$STATUSDEFITEM{$$_[0]}}[1]}[0] ne "" && (((time + $DIFTIME) - $$_[1]) >= ${${$STATUSDEFITEM{$$_[0]}}[1]}[0]))))) { # 削除フラグがなく('d'指定||(未存在アイテム||(有限期限アイテム&&削除期間内アイテム)に(削除フラグ追加))) @$_ = (@$_[0 .. ($#$_ - 2)], (time + $DIFTIME), 'd', 'v'); } } foreach (@SaveItem) { $_ = join('_', @$_); } # 書式に変換 $$refAddData[2] = join('|', @SaveItem); # 処理結果を連結書き換え @$refSaveData = ($$refSaveData[0], @$refAddData[1 .. $#$refAddData]); # パスワードの場所を追加データに書き換え if ($_) { @$refAddData = @$refSaveData; } # 最終行(追加データ書き換え) else { return 1; } # 最終行以外(終了シグナルを返す) } else { if ($$refSaveInf[2] != $$refSaveInf[3]) { last; } # 最終行以外 } } return ""; # ループ持続 } , [], $USEFLOCK); if (!defined($ResultPreSta)) { &EmpFileChk(\"", $STATUSINFPRESFN); } foreach (@PreStaData) { $PreStaData{$$_[0]} = [@$_[1 .. $#$_]]; } undef(%STATUSINFPRESTA); # グローバルを一旦クリア my($StaNum) = 0; # ステータス番号を保存 foreach (@STATUSINF) { # @STATUSINF配列番号変換 if (exists($PreStaData{$$_[1]})) { if (${$PreStaData{$$_[1]}}[0] eq $$_[0]) { $STATUSINFPRESTA{$$_[1]} = [$StaNum, @{$PreStaData{$$_[1]}}[1 .. $#{$PreStaData{$$_[1]}}]]; } # 一致ID時 elsif (${$PreStaData{$$_[1]}}[0] eq "0") { $STATUSINFPRESTA{$$_[1]} = [$#STATUSINF, @{$PreStaData{$$_[1]}}[1 .. $#{$PreStaData{$$_[1]}}]]; } } else { $STATUSINFPRESTA{$$_[1]} = [$#STATUSINF, @{$PreStaData{""}}[1 .. $#{$PreStaData{""}}]]; } # キー未存在時、強制ID0(通常ない) # PASSとID両方一致しない時、強制ID0 $StaNum++; } foreach (keys %STATUSINFPRESTA) { # アイテムリファレンス配列化 my(@AddItem); # 処理したアイテム情報を格納 ${$STATUSINFPRESTA{$_}}[1] = "|${$STATUSINFPRESTA{$_}}[1]"; while (${$STATUSINFPRESTA{$_}}[1] =~ /\|(\d+)_(\d+)(_([a-zA-Z]+)?)?(_([a-zA-Z]+)?)?/g) { push(@AddItem, [$1, $2, ((defined($4)) ? $4 : ""), ((defined($6)) ? $6 : "")]); } ${$STATUSINFPRESTA{$_}}[1] = \@AddItem; } &$refSetSelectedStatus(); # $SELECTEDSTATUSセット # 現ステータス情報処理ここまで # # # # ★備考★ # $STATUSINF[0 .. ID0情報の添え字] = [STA_ID, PASS, NAME, TIME, TTLPT, [PT...]] # ←@STATUSINF構造(ファイル行順) # $STATUSINFPRESTA{PASS} = [@STATUSINF配列の添え字, [[ITEM_ID, ITEM_TIME, F_DEL, F_VIEW]...]] # ←%STATUSINFPRESTA構造 return [$ResultSta, $ResultPreSta]; # [ステータス情報結果, 現ステータス情報結果] } sub ManageViewUpFile { # アップファイル表示情報を管理します if (!$USEVIEWUPFILEMANAGER) { return; } # 無管理指定時 my($refAddData) = @_; # 引数([追加データ](省略時は取得のみ)) if (ref($refAddData) eq 'SCALAR') { # ○削除指定時 my %refExists_d; foreach (@VIEWUPFILEINF) { my $ObjFN = ""; if ($$_[1] ne "") { if ($$_[0] eq 'd') { unless (exists($refExists_d{$$_[1]})) { $refExists_d{$$_[1]} = [&DataFormatEx($$_[1])]; } foreach my $DataInf (@{$refExists_d{$$_[1]}}) { if ($$DataInf[0] ne "" && $$_[2] eq $$DataInf[0]) { $ObjFN = $$DataInf[9]; } } } elsif ($$_[0] eq 'i') { if (exists($IconInfID{$$_[1]})) { $ObjFN = ${$IconInf[$IconInfID{$$_[1]}]}[2]; } } elsif ($$_[0] eq 'b') { if (exists($BgsInfID{$$_[1]})) { $ObjFN = ${$BgsInf[$BgsInfID{$$_[1]}]}[2]; } } } if ($ObjFN ne "" && -w "$ObjFN$ExData") { rename("$ObjFN$ExData", $ObjFN); } } if (unlink($VIEWUPFILEINFFN)) { @VIEWUPFILEINF = (); }; # ファイルを削除してクリア更新(あれば) } else { # ○追加指定時 my $fProc; if (ref($refAddData) eq 'ARRAY') { $refAddData = [$refAddData]; $fProc = 1; } # 引数指定 elsif (-w $VIEWUPFILEINFFN) { $fProc = 1; } # 引数省略 if ($fProc) { if (!defined(&FileFormatDataManager($VIEWUPFILEINFFN, \@VIEWUPFILEINF, "\t", $refAddData, sub { my($refSaveData, $refAddData) = @_; # 引数([保存データ], [追加データ]) if ($$refSaveData[0] eq $$refAddData[0] && $$refSaveData[1] eq $$refAddData[1] && $$refSaveData[2] eq $$refAddData[2]) { # モード&記事&返信ナンバー一致時 return 1; # 終了シグナルを返す } return ""; # ループ持続 } , "", $USEFLOCK)) ) { &EmpFileChk(\"", $VIEWUPFILEINFFN); } # ファイルが空の時のエラー処理 } } return 1; } sub ManageThreadInf { my($refGetThreadInf, $Mode, $refAddData) = @_; # 引数(\@取得変数, モード, [[追加データ]..]) my @Param; if ($Mode eq 'get') { @Param = ("", ""); } elsif ($Mode eq 'add') { if ($MAXRSVTHREADINF eq "") { @Param = ($refAddData, ""); } else { @Param = ($refAddData, sub { my($refSaveData, $refAddData, $refSaveInf, $refTemp) = @_; if ($$refSaveInf[2] + 1 >= $MAXRSVTHREADINF) { undef($_[0]); return 2; } return 0; } ); } } elsif ($Mode eq 'edt' || $Mode eq 'del') { my $fMode = ($Mode eq 'edt'); @Param = ($refAddData, sub { my($refSaveData, $refAddData, $refSaveInf, $refTemp) = @_; if ($$refSaveData[0] == $$refAddData[0]) { if ($fMode) { foreach (0 .. $#$refAddData) { if ($_ == 2) { $$refSaveData[$_] += $$refAddData[$_]; } elsif ($$refAddData[$_] ne "") { $$refSaveData[$_] = $$refAddData[$_]; } } } else { undef($_[0]); } return 1; } if ($$refSaveInf[2] == $$refSaveInf[3]) { return; } # 最終行 return 0; } ); } else { return; } my $Result = &FileFormatDataManager($THREADINFFN, $refGetThreadInf, "\t", @Param[0 .. 1], "", $USEFLOCK); if (!defined($Result)) { &EmpFileChk(\"", $THREADINFFN); } return $Result; } sub JudgeSwUnjustPass { # 不正パス連続入力エラー処理('SAVE'のみの呼び出しは×(一致した時、キャンセルされる為)) # 引数((偽:GET|真:SAVE), エラーコード, PASS(エラーコードに使用)) my($OverNum, $OverSec, $ErrMes) = &OverAccessNum($SWIPLOGFNMSPS, $SWLIMITNUMMSPS, $SWLIMITSECMSPS, (($_[0]) ? 1 : ""), $USEFLOCK, (time + $DIFTIME)); # オーバーアクセス数を取得(オーバーしていれば)(引数が不正の時も処理される) if ($ErrMes eq 'Err_EmpFile') { &EmpFileChk(\"", $SWIPLOGFNMSPS); } # 同時アクセスした時 if ($OverNum > 0) { # オーバーした時、エラーメッセージページを表示 $ERR_CODE = "SW_PASS_$_[1](" . ($LimitNum + $OverNum) . "): \"$_[2]\""; # エラーコードを格納する &ViewFormErr("$BBSTITLENAME <エラー:連続アクセス禁止>", "", 'エラー:連続アクセスは禁止されています。
しばらくしてからアクセスして下さい。
', 1); # エラーメッセージフォーム表示 } return ($OverNum, $OverSec, $ErrMes); } sub ExFullPath { # フルパスに変換 my($FilePath) = @_; if ($DIRPATHWEB ne $REGAUTOABSPATH) { &VarExAbsolutePath([\$FilePath]); } elsif ($FilePath =~ s/^.\///) { $FilePath = (&DataDec::GetMyUrl('c') . $FilePath); } return $FilePath; }; 1;