#!/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 "\"$NUM\""; } } }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) }