#!/usr/bin/perl
# ↑あなたのプロバイダの PERL5 のパスを記述します
# ↓この1行は書き換えないで下さい。
$CONF{CONF_MODE} = 'risque';
############################################################
# 設定項目、開始
############################################################
# -----------------------------------------
# ここで言う「フルパス」の意味は?
# -----------------------------------------
# 正:/home/user/public_html/cgi-bin/...
# 誤:http://...
# -----------------------------------------
# 設定ファイルを読み込みます
require './rssss.pl'; # (フルパスだと確実)
############################################################
# 設定項目終了
############################################################
# 以上で設定は終わりです
# #################################################################### #
$LOCKFILE = $DATA_DIR.'delete_me_plz';
$FILE_CHK = $DATA_DIR.'acc_list.txt';
$FILE_C = $DATA_DIR.'acc_count.txt';
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# ----------------------- // メインルーチン
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# ----------------------- // SSI ではない場合、IMG画像を出力する
unless( $DEBUG ){
&print_img unless $SSI;
}
# ----------------------- // データを取得する
&get_ur_data;
# ----------------------- // TIME,年,月 を取得する
($TIME, $year, $mon, $today) = &get_time;
# ----------------------- // 指定時間内の再訪問か、判別する
$FLAG = &time_check( $KEIKA_JIKAN );
if( $FLAG ){
# 1回目のアクセス
if( $LOCK ){ &FILE_LOCK; } # ロック開始
$COUNT = &COUNT_UP;
if( $LOCK ){ unlink($LOCKFILE); } # ロック解除
}else{
# 2回目以降のアクセス
$COUNT = &COUNT_NO;
}
if( $CONF{SSI_COUNT} && $SSI ){
if( $CONF{SSI_COUNT_IMG} == 0 ){
print "Content-type: text/plain\n\n";
print "";
print $COUNT."\n";
}elsif( $CONF{SSI_COUNT_IMG} == 1 ){
print "Content-type: text/plain\n\n";
print "";
foreach $NUM ( split(//,$COUNT) ){
print "
";
}
}
}elsif( $SSI ){
print "Content-type: text/plain\n\n";
print "";
}
# ----------------------- // 指定時間内の再訪問
# 指定時間以内の場合、終了する
exit(0) unless $FLAG;
# ----------------------- // ログデータ保存用ファイル名を生成する
&make_file_name( $year, $mon );
# ----------------------- // データを保存する
if( $LOCK ){ &FILE_LOCK; } # ロック開始
&print_data( $FILE_URL, $URL ) if $URL;
&print_data( $FILE_AGENT, $AGENT ) if $AGENT;
&print_data( $FILE_HOST, $HOST ) if $HOST;
&print_data( $FILE_KEY, $KEY ) if $KEY;
# $COUNT = &COUNT_UP if $FLAG;
&ADD_HOST( $MAX ) if $FLAG;
&ADD_HOSTLOG if $FLAG;
if( $LOCK ){ unlink($LOCKFILE); } # ロック解除
# ----------------------- // 終了する
exit(0);
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# ----------------------- // 以下サブルーチン
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# ----------------------- // 各種データの取得
sub get_ur_data{
if( $SSI ){
# SSI の場合の処理
$URL = $ENV{'HTTP_REFERER'};
}else{
# IMG の場合の処理
$URL = $ENV{QUERY_STRING};
$URL =~ s/__QUESTION__/\?/;
$URL =~ s/^URL=//i;
}
( $URL, $DATA ) = split( /\?/, $URL);
$URL =~ s/%7E/~/i;
if( $DEBUG ){ if( $HOME_URL ){ print "自ページ内の移動です\n" if $URL =~ /^$HOME_URL/i; } }
if( $HOME_URL ){ exit(0) if $URL =~ /^$HOME_URL/i; }
if( $KINSI[0] ){ $URL = 0 if $URL =~ /^$KINSI[0]/i; }
if( $KINSI[1] ){ $URL = 0 if $URL =~ /^$KINSI[1]/i; }
if( $KINSI[2] ){ $URL = 0 if $URL =~ /^$KINSI[2]/i; }
if( $KINSI[3] ){ $URL = 0 if $URL =~ /^$KINSI[3]/i; }
if( $KINSI[4] ){ $URL = 0 if $URL =~ /^$KINSI[4]/i; }
# // $KEY -> engine + keyword
if( $DATA ){
( $ENGINE, $KEYWORD ) = &get_keyword( $DATA );
if( $ENGINE && $KEYWORD ){
$KEY = $KEYWORD."\t".$ENGINE;
}else{
$KEY = 0;
# サーチエンジン以外だった場合は ? 以降の文字も保存する
if( $CONF{'URL_ZENBUHOZON'} == 1 ){
$URL .= '?' . $DATA;
$URL =~ tr/+/ /;
$URL =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
}
}
}
# ? 以降の文字も全部保存する
if( $CONF{'URL_ZENBUHOZON'} == 2 && $DATA ){
$URL .= '?' . $DATA;
$URL =~ tr/+/ /;
$URL =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
}
# // $AGENT -> user agent
$AGENT = $ENV{'HTTP_USER_AGENT'};
# // $HOST -> host
$HOST = &IP;
if( $CONF{IP2HOST} == 1 ){
$HOST =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
$TEMP = "$1.$2.$3.";
open( LIST, $IP2HOST_FILE );
foreach $LINE ( ){
if( $LINE =~ /^$TEMP\s.*/ ){
chomp($LINE);
$HOST = ( split(/\s/,$LINE))[1];
last;
}
}
}
}
# ----------------------- // 検索キーワードとケンサクエンジンを返す
#
# %SEARCH の値を増やせばいろいろな検索エンジンに対応できる
# 例: $SERRCH{'検索エンジンURL'} = '検索文字を格納する「キー」'
sub get_keyword{
my( $n, $key, $value, $temp, %SEARCH, %KEY );
my $ENGINE = 0;
my $KEYWORD = 0;
my $DATA = $_[0];
# 2000.11.8 add, けん様情報ありがとうございました☆
$SEARCH{'http://search.dragon.co.jp'} = 'query'; # Dragon Next
$SEARCH{'http://www.excite.co.jp'} = 's'; # excite
$SEARCH{'http://odn.excite.co.jp'} = 'search'; # excite
$SEARCH{'http://excite.co.jp'} = 'search'; # excite
$SEARCH{'http://excite.jp.netscape.com'} = 'search'; # excite
$SEARCH{'http://aol.excite.co.jp'} = 'search'; # excite
$SEARCH{'http://jp.excite.com/'} = 'search'; # excite
$SEARCH{'http://search.fresheye.com'} = 'kw'; # FreshEye
$SEARCH{'http://www.google.com'} = 'q'; # google
$SEARCH{'http://www.goo.ne.jp'} = 'MT'; # goo
$SEARCH{'http://goo.ne.jp'} = 'MT'; # goo
$SEARCH{'http://search.mycom.co.jp'} = 'a1'; # GotCha
$SEARCH{'http://www.hole-in-one.com'} = 's'; # Hole-in-One(excite?)
$SEARCH{'http://www.infoseek.co.jp'} = 'qt'; # infoseek
$SEARCH{'http://japan.infoseek.com'} = 'qt'; # infoseek
$SEARCH{'http://para.cab.infoweb.ne.jp'} = 'Querystring'; # InfoNavigator
$SEARCH{'http://inetg.com'} = 'key'; # iNET Guide
$SEARCH{'http://search.netjoy.ne.jp'} = 'key'; # JOY
$SEARCH{'http://kensaku.org'} = 'key'; # kensaku
$SEARCH{'http://www.lycos.co.jp'} = 'query'; # Lycos
$SEARCH{'http://search2.jp.msn.com'} = 'qt'; # MSN
$SEARCH{'http://search.msn.co.jp'} = 'q'; # MSN
$SEARCH{'http://beta.search.msn.co.jp'} = 'q'; # MSN BETA
$SEARCH{'http://kuamp.kuamp.kyoto-u.ac.jp'} = 'key'; # MONDOU
$SEARCH{'http://rex1.netplaza.biglobe.ne.jp'} = 'key'; # Netplaza
$SEARCH{'http://websearch.rd.nacsis.ac.jp'} = 'Query'; # NACSIS
$SEARCH{'http://search.navi.ocn.ne.jp'} = 'kw'; # OCN navi
$SEARCH{'http://navi.ocn.ne.jp'} = 'keyword'; # OCN navi
$SEARCH{'http://search.odn.ne.jp'} = 'query'; # ODN
$SEARCH{'http://www.orions.ad.jp'} = 'search_term'; # ORIONS
$SEARCH{'http://odin.ingrid.org'} = 'key'; # ODiN
$SEARCH{'http://www.surpara.ne.jp'} = 'search'; # Surfersparadice
$SEARCH{'http://www2.surpara.com'} = 'search'; # Surfersparadice
$SEARCH{'http://search.surpara.ne.jp'} = 'search'; # Surfersparadice
$SEARCH{'http://www.marunaka.com'} = 'key'; # STRAIGHT FLASH!!
# $SEARCH{'http://www.tamon.co.jp'} = 'word'; # TINAMI
$SEARCH{'http://www.tinami.com'} = 'word'; # TINAMI
$SEARCH{'http://verno.ueda.info.waseda.ac.jp'}= 'index-and'; # Verno
$SEARCH{'http://www.wave.co.jp'} = 'keyword'; # Wave
$SEARCH{'http://www.webring.ne.jp'} = 'ring'; # webring
$SEARCH{'http://search.yahoo.co.jp'} = 'p'; # yahoo
# 海外
$SEARCH{'http://www.altavista.com'} = 'q'; # AltaVista
$SEARCH{'http://search.aol.com'} = 'query'; # AOL
$SEARCH{'http://search.excite.com'} = 'search'; # excite
$SEARCH{'http://www.bos2.alltheweb.com'} = 'query'; # FAST
$SEARCH{'http://beta.go.com'} = 'qt'; # GO
$SEARCH{'http://hotbot.lycos.com'} = 'MT'; # HotBot
$SEARCH{'http://www.lycos.com'} = 'query'; # lycos
$SEARCH{'http://www.northernlight.com'} = 'qr'; # Northern
$SEARCH{'http://www.seed.net.tw'} = 'query'; #
$SEARCH{'http://search.yahoo.com'} = 'p'; # YAHOO
# まず、GETメソッドデータ「キー・値」を全て読み込む。
foreach( split( /\&/, $DATA) ){
($key, $value) = split(/=/, $_ );
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$KEY{$key} = $value;
}
# 検索エンジンがどこか確定し、検索キーを取得する。
foreach( keys( %SEARCH ) ){
if( $URL =~ /^\Q$_\E.*/i ){
$ENGINE = $_;
$temp = $SEARCH{$ENGINE};
$KEYWORD = $KEY{$temp};
last;
}
}
# 検索キー を取得出来ていれば、EUC に変換する
if( $KEYWORD ){
require './jcode.pl';
&jcode'convert( \$KEYWORD, 'euc' );
}
($ENGINE, $KEYWORD);
}
# ----------------------- // IP アドレスを取得し、ホスト名に変換して返す。
# ( Proxy 経由でも可能な限り IP を取得しようとする)
sub IP{
my( $IP, $name, $aliase, $type, $no, @addr);
$IP = $ENV{'REMOTE_HOST'};
$IP = $ENV{'REMOTE_ADDR'} unless $IP;
if( $ENV{'HTTP_X_FORWARDED_FOR'} =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/ ){
$IP = "$1.$2.$3.$4";
}elsif( $ENV{'HTTP_CACHE_INFO'} =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
$IP = "$1.$2.$3.$4";
}elsif( $ENV{'HTTP_FROM'} =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
$IP = "$1.$2.$3.$4";
}elsif( $ENV{'HTTP_SP_HOST'} =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
$IP = "$1.$2.$3.$4";
}elsif( $ENV{'HTTP_VIA'} =~ m/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
$IP = "$1.$2.$3.$4";
}elsif( $ENV{'HTTP_FORWARDED'} =~ m/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
$IP = "$1.$2.$3.$4";
}
if( $IP =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/ ){
($i1,$i2,$i3,$i4) = split(/\./,$IP);
my $p_name = pack("CCCC",$i1,$i2,$i3,$i4);
($name, $aliase, $type, $no, @addr) = gethostbyaddr($p_name, 2);
}
$name = $IP unless $name;
return $name;
}
# ----------------------- // ファイルにデータを保存します。
#
# 第1引数:ファイル名
# 第2引数:データ
sub print_data{
my $LOG_FILE = $_[0];
my $DATA = $_[1];
my( $n );
if ( $DATA ){
open( DST, ">>$LOG_FILE" );
print DST "$TIME\t$DATA\n"; # 保存する。
close(DST);
}
}
# ----------------------- // アクセスログ
sub ADD_HOSTLOG{
open( CHK,">>$FILE_LOG" );
print CHK $TIME."\t".$HOST."\t".$COUNT.".hit\t<= ".$today."\n";
close(CHK);
}
# ----------------------- // 時間とホスト名を保存します。
# リロードチェック用の履歴ログです
#
# 第1引数:最大保存件数(数)
sub ADD_HOST{
my( @LIST );
my $c = 0;
my $MAX_LOG = $_[0]; $MAX_LOG -= 2;
open( CHK,"$FILE_CHK" );
@LIST = ;
$LIST_NO = @LIST;
close(CHK);
open( CHK,">$FILE_CHK" );
print CHK $TIME."\t".$HOST."\t".$COUNT.".hit\t<= ".$today."\n";
for($c = 0; $c <= $MAX_LOG; $c++){
print CHK "$LIST[$c]" if $LIST[$c];
}
close(CHK);
}
# 指定時間内に、同じホストからアクセスがあったかどうかをチェックする。
# アクセスがあった場合 0 を返す。
# アクセスが無かった場合 1 を返す。
#
# 第1引数:時間(秒)
sub time_check{
my $LIMIT = $_[0];
my $FLAG = 1;
open( CHK,"$FILE_CHK" );
while( ){
chomp();
( $TIME_SRC, $HOST_SRC, ) = split(/\t/,$_);
# IP が一致したら・・・
if( $HOST eq $HOST_SRC ){
# リロードと判定するなら 0 をセット
$FLAG = 0 if ($TIME - $TIME_SRC) < $LIMIT;
}
}
close(CHK);
$FLAG;
}
# ----------------------- // カウントアップして、その結果の数を返す
sub COUNT_UP{
my $NO = 0;
open( COUNT,"$FILE_C" );
$NO = ;
chomp( $NO );
$NO++;
close(COUNT);
open( COUNT,">$FILE_C" );
print COUNT $NO;
close(COUNT);
$NO;
}
# ----------------------- // 現在のカウント数を返す
sub COUNT_NO{
open( COUNT,"$FILE_C" );
my $NO = ;
chomp( $NO );
close(COUNT);
$NO;
}
# ----------------------- // 画像を出力する
# あらかじめ $image に画像ファイル、$imgtype に jpeg or gif を
# 設定しておかなければならない。
sub print_img{
if( $image =~ /^http/ ){
print "Location: $image\r\n\r\n";
}else{
if( open( IMG, $image ) ){
$size = ( stat($image) )[7];
print "Content-type: image/$imgtype","\n";
print "Content-length: $size","\n\n";
print
;
}else{
print "Content-type: image/$imgtype","\n";
print "Status: 204 No Response\n\n";
}
}
}
sub get_time{
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);
my $TIME = time;
$TIME += $CHOUSEI;
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( $TIME );
$mon = ($mon + 1);
$year= $year + 1900;
if ($mon < 10) { $mon = "0$mon"; }
if ($mday < 10) { $mday = "0$mday"; }
if ($hour < 10) { $hour = "0$hour"; }
if ($min < 10) { $min = "0$min"; }
if ($sec < 10) { $sec = "0$sec"; }
my $today = "$year/$mon/$mday $hour:$min:$sec";
($TIME, $year, $mon, $today);
}
sub make_file_name{
my $YEAR = $_[0];
my $MON = $_[1];
$FILE_URL = $DATA_DIR."$YEAR.$MON.url.txt";
$FILE_AGENT = $DATA_DIR."$YEAR.$MON.agent.txt";
$FILE_HOST = $DATA_DIR."$YEAR.$MON.host.txt";
$FILE_KEY = $DATA_DIR."$YEAR.$MON.key.txt";
$FILE_LOG = $DATA_DIR."$YEAR.$MON.log.txt";
}
sub FILE_LOCK{
local($retry) = 3;
while (!symlink(".", $LOCKFILE)) {
if (--$retry <= 0) { unlink($LOCKFILE); exit; }
sleep(1);
}
}
sub error{
my $msg = '何らかのエラーで終了しました';
print "Content-type: text/plain\n\n";
print $msg;
exit(0)
}