#!/usr/local/bin/perl #↑perlまでのパスを指定(わからない場合はプロバイダに確認する) #〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜# #Copyright(C)1999 ohtan. All rights reserved. # #CmfCounter ver4.3 # #製作日:1999/12/6 # #更新日:2000/6/29 # # HOME:Counter Material Factory # # http://www.din.or.jp/~ohtan/ # # MAIL:ohtan@din.or.jp # #〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜# #-------------------------設定項目-------------------------- #1.カウンターの桁数(この桁数をカウント数値が超えた時はカウント数値の桁数で表示) $keta = 6; #2.不正使用防止機能を(0:使う/1:使わない) $def = 1; #3.2を「使う」にした場合カウンターを表示するページのURLを指定(複数設置の時は下記のように「,」で区切って指定) @URL = ('http://...','http:/...'); #4.ファイルロック(flock関数)を(0:使う/1:使わない)未対応サーバーでは必ず1を指定 $f_lock = 1; #5.同日中に同一IPがアクセスした場合のカウントアップ(0:する/1:しない) $up = 1; #6.カウンターを複数のページに設置する場合それぞれ別のGIF画像を使用(0:する/1:しない) $gifimg = 1; #7.ロックファイル監視用ディレクトリ(通常は変更不要) $lockdir = './lock/'; #8.GIF画像格納用ディレクトリ(通常は変更不要) $imgdir = './images/'; #--------------------以下はperlの知識が必要----------------- #------------------------メイン処理------------------------- require './gifcat.pl'; $home = $ENV{'HTTP_REFERER'}; $name = $ENV{'QUERY_STRING'}; $addr = $ENV{'REMOTE_ADDR'}; $addr =~ s/\.//g; $lockn = "$name\.tmp"; $tmpfile = "$lockdir$addr$lockn"; $getcnt = $name."cnt.dat"; $gettim = $name."time.txt"; if (!$def) { if (!grep($home =~ /$_/i,@URL)) { &Error(1); } } &LockFile; if ($up) { &Check; } else { &CntUp; } #-----------------ロックファイルのチェック------------------ sub LockFile { &LockList; if (grep(/$lockn/,$dirchk)) { for ($retry = 0; $retry <= 5; $retry++) { sleep(1); &LockList; if (!grep(/$lockn/,$dirchk)) { last; } if ($retry == 5) { &LockList; @TMP = split(/\s+/,$dirchk); foreach $tmp (@TMP) { $ltime = (stat("$lockdir$tmp"))[9]; $ntime = time - 30; if ($ltime < $ntime) { unlink "$lockdir$tmp" || &Error(4); } } &LockList; if (grep(/$lockn/,$dirchk)) { &Error(2); } else { last; } } } } open(FLAG, ">$tmpfile") || &Error(3); close(FLAG); chmod(0666, "$tmpfile"); } sub LockList { $dirchk = `ls $lockdir$ls`; } #----------------------IPアドレスのチェック----------------- sub Check { if (!-e $gettim) { &TimeLog; } $last = (localtime( (stat($gettim))[9] ))[3]; $today = (localtime(time))[3]; if ($last != $today) { unlink "$gettim" || &Error(10); &TimeLog; } open(TLOG, "<$gettim") || &Error(11); $l = 0; while ($_ = ) { chop; $IP[$l] = "$_"; $l++; } close(TLOG); $iplist = grep /$addr/, @IP; if (!$iplist) { open(RTIP, ">>$gettim") || &Error(12); print RTIP "$addr\n" || &Error(12); close(RTIP); &CntUp; } else { &NoCnt; } } sub TimeLog { open(TIME, ">$gettim") || &Error(9); print TIME "$addr\n" || &Error(9); close(TIME); &CntUp; } #----------------------カウント数値取得--------------------- sub CntUp { &MakeCnt; open(WRITE, ">$tmpfile") || &Error(8); if (!$f_lock) { eval'flock(WRITE,2);'; } $count++; seek(WRITE, 0, 0); print WRITE "$count\n" || &Error(8); if (!$f_lock) { eval'flock(WRITE,8);'; } close(WRITE); rename("$tmpfile", "$getcnt") || &Error(5); &OutImage; } sub NoCnt { &MakeCnt; unlink "$tmpfile" || &Error(4); &OutImage; } sub MakeCnt { if (!-e $getcnt) { open(MAKE, ">$getcnt") || &Error(6); print MAKE "0\n" || &Error(6); close(MAKE); chmod(0666,"$getcnt"); } open(READ, "<$getcnt") || &Error(7); $count = ; if ($count =~ /\n$/) { chop $count; } close(READ); } #-----------------------画像出力処理------------------------ sub OutImage { if ($keta < length($count)) { $digit = $count; } else { $digit = sprintf("%0$keta\d",$count); } @DIGIT = split(//, $digit); $i = 0; foreach (@DIGIT) { if ($gifimg) { $IMGF[$i] = "$imgdir$_.gif"; } else { $IMGF[$i] = "$imgdir$name$_.gif"; } $i ++; } binmode(STDOUT); print "Content-type: image/gif\n\n"; print &gifcat'gifcat(@IMGF); exit; } #--------------------エラー画像出力処理--------------------- sub Error { $ername = 'error'; $ERR[0] = "$imgdir$ername$_[0].gif"; if (-e $tmpfile) { unlink "$tmpfile"; } binmode(STDOUT); print "Content-type: image/gif\n\n"; print &gifcat'gifcat(@ERR); exit; } #error1(設定URLエラー) #error2(ビジー状態) #error3(ロックファイルオープンエラー) #error4(ロックファイルクローズエラー) #error5(ロックファイルリネームエラー) #error6(カウントログ作成エラー) #error7(カウント数値読込みエラー) #error8(カウント数値書込みエラー) #error9(タイムログ作成エラー) #error10(タイムログ削除エラー) #error11(タイムログ読込みエラー) #error12(タイムログ書込みエラー)