#!/usr/local/bin/perl # ↑あなたのプロバイダの PERL5 のパスを記述します $|=1; # ↓この1行は書き換えないで下さい。 $CONF{'CONF_MODE'} = 'safety'; ############################################################ # 設定項目、開始 ############################################################ # ------------------------------------------------ # 設定ファイルを読み込みます # ------------------------------------------------ $RSSSS_PL = './rssss.pl'; # ------------------------------------------------ # 日本語コード変換ルーチンファイルの場所 # ------------------------------------------------ $JCODE_PL = './jcode.pl'; # ------------------------------------------------ # timelocal.pl ファイルの場所 # ------------------------------------------------ $TIMELOCAL_PL = './timelocal.pl'; # ------------------------------------------------ # バージョンアップ情報取得用ルーチンファイルの場所 # ------------------------------------------------ $VER_INFO_PL = './ver_info.pl'; # ------------------------------------------------ # このファイルの場所(URL) # ------------------------------------------------ $FORM_ACTION = './safety.cgi'; ############################################################ # 設定項目終了 ############################################################ # ------------------------------------------------ # エラーチェック # ------------------------------------------------ if( -f $RSSSS_PL ){ require $RSSSS_PL; }else{ print "Content-type: text/html\r\n\r\n"; print <<__STRING__; $RSSSS_PL ファイルが見つかりません safety.cgi の実行には $RSSSS_PL が必要です __STRING__ exit(); } if( -f $JCODE_PL ){ require $JCODE_PL; }else{ print "Content-type: text/html\r\n\r\n"; print <<__STRING__; $JCODE_PL ファイルが見つかりません safety.cgi の実行には $JCODE_PL が必要です __STRING__ exit(); } if( $NO_SOCKET == 0 ){ if( -f $VER_INFO_PL ){ require $VER_INFO_PL; }else{ print "Content-type: text/html\r\n\r\n"; print <<__STRING__; $VER_INFO_PL ファイルが見つかりません safety.cgi の実行には $VER_INFO_PL が必要です __STRING__ exit(); } } # ---------------------------------------------------------- # ベンチマークモードです。キャッシュ効果の測定にどうぞ(笑) # ---------------------------------------------------------- # 左上に実行時間(秒数)が表示されるようになります。 # on:1 off:0 $CONF{BENCH} = 0; $CONF{'SOCKET'} = $ver_info_required; # -------------// バージョン告知用設定 $CONF{'THIS_VER'} = '1.2.3'; $CONF{'VER_HOST'} = 'www.acc.ne.jp'; $CONF{'VER_URI'} = '/~pastel/cgi-lab/.rssss_ver.txt'; $CONF{'USER_URI'} = '/~pastel/cgi-bin/rssss/rssss_url.cgi'; # -------------// Copyright $COPYRIGHT = <<__STRING__; - R&S Statistics Structure System -
__STRING__ # -----------// メインルーチン &getdata; &DATE; $CONF{URL_LEN}= $FORM{URL_LEN} if $FORM{URL_LEN}; $CONF{URL_LEN}= 999 if $CONF{URL_LEN} >= 1000; $CONF{ADDR_SHORT}= $FORM{ADDR_SHORT}; &make_file_name( $FORM{'YEAR'}, $FORM{'MON'} ); &set_agent_name; if( $FORM{'VIEW'} ){ if( -f $TIMELOCAL_PL ){ require $TIMELOCAL_PL; }else{ print "Content-type: text/html\r\n\r\n"; print <<__STRING__; timelocal.pl ファイルが見つかりません safety.cgi の実行には timelocal.pl が必要です __STRING__ exit(); } my $YEAR = $FORM{'YEAR'} -1900; my $MON = $FORM{'MON'} -1; my $MDAY = $FORM{'MDAY'}; my $MDAYz= $FORM{'MDAYz'}; $TIME_START = &timelocal( 0, 0, 0, $MDAY , $MON, $YEAR); $TIME_END = &timelocal( 0, 0, 0, $MDAYz, $MON, $YEAR); $TIME_END += 86400; if( $TIME_START > $TIME_END ){ # 開始日〜終了日 を逆に入力してもちゃんと認識してあげる $TIME_END -= 86400; $TIME_START += 86400; $TEMP = $TIME_END; $TIME_END = $TIME_START; $TIME_START = $TEMP; } } $BENCH{'T_STR'} = time if $CONF{'BENCH'} == 1; &read_data( 'AGE', $FILE_AGENT, 'agent' ) if $FORM{'AGE'}; &read_data( 'OS', $FILE_AGENT, 'agent' ) if $FORM{'OS'}; &read_data( 'KT', $FILE_AGENT, 'ktai_cut' ) if $FORM{'KT'}; &read_data( 'VER', $FILE_AGENT, 'agent_ver' ) if $FORM{'VER'}; &read_data( 'KEY', $FILE_KEY , 'keyword_cut' ) if $FORM{'KEY'}; &read_data( 'URL', $FILE_URL , 0 ) if $FORM{'URL'}; &read_data( 'HOS', $FILE_HOST , 'ppp_cut' ) if $FORM{'HOS'}; &read_data( 'CNT', $FILE_HOST , 'country_cut' ) if $FORM{'CNT'}; &log_count( $FILE_LOG ) if $FORM{'DAY'} || $FORM{'TIME'}; &read_cache( 'AGE' ) if $FORM{'AGE'}; &read_cache( 'OS' ) if $FORM{'OS'}; &read_cache( 'KT' ) if $FORM{'KT'}; &read_cache( 'VER' ) if $FORM{'VER'}; &read_cache( 'KEY' ) if $FORM{'KEY'}; &read_cache( 'URL' ) if $FORM{'URL'}; &read_cache( 'HOS' ) if $FORM{'HOS'}; &read_cache( 'CNT' ) if $FORM{'CNT'}; $BENCH{'T_END'} = time if $CONF{'BENCH'} == 1; $BENCH{'T_ANS'} = $BENCH{'T_END'} - $BENCH{'T_STR'} if $CONF{'BENCH'} == 1; if( $CONF{CACHE_USE} == 1 ){ &save_cache( 'AGE' ) if $FORM{'AGE'}; &save_cache( 'OS' ) if $FORM{'OS'}; &save_cache( 'KT' ) if $FORM{'KT'}; &save_cache( 'VER' ) if $FORM{'VER'}; &save_cache( 'KEY' ) if $FORM{'KEY'}; &save_cache( 'URL' ) if $FORM{'URL'}; &save_cache( 'HOS' ) if $FORM{'HOS'}; &save_cache( 'CNT' ) if $FORM{'CNT'}; } if( $ENV{'HTTP_ACCEPT_ENCODING'}=~/gzip/ && $CONF{'GZIP'} == 1 ){ print "Content-type: text/html\r\n"; print "Content-encoding: gzip\r\n\r\n"; open(STDOUT,"| $CONF{'GZIP_PATH'}"); }else{ print "Content-type: text/html\r\n\r\n"; } print <<__STRING__; $CONF{'TITLE'} __STRING__ # ベンチ関係の表示 if( $CONF{'BENCH'} == 1 ){ $CACHE{'MISS'} = 0 if $CACHE{MISS} eq ''; $CACHE{'HIT'} = 0 if $CACHE{HIT} eq ''; $CACHE{'ALL'} = 1 unless $CACHE{ALL}; $CACHE{'PAR'} = int( 0.5 + (( 100 * $CACHE{HIT} ) / $CACHE{ALL} ) * 10 ) / 10; $CACHE{'PAR'} .= '.0' if $CACHE{'PAR'} !~ /\./ && $CACHE{'PAR'} < 100; print ''; print "キャッシュ使用率:$CACHE{'PAR'}% (HIT:$CACHE{HIT}/MISS:$CACHE{MISS}/ALL:$CACHE{ALL})
"; print "データ集計時間:$BENCH{'T_ANS'}秒
"; print '
'; } # キャッシュの削除 if( $FORM{CACHE_MODE} == 9 ){ ($CACHE_DELETED, $CACHE_DELETED_SIZE) = &delete_cache( $CACHE_DIR ); if( $CACHE_DELETED ){ my $CACHE_DELETED_SIZE_conma = &add_conma($CACHE_DELETED_SIZE); print ''; print $CACHE_DELETED.'個('.$CACHE_DELETED_SIZE_conma.'byte) のキャッシュファイルを削除しました
'; print '
'; }else{ print 'キャッシュファイルはありません
'; } } print '
'; if( $CONF{'PASSWORD'} ne '' && $CONF{'PASSWORD'} ne $FORM{'PASSWORD'}){ &print_form_password; }elsif( $CONF{'PASSWORD'} ne '' && $CONF{'PASSWORD'} eq $FORM{'PASSWORD'}){ &print_form_1; }elsif( $CONF{'PASSWORD'} eq '' ){ &print_form_1; } if( $FORM{'VIEW'} ){ # if( $URL|$AGE|$VER|$OS|$HOS|$KEY|$DAY ){ &list; } if( $URL|$AGE|$HOS|$KEY|$DAY ){ &list; } # ---------------------------------------------------------------------------- # ● 改造ポイント ● # 表示順を変えたい場合は以下の行の順番を変えて下さい。 # ---------------------------------------------------------------------------- if($FORM{'OS'} ){ print "
環境" ;&make_data( 'OS', $CONF{GRAPH_MAX}, $CONF{OS_MAX_V} );} if($FORM{'AGE'}){ print "
ブラウザ" ;&make_data( 'AGE', $CONF{GRAPH_MAX}, $CONF{AGE_MAX_V} );} if($FORM{'KT'} ){ print "
携帯" ;&make_data( 'KT', $CONF{GRAPH_MAX}, $CONF{KT_MAX_V} );} if($FORM{'VER'}){ print "
バージョン" ;&make_data( 'VER', $CONF{GRAPH_MAX}, $CONF{VER_MAX_V} );} if($FORM{'KEY'}){ print "
検索キーワード" ;&make_data( 'KEY', $CONF{GRAPH_MAX}, $CONF{KEY_MAX_V} );} if($FORM{'TIME'}){print "
時間別アクセス" ;&make_data_log('TIME',$CONF{GRAPH_MAX},$CONF{TIME_MAX_V});} if($FORM{'DAY'}){ print "
日別アクセス" ;&make_data_log('DAY',$CONF{GRAPH_MAX}, $CONF{DAY_MAX_V});} if($FORM{'URL'}){ print "
リンクURL" ;&make_data( 'URL', $CONF{GRAPH_MAX}, $CONF{URL_MAX_V} );} if($FORM{'CNT'}){ print "
国別アクセス" ;&make_data( 'CNT', $CONF{GRAPH_MAX}, $CONF{CNT_MAX_V} );} if($FORM{'HOS'}){ print "
ホスト" ;&make_data( 'HOS', $CONF{GRAPH_MAX}, $CONF{HOS_MAX_V} );} # ---------------------------------------------------------------------------- }elsif( $CONF{SOCKET} ){ # データを表示しない場合、当CGIのバージョン情報を告知する。 ( $INFO{VERSION}, $INFO{DATE}, $INFO{MAIL}, $INFO{'URL'}, $INFO{MESS1}, $INFO{MESS2}, $INFO{FLAG}) = &ver_info( $CONF{VER_HOST}, $CONF{VER_URI}, 80 ); &jcode'convert( \$INFO{MESS1}, $CONF{CODE}, 'sjis' ); &jcode'convert( \$INFO{MESS2}, $CONF{CODE}, 'sjis' ); # Version Information 表示 # 表示フラグ判定 if( $INFO{FLAG} ){ # HTML 表示 print <<__STRING__; __STRING__ if( $CONF{THIS_VER} eq $INFO{VERSION} ){ # 最新版の時のメッセージを表示する print <<__STRING__; __STRING__ }else{ # バージョンが古い場合のメッセージを表示する print <<__STRING__; __STRING__ } print "
VERSION INFORMATION
このバージョン$CONF{THIS_VER}
最新バージョン$INFO{VERSION} ($INFO{DATE})
コメント$INFO{MESS2}
コメント$INFO{MESS1}
"; } } print "

$COPYRIGHT"; exit(0); # -----------// メインルーチンここまで。 sub print_form_password{ print <<__STRING__;
PASSWORD
__STRING__ } # ---------------// FORM HTML 作成 sub print_form_1{ &H_YEAR; &H_MONTH; &H_MDAY; &H_MDAYz; if( $FORM{'VIEW'} ){ # map(checked{$_} = 'checked' if ($conf{$_})){'AGE','OS'...........}; $CHECKED{'AGE'} = ' checked' if $FORM{'AGE'}; $CHECKED{'OS'} = ' checked' if $FORM{'OS'}; $CHECKED{'KT'} = ' checked' if $FORM{'KT'}; $CHECKED{'VER'} = ' checked' if $FORM{'VER'}; $CHECKED{'KEY'} = ' checked' if $FORM{'KEY'}; $CHECKED{'URL'} = ' checked' if $FORM{'URL'}; $CHECKED{'HOS'} = ' checked' if $FORM{'HOS'}; $CHECKED{'CNT'} = ' checked' if $FORM{'CNT'}; $CHECKED{'TIME'}= ' checked' if $FORM{'TIME'}; $CHECKED{'DAY'} = ' checked' if $FORM{'DAY'}; $CHECKED{PPP0} = ' checked' if $FORM{ADDR_SHORT} == 0; $CHECKED{PPP1} = ' checked' if $FORM{ADDR_SHORT} == 1; # $CHECKED{'YEAR'}= ' selected' if $FORM{'YEAR'}; # いらない $CHECKED{'MON'} = ' selected' if $FORM{'MON'}; $CHECKED{'CACHE_MODE_0'} = 'checked' if $FORM{'CACHE_MODE'} == 0; $CHECKED{'CACHE_MODE_1'} = 'checked' if $FORM{'CACHE_MODE'} == 1; $CHECKED{'CACHE_MODE_2'} = 'checked' if $FORM{'CACHE_MODE'} == 2; $CHECKED{'CACHE_MODE_9'} = 'checked' if $FORM{'CACHE_MODE'} == 9; }else{ $CHECKED{'AGE'} = ' checked' if $CONF{'AGE'}; $CHECKED{'OS'} = ' checked' if $CONF{'OS'}; $CHECKED{'KT'} = ' checked' if $CONF{'KT'}; $CHECKED{'VER'} = ' checked' if $CONF{'VER'}; $CHECKED{'KEY'} = ' checked' if $CONF{'KEY'}; $CHECKED{'URL'} = ' checked' if $CONF{'URL'}; $CHECKED{'HOS'} = ' checked' if $CONF{'HOS'}; $CHECKED{'CNT'} = ' checked' if $CONF{'CNT'}; $CHECKED{'TIME'}= ' checked' if $CONF{'TIME'}; $CHECKED{'DAY'} = ' checked' if $CONF{'DAY'}; if( $CONF{PPP} ){ $CHECKED{PPP1}= ' checked';}else{ $CHECKED{PPP0}= ' checked';} $CHECKED{'CACHE_MODE_0'} = 'checked' if $CONF{'CACHE_MODE'} == 0; $CHECKED{'CACHE_MODE_1'} = 'checked' if $CONF{'CACHE_MODE'} == 1; $CHECKED{'CACHE_MODE_2'} = 'checked' if $CONF{'CACHE_MODE'} == 2; $CHECKED{'CACHE_MODE_9'} = 'checked' if $CONF{'CACHE_MODE'} == 9; } print <<__STRING__;
CONTROL PANEL
統計年月$H_YEAR $H_MONTH $H_MDAY 〜 $H_MDAYz
統計対象 環境 ブラウザ バージョン 携帯 検索キー
時間別 日別 リンクURL 国別 利用ホスト
OPTION PPP部分削除厳密簡易 URL欄の文字数 __STRING__ print <<__STRING__ if $CONF{CACHE_USE};
キャッシュを 自動作成 再構\築 作らない 削除 __STRING__ print <<__STRING__;



__STRING__ } # ---------------// データを読んでカウントする。 # 第一引数:対象引数名 # 第二引数:ファイルパス # 第三引数:データ加工時に使用するサブルーチン名 sub read_data{ my $NAME = $_[0]; my $FILE = $_[1]; my $SUB = $_[2] if $_[2]; my( $TIME, $DATA, $TEMP_for_time_check ); # &cache_check( $NAME, $TIME_START, $TIME_END ); my $TODAY_TIME = &DATE2( time ); open( READ, $FILE ); foreach(){ chomp; ( $TIME, $DATA, ) = split( /\t/, $_ ); next if $DATA eq ''; $AM00_TIME = &DATE2( $TIME ); # 指定期間じゃなかったら、とばす unless( $TIME_START <= $TIME && $TIME < $TIME_END ){ next; } $CACHE{ALL}++; $CACHE_FILE = $CACHE_DIR .'cache.'. $AM00_TIME .'.'. $NAME . '.txt'; if( -f $CACHE_FILE ){ if( $FORM{'CACHE_MODE'} == 1 ){ unlink( $CACHE_FILE ); $CACHE{MISS}++; }else{ # キャッシュファイルがあるのでとばす $CACHE_EXIST{$AM00_TIME} = 1; $$NAME++; # 行数(=抽出数)だけは数えておく $CACHE{HIT}++; next; } }else{ $CACHE{MISS}++; } if( $SUB ){ # データ加工 foreach( &$SUB( $DATA, $NAME ) ){ if( $_ ){ # 検索KEYの処理の場合 if( $NAME eq 'KEY' ){ # 全角を半角に統一 if( $CONF{USE_JPERL} == 0 ){ $char = 'a-zA-Z0-9−'; &jcode::convert( \$char, 'euc', $CONF{CODE} ); &jcode::tr( \$_, $char, "a-zA-Z0-9-"); } # 大文字小文字の統一 if( $CONF{CHAR} ){ $_ =~ tr/a-z/A-Z/ if $CONF{CHAR} eq 'UP'; $_ =~ tr/A-Z/a-z/ if $CONF{CHAR} eq 'LOW'; } # 文字コードを変換する &jcode::convert( \$_, $CONF{CODE}, 'euc' ); # }elsif( $NAME eq 'HOS' ){ # # } $$NAME{$_}++; $$NAME++; $MAX_NUM{$NAME} = $$NAME{$_} if $MAX_NUM{$NAME} < $$NAME{$_}; # --------------------------------------------- # キャッシュデータの作成。 # ただし最新日のキャッシュは作らないし # キャッシュが存在する場合は処理を行わない。 # --------------------------------------------- if( $CONF{CACHE_USE} == 1 ){ # キャッシュ機能を使用する場合だけデータを作成する $CACHE_FILE = $CACHE_DIR .'cache.'. $AM00_TIME .'.'. $NAME . '.txt'; unless( -f $CACHE_FILE ){ &make_cache_data( $NAME, $AM00_TIME, $_ ) if $TODAY_TIME != $AM00_TIME; } } } } }else{ # ノーマル # この部分は多分使わないでしょう。 # if( $NAME eq 'KEY' ){ &jcode'convert( \$DATA, 'sjis', 'euc' ); } $$NAME{$DATA}++; $$NAME++; $MAX_NUM{$NAME} = $$NAME{$DATA} if $MAX_NUM{$NAME} < $$NAME{$DATA}; # --------------------------------------------- # キャッシュデータの作成。 # ただし最新日のキャッシュは作らないし # キャッシュが存在する場合は処理を行わない。 # --------------------------------------------- if( $CONF{CACHE_USE} == 1 ){ # キャッシュ機能を使用する場合だけデータを作成する $CACHE_FILE = $CACHE_DIR .'cache.'. $AM00_TIME .'.'. $NAME . '.txt'; unless( -f $CACHE_FILE ){ &make_cache_data( $NAME, $AM00_TIME, $DATA ) if $TODAY_TIME != $AM00_TIME;; } } } } close( READ ); } sub read_cache{ my $NAME = $_[0]; my $DATA = ''; my $COUNT = 0; foreach $AM00_TIME ( keys %CACHE_EXIST ){ $CACHE_FILE = $CACHE_DIR .'cache.'. $AM00_TIME .'.'. $NAME . '.txt'; open( CACHE, "$CACHE_FILE" ); foreach $LINE ( ){ chomp( $LINE ); ( $DATA, $COUNT ) = split( /\t/, $LINE ); $$NAME{$DATA} += $COUNT; $MAX_NUM{$NAME} = $$NAME{$DATA} if $MAX_NUM{$NAME} < $$NAME{$DATA}; } } } # ----------------// キャッシュデータを1日ごとに作成する # 第1引数:対象引数名 # 第2引数:TIME # 第3引数:DATA sub make_cache_data{ my $NAME = $_[0]; my $AM00_TIME = $_[1]; my $DATA = $_[2]; $CACHE_MAIN{$NAME}{$AM00_TIME}{$DATA}++; } # ----------------// キャッシュデータを1日ごとに保存する # 第1引数:対象引数名 sub save_cache{ my $NAME = $_[0]; foreach $AM00_TIME ( keys %{$CACHE_MAIN{$NAME}} ){ $CACHE_FILE = $CACHE_DIR .'cache.'. $AM00_TIME .'.'. $NAME . '.txt'; open( OUT, ">$CACHE_FILE" ); foreach $DATA ( keys %{$CACHE_MAIN{$NAME}{$AM00_TIME}} ){ print OUT $DATA ."\t". $CACHE_MAIN{$NAME}{$AM00_TIME}{$DATA} ."\n"; } close( OUT ); } } # ---------------// データをソートして統計・表示します # 第一引数:対象引数名 # 第二引数:棒グラフの最大長さ(pixel) # 第三引数:最大表示件数 sub make_data{ my $NAME = $_[0]; my $MAX_LENGTH = $_[1]; my $MAX_VIEW = $_[2]; my $PAR = 0; my $c = 0; my $CHUSYUTSU = $$NAME; $CHUSYUTSU = 0 unless $CHUSYUTSU; my $KENSU = keys %$NAME; $TEMP_SORT_NAME = $NAME; print ''; print <<__STRING__; __STRING__ foreach( sort $BY keys %$NAME ){ $c++; # 最大表示件数に達したらループ終了 if( $MAX_VIEW ){ last if $MAX_VIEW < $c; } # パーセント計算 $PAR = int( 0.5 + (( 100 * $$NAME{$_} ) / $$NAME ) * 10 ) / 10; $PAR .= '.0' if $PAR !~ /\./ && $PAR < 100; # 棒グラフIMAGEの長さを算出 $LENGTH = int( 0.5 + (( $MAX_LENGTH * $$NAME{$_} ) / $MAX_NUM{$NAME} )) if $MAX_NUM{$NAME}; $LENGTH = 1 if $LENGTH == 0; my $DATA = $_; # KEY をニックネームに置き換える if( $NAME eq 'AGE' ){ # foreach( keys %NAME_AGE ){ # $DATA = $NAME_AGE{$_} if $DATA =~ /^$_$/i; # } if( $NAME_AGE{$_} ne '' ){ $DATA = $NAME_AGE{$_}; } }elsif( $NAME eq 'OS'){ # foreach( keys %NAME_OS ){ # $DATA = $NAME_OS{$_} if $DATA =~ /^$_$/i; # } if( $NAME_OS{$_} ne '' ){ $DATA = $NAME_OS{$_}; } }elsif( $NAME eq 'VER'){ # foreach( keys %NAME_VER ){ # $DATA = $NAME_VER{$_} if $DATA =~ /^$_$/i; # } if( $NAME_VER{$_} ne '' ){ $DATA = $NAME_VER{$_}; } }elsif( $NAME eq 'CNT'){ # foreach( keys %NAME_CNT ){ # $DATA = $NAME_CNT{$_} if $DATA =~ /^$_$/i; # } if( $NAME_CNT{$_} ne '' ){ $DATA = $NAME_CNT{$_}; } # http...で続く文字にアンカータグを付ける。 # 最大文字数を越える部分を省略する }elsif( $NAME eq 'URL'){ my $Anker = $DATA; my $LENGTH = length( $DATA ); if( $CONF{URL_LEN} < $LENGTH ){ $Anker = substr( $DATA, 0, $CONF{URL_LEN} ); $Anker .= '.....'; } # アンカータグを付けるか付けないか。 if( $CONF{LINK} ){ # 付ける $DATA = "$Anker" if $DATA =~ /^http/i; }else{ # 付けない $DATA = "$Anker"; } }elsif( $NAME eq 'HOS'){ if( $CONF{HOS_IPIGNORE} ){ if( $DATA =~ /^\d*\.\d*\.\d*\.\d*$/i ){ $c--; next; } } # ホスト名のホストにリンクを張る場合 if( $CONF{HOS_LINK} ){ $DATA = "$DATA" if $DATA !~ /^\d*\.\d*\.\d*\.\d*$/i; } } print <<__STRING__; __STRING__ } print '
NO COUNT GRAPH DATA $KENSU件 ( 抽出数:$CHUSYUTSU件 )
$c $$NAME{$_} $PAR\% $DATA
'; # 一応メモリ解放 undef %$NAME; } # 時間別・日別 ログ読み込み # 第一引数:ファイルパス sub log_count{ my $FILE = $_[0]; my( $DATA ); open( READ, $FILE ); foreach(){ chomp; ($TEMP,$DATA) = (split( /\t/, $_ ))[0,3]; next if $DATA eq ''; # 指定期間じゃなかったら、とばす $TEMP_for_time_check =0; if( $TIME_START <= $TEMP && $TEMP < $TIME_END ){ # とりあえず、期間内データ数をカウント $TEMP_for_time_check++; }elsif( 10 < $TEMP_for_time_check ){ # これ以上続けても、対象期間のデータは無いでしょう。多分。break! return 1; }else{ # 期間外なので、とばす。 next; } $DATA =~ m!.*\<\=\s\d+/\d+/(\d+)\s(\d+)!; $TEMP = $1; $DAY{$TEMP}++; $DAY++; $MAX_NUM{'DAY'} = $DAY{$TEMP} if $MAX_NUM{'DAY'} < $DAY{$TEMP}; $TEMP = $2; $TIME{$TEMP}++; $TIME++; $MAX_NUM{'TIME'} = $TIME{$TEMP} if $MAX_NUM{'TIME'} < $TIME{$TEMP}; } close(READ); } # 時間別・日別 用 # ---------------// データをソートして統計・表示します # 第一引数:対象引数名 # 第二引数:棒グラフの最大長さ(pixel) # 第三引数:最大表示件数 sub make_data_log{ my $NAME = $_[0]; my $MAX_LENGTH = $_[1] + 100; my $MAX_VIEW = $_[2]; my $PAR = 0; my $c = 0; my $CHUSYUTSU = $$NAME; $CHUSYUTSU = 0 unless $CHUSYUTSU; my $KENSU = keys %$NAME; $TEMP_SORT_NAME = $NAME; print ''; print <<__STRING__; __STRING__ my $TEMP = $BY; $BY = 'by_char'; foreach( sort $BY keys %$NAME ){ $c++; # 最大表示件数に達したらループ終了 if( $MAX_VIEW ){ last if $MAX_VIEW < $c; } # パーセント計算 $PAR = int( 0.5 + (( 100 * $$NAME{$_} ) / $$NAME ) * 10 ) / 10; $PAR .= '.0' if $PAR !~ /\./ && $PAR < 100; # 棒グラフIMAGEの長さを算出 $LENGTH = int( 0.5 + (( $MAX_LENGTH * $$NAME{$_} ) / $MAX_NUM{$NAME} )) if $MAX_NUM{$NAME}; $LENGTH = 1 if $LENGTH == 0; my $DATA = $_; print <<__STRING__; __STRING__ } print '
$NAME COUNT GRAPH $KENSU件 ( 抽出数:$CHUSYUTSU件 )
$DATA $$NAME{$_} $PAR\%
'; $BY = $TEMP; } # ---------------// HOST の PPP部分を削除する # 第一引数:HOST sub ppp_cut{ my $ADR = $_[0]; my @ADDR; # localhost の場合何もせずに値を返す if( $ADR eq 'localhost' ){ return $ADR; } unless( $ADR =~ /^\d*\.\d*\.\d*\.\d*$/ ){ # ドメインを厳密に短くする if( $CONF{ADDR_SHORT} == 1){ @ADDR = split( /\./, $ADR ); # shift( @ADDR ); @ADDR = reverse( @ADDR ); # 短くしたら「ピリオド挟んで2つ」になるドメイン(決め打ち(^_^;;;) if( $ADR =~ /com$|net$|org$|gov$|mil$|edu$|nu$|to$|be$|at$/i){ $ADR = "$ADDR[1].$ADDR[0]"; }else{ if( $ADDR[0] eq 'jp' ){ $ADR = "$ADDR[2].$ADDR[1].$ADDR[0]"; }elsif( $ADDR[2] ne '' ){ $ADR = "$ADDR[2].$ADDR[1].$ADDR[0]"; }else{ $ADR = "$ADDR[1].$ADDR[0]"; } } # ドメインを左端の PPP部分 のみ削除する }elsif( $CONF{ADDR_SHORT} == 0 ){ @ADDR = split( /\./, $ADR ); my $TEMP = @ADDR; # ピリオド挟んで 3 個以上だったら削除する必要があるね。 if( $TEMP >= 3){ shift( @ADDR ); $ADR = join( '.', @ADDR ); } } } $ADR; } # host名の後ろについてる国コード(?)を切り取って返す。 # IP アドレスの場合はなにも返さない。 # どの国からきたのかな? という統計用 sub country_cut{ my $ADR = $_[0]; if( $ADR !~ /\d*\.\d*\.\d*\.\d*/ ){ $res = (split(/\./,$ADR))[-1]; $res =~ tr/A-Z/a-z/; $res; } } # 携帯電話の場合、機種名を切り取って返す # それ以外はなにも返さない sub ktai_cut{ # (imode) DoCoMo/1.0/P501i # (J-SKY) J-PHONE/2.0/J-SH03 # (ezweb) UP.Browser/3.04-HI12 UP.Link/3.3.0.3 my $UA = $_[0]; if( $UA =~ /^DoCoMo\//i ){ $res = (split(/\//,$UA))[2]; $res; }elsif( $UA =~ /^J-PHONE\//i ){ $res = (split(/\//,$UA))[2]; $res; } } # ---------------// キーワードが複数あれば分割する # 第一引数:キーワード sub keyword_cut{ my $KEY = $_[0]; $KEY =~ s/\+/ /g; $KEY =~ s/。。/ /g; $KEY =~ s/\|/ /g; $KEY =~ s/ / /g; split( /\s/, $KEY ); } # ---------------// HTTP_USER_AGENT ログの統計用 # 第一引数:データ # 第二引数:引数名 # # マッチしたら、それに対応するキーを返す sub agent{ my $AGENT = $_[0]; my $NAME = $_[1]; my $FLAG = 0; my($KEY,$DATA); foreach( @$NAME ){ ($KEY,$DATA) = split( /__/, $_ ); foreach( split( /\|/, $DATA )){ $FLAG = 1 if $AGENT =~ /$_/i; } last if $FLAG; $KEY = '' unless $FLAG; } $KEY; } # ---------------// HTTP_USER_AGENT ログの統計用 # 第一引数:データ # 第二引数:引数名 # # マッチしたら、それに対応するキーを返す sub agent_ver{ my $AGENT = $_[0]; my $NAME = $_[1]; my $FLAG = 1; my($KEY,$DATA); foreach( @$NAME ){ ($KEY,$DATA) = split( /__/, $_ ); foreach( split( /\|/, $DATA )){ # or条件。どれかが真ならば FLAG=1 である $FLAG = 1; foreach( split( /\&/, $_ ) ){ # and条件。1つでも偽ならば FLAG_AND=0 である $FLAG = 0 if $AGENT !~ /$_/i; } last if $FLAG == 1; } last if $FLAG == 1; $KEY = '' unless $FLAG; } $KEY; } # ---------------// USER_AGENT の文字列比較時に使用する文字列 sub set_agent_name{ # USER_AGENT 参考:http://www.dais.is.tohoku.ac.jp/logs/agentgripes.html # [KEY] __ [VALUE|VALUE|VALUE|...] # # 左辺と右辺は "__" アンダーバー2つで区切られる。 # 右辺には、マッチさせる文字列をいれる。 # ("|" で区切ると複数指定可) # @VER(version)だけは & 判別もする。 @VER = ( 'MSIE9__MSIE\s9&compatible', 'MSIE8__MSIE\s8&compatible', 'MSIE7__MSIE\s7&compatible', 'MSIE6__MSIE\s6&compatible', 'MSIE5__MSIE\s5&compatible', 'MSIE4__MSIE\s4&compatible', 'MSIE3__MSIE\s3&compatible', 'MSIE2__MSIE\s2&compatible', 'MSIE1__MSIE\s1&compatible', 'MOZI9__Mozilla/9&;\sI|Mozilla/9&;\sU|Mozilla/9&;\sN', 'MOZI8__Mozilla/8&;\sI|Mozilla/8&;\sU|Mozilla/8&;\sN', 'MOZI7__Mozilla/7&;\sI|Mozilla/7&;\sU|Mozilla/7&;\sN', 'MOZI6__Mozilla/6&;\sI|Mozilla/6&;\sU|Mozilla/6&;\sN|Mozilla/5&\sNetscape6', 'MOZI5__Mozilla/5&;\sI|Mozilla/5&;\sU|Mozilla/5&;\sN', 'MOZI4__Mozilla/4&;\sI|Mozilla/4&;\sU|Mozilla/4&;\sN', 'MOZI3__Mozilla/3&;\sI|Mozilla/3&;\sU|Mozilla/3&;\sN', 'MOZI2__Mozilla/2&;\sI|Mozilla/2&;\sU|Mozilla/2&;\sN', 'MOZI1__Mozilla/1&;\sI|Mozilla/1&;\sU|Mozilla/1&;\sN' ); # ブラウザ @AGE = ( 'IMODE__DoCoMo\/', 'JSKY__J\-PHONE\/', 'EZWEB__UP\.Browser\/', 'AVEF__AVE-Front|sharp\swd\sbrowser|sharp\stv\sbrowser|sharp\spda\sbrowser', 'DPAS__DreamPassport', 'SPAS__SonicPassport', 'WEBTV__WebTV|PlanetWeb', 'MSPIE__MSPIE', 'TOOL__Getweb|PNWalker|Pockey|WWWC|Internet\sNinja|WebFetch|PerMan\sSurfer|Wget|WebAuto|Drip|WebWhacker|VCI\sWebViewer|httpdown|PageDown|Offline\sExplorer', 'MSIE__MSIE', 'TOOL__compatible', 'HJAVA__HotJava', 'CDOG__Cyberdog', 'EMACS__Emacs', 'LYNX__Lynx', 'OMNI__OmniWeb', 'WBOY__WebBoy', 'AMAYA__amaya', 'NETP__NetPositive', 'MOSAIC__NCSA_Mosaic|Mosaic', 'JUST__JustView', 'ICAB__iCab', 'OPERA__Opera\s', 'NETSCAPE__Mozilla' ); # OS環境など @OS = ( 'BEOS__BeOS', 'OS_2__OS/2', 'DCAST__DreamPassport|SonicPassport', 'MAC_OS__Macintosh|Mac_PowerPC|Mac_68K', 'WIN_CE__Windows\sCE', 'WIN_31__Windows\s3.1', 'WIN_95__Win95|Windows\s95', 'WIN_ME__Win\s9x\s4\.90', 'WIN_98__Win98|Windows\s98', 'WIN_2K__Win2K|Windows\sNT\s5|Windows\s2000|Windows\s2k', 'WIN_NT__WinNT|Windows\sNT', 'X11CPM__CP/M', 'X11PBD__PocketBSD', 'X11NBD__NetBSD', 'X11FBD__FreeBSD', 'X11OBD__OpenBSD', 'X11BSD__BSD/OS', 'X11LIN__Linux', 'X11SUN__SunOS', 'X11AIX__AIX', 'X11IRI__IRIX', 'X11NEW__NEWS-OS', 'X11UNI__UNIX_SV', 'X11HP__HP-UX', 'X11OSF__OSF1', 'X11ETC__X11' ); # $NAME{[KEY]} = [VALUE] # # [KEY] = 上で使用した KEY # [VALUE] = 読みやすい呼び名。 # 統計表示時、KEY を表示する代わりにここで指定した VALUE を # 表示する。(その方が見やすいでしょ?) $NAME_AGE{'TOOL'} = '巡回ツール等'; $NAME_AGE{'MSIE'} = 'Internet Explorer'; $NAME_AGE{'MSPIE'} = 'Pocket Internet Explorer'; $NAME_AGE{'NETSCAPE'} = 'Netscape'; $NAME_AGE{'MOSAIC'} = 'MOSAIC'; $NAME_AGE{'LYNX'} = 'Lynx'; $NAME_AGE{'OMNI'} = 'OmniWeb'; $NAME_AGE{'EMACS'} = 'Emacs-W3'; $NAME_AGE{'AMAYA'} = 'AMAYA(W3C)'; $NAME_AGE{'JUST'} = 'JustView'; $NAME_AGE{'DPAS'} = 'DreamPassport(DC)'; $NAME_AGE{'SPAS'} = 'SonicPassport(DC)'; $NAME_AGE{'WEBTV'} = 'WebTV'; $NAME_AGE{'NETF'} = 'NetFront'; $NAME_AGE{'NETP'} = 'NetPositive'; $NAME_AGE{'IMODE'} = 'i-mode'; # 正式なのって大文字?小文字? $NAME_AGE{'EZWEB'} = 'EZweb'; $NAME_AGE{'JSKY'} = 'J-SkyWeb'; $NAME_AGE{'HJAVA'} = 'HotJava'; $NAME_AGE{'AVEF'} = 'AVE-Front'; $NAME_AGE{'CDOG'} = 'Cyberdog'; $NAME_AGE{'WBOY'} = 'WebBoy'; $NAME_AGE{'ICAB'} = 'iCab'; $NAME_AGE{'OPERA'} = 'Opera'; $NAME_OS{'BEOS'} = 'BeOS'; $NAME_OS{'OS_2'} = 'OS/2'; $NAME_OS{'DCAST'} = 'Dreamcast'; $NAME_OS{'MAC_OS'} = 'Macintosh'; $NAME_OS{'WIN_CE'} = 'Windows CE'; $NAME_OS{'WIN_31'} = 'Windows 3.1'; $NAME_OS{'WIN_95'} = 'Windows 95'; $NAME_OS{'WIN_98'} = 'Windows 98'; $NAME_OS{'WIN_ME'} = 'Windows Me'; $NAME_OS{'WIN_NT'} = 'Windows NT'; $NAME_OS{'WIN_2K'} = 'Windows 2000'; $NAME_OS{'X11PBD'} = 'PocketBSD'; $NAME_OS{'X11CPM'} = 'CP/M'; $NAME_OS{'X11OBD'} = 'OpenBSD'; $NAME_OS{'X11NBD'} = 'NetBSD'; $NAME_OS{'X11FBD'} = 'FreeBSD'; $NAME_OS{'X11BSD'} = 'BSD/OS'; $NAME_OS{'X11LIN'} = 'Linux'; $NAME_OS{'X11SUN'} = 'Solaris'; $NAME_OS{'X11AIX'} = 'AIX'; $NAME_OS{'X11IRI'} = 'IRIX'; $NAME_OS{'X11NEW'} = 'NEWS-OS'; $NAME_OS{'X11HP'} = 'HP-UX'; $NAME_OS{'X11OSF'} = 'Digital UNIX'; $NAME_OS{'X11UNI'} = 'UnixWare'; $NAME_OS{'X11ETC'} = 'その他 (X window system)'; $NAME_VER{'MSIE1'} = 'Internet Explorer 1.x'; $NAME_VER{'MSIE2'} = 'Internet Explorer 2.x'; $NAME_VER{'MSIE3'} = 'Internet Explorer 3.x'; $NAME_VER{'MSIE4'} = 'Internet Explorer 4.x'; $NAME_VER{'MSIE5'} = 'Internet Explorer 5.x'; $NAME_VER{'MSIE6'} = 'Internet Explorer 6.x'; $NAME_VER{'MSIE7'} = 'Internet Explorer 7.x'; $NAME_VER{'MSIE8'} = 'Internet Explorer 8.x'; $NAME_VER{'MSIE9'} = 'Internet Explorer 9.x'; $NAME_VER{'MOZI1'} = 'Netscape 1.x'; $NAME_VER{'MOZI2'} = 'Netscape 2.x'; $NAME_VER{'MOZI3'} = 'Netscape 3.x'; $NAME_VER{'MOZI4'} = 'Netscape 4.x'; $NAME_VER{'MOZI5'} = 'Netscape 5.x'; $NAME_VER{'MOZI6'} = 'Netscape 6.x'; $NAME_VER{'MOZI7'} = 'Netscape 7.x'; $NAME_VER{'MOZI8'} = 'Netscape 8.x'; $NAME_VER{'MOZI9'} = 'Netscape 9.x'; $NAME_CNT{'com'}= '(COM) 商業'; $NAME_CNT{'edu'}= '(EDU) 学術'; $NAME_CNT{'gov'}= '(GOV) 米国政府'; $NAME_CNT{'int'}= '(INT) 国際機関'; $NAME_CNT{'mil'}= '(MIL) 国防総省'; $NAME_CNT{'net'}= '(NET) ネットワーク'; $NAME_CNT{'org'}= '(ORG) 機関'; $NAME_CNT{'ac'} = '(AC) アセッション島'; $NAME_CNT{'ad'} = '(AD) アンドラ'; $NAME_CNT{'ae'} = '(AE) アラブ首長国連邦'; $NAME_CNT{'af'} = '(AF) アフガニスタン'; $NAME_CNT{'ag'} = '(AG) アンティグア'; $NAME_CNT{'ai'} = '(AI) アンギラ'; $NAME_CNT{'al'} = '(AL) アルバニア'; $NAME_CNT{'am'} = '(AM) アルメニア'; $NAME_CNT{'an'} = '(AN) 蘭領アンティル'; $NAME_CNT{'ao'} = '(AO) アンゴラ'; $NAME_CNT{'aq'} = '(AQ) 南極'; $NAME_CNT{'ar'} = '(AR) アルゼンチン'; $NAME_CNT{'as'} = '(AS) 米領サモア'; $NAME_CNT{'at'} = '(AT) オーストリア'; $NAME_CNT{'au'} = '(AU) オーストラリア'; $NAME_CNT{'aw'} = '(AW) ルバ'; $NAME_CNT{'az'} = '(AZ) アゼルバイジャン'; $NAME_CNT{'ba'} = '(BA) ボスニア・ヘルツェゴビナ'; $NAME_CNT{'bb'} = '(BB) バルバドス'; $NAME_CNT{'bd'} = '(BD) バングラディシュ'; $NAME_CNT{'be'} = '(BE) ベルギー'; $NAME_CNT{'bf'} = '(BF) ブルキナファソ\'; $NAME_CNT{'bg'} = '(BG) ブルガリア'; $NAME_CNT{'bh'} = '(BH) バーレーン'; $NAME_CNT{'bi'} = '(BI) ブルンジ'; $NAME_CNT{'bj'} = '(BJ) ベナン'; $NAME_CNT{'bm'} = '(BM) バミューダ'; $NAME_CNT{'bn'} = '(BN) ブルネイ'; $NAME_CNT{'bo'} = '(BO) ボリビア'; $NAME_CNT{'br'} = '(BR) ブラジル'; $NAME_CNT{'bs'} = '(BS) バハマ'; $NAME_CNT{'bt'} = '(BT) ブータン'; $NAME_CNT{'bv'} = '(BV) ブーベ島'; $NAME_CNT{'bw'} = '(BW) ボツワナ'; $NAME_CNT{'by'} = '(BY) ベラルーシ'; $NAME_CNT{'bz'} = '(BZ) ベリーズ'; $NAME_CNT{'ca'} = '(CA) カナダ'; $NAME_CNT{'cc'} = '(CC) ココス諸島'; $NAME_CNT{'cd'} = '(CD) ザイール'; $NAME_CNT{'cf'} = '(CF) 中央アフリカ共和国'; $NAME_CNT{'cg'} = '(CG) コンゴ'; $NAME_CNT{'ch'} = '(CH) スイス'; $NAME_CNT{'ci'} = '(CI) コートジボアール'; $NAME_CNT{'ck'} = '(CK) クック諸島'; $NAME_CNT{'cl'} = '(CL) チリ'; $NAME_CNT{'cm'} = '(CM) カメルーン'; $NAME_CNT{'cn'} = '(CN) 中国'; $NAME_CNT{'co'} = '(CO) コロンビア'; $NAME_CNT{'cr'} = '(CR) コスタリカ'; $NAME_CNT{'cs'} = '(CS) チェコスロバキア'; $NAME_CNT{'cu'} = '(CU) キューバ'; $NAME_CNT{'cv'} = '(CV) カーボ・ベルデ'; $NAME_CNT{'cx'} = '(CX) クリスマス島'; $NAME_CNT{'cy'} = '(CY) キプロス'; $NAME_CNT{'cz'} = '(CZ) チェコ'; $NAME_CNT{'de'} = '(DE) ドイツ'; $NAME_CNT{'dj'} = '(DJ) ジブチ'; $NAME_CNT{'dk'} = '(DK) デンマーク'; $NAME_CNT{'dm'} = '(DM) ドミニカ'; $NAME_CNT{'do'} = '(DO) ドミニカ共和国'; $NAME_CNT{'dz'} = '(DZ) アルジェリア'; $NAME_CNT{'ec'} = '(EC) エクアドル'; $NAME_CNT{'ee'} = '(EE) エストニア'; $NAME_CNT{'eg'} = '(EG) エジプト'; $NAME_CNT{'eh'} = '(EH) 西サハラ'; $NAME_CNT{'er'} = '(ER) エリトリア'; $NAME_CNT{'es'} = '(ES) スペイン'; $NAME_CNT{'et'} = '(ET) エチオピア'; $NAME_CNT{'fi'} = '(FI) フィンランド'; $NAME_CNT{'fj'} = '(FJ) フィジー'; $NAME_CNT{'fk'} = '(FK) フォークランド諸島'; $NAME_CNT{'fm'} = '(FM) ミクロネシア'; $NAME_CNT{'fo'} = '(FO) ファロー群島'; $NAME_CNT{'fr'} = '(FR) フランス'; $NAME_CNT{'fx'} = '(FX) フランス、メトロポリタン'; $NAME_CNT{'ga'} = '(GA) ガボン'; $NAME_CNT{'gb'} = '(GB) イギリス'; $NAME_CNT{'gd'} = '(GD) グレナダ'; $NAME_CNT{'ge'} = '(GE) グルジア'; $NAME_CNT{'gf'} = '(GF) 仏領ギアナ'; $NAME_CNT{'gg'} = '(GG) ガーンジィ'; $NAME_CNT{'gh'} = '(GH) ガーナ'; $NAME_CNT{'gi'} = '(GI) ジブラルタル'; $NAME_CNT{'gl'} = '(GL) グリーンランド'; $NAME_CNT{'gm'} = '(GM) ガンビア'; $NAME_CNT{'gn'} = '(GN) ギニア'; $NAME_CNT{'gp'} = '(GP) グアデルーペ'; $NAME_CNT{'gq'} = '(GQ) 赤道ギアナ'; $NAME_CNT{'gr'} = '(GR) ギリシャ'; $NAME_CNT{'gs'} = '(GS) サウスジョージア島・サウスサンドイッチ島'; $NAME_CNT{'gt'} = '(GT) グァテマラ'; $NAME_CNT{'gu'} = '(GU) グアム'; $NAME_CNT{'gw'} = '(GW) ギニア・ビサウ'; $NAME_CNT{'gy'} = '(GY) ガイアナ'; $NAME_CNT{'hk'} = '(HK) 香港'; $NAME_CNT{'hm'} = '(HM) ハード・マクドナルド諸島'; $NAME_CNT{'hn'} = '(HN) ホンジュラス'; $NAME_CNT{'hr'} = '(HR) クロアチア'; $NAME_CNT{'ht'} = '(HT) ハイチ'; $NAME_CNT{'hu'} = '(HU) ハンガリー'; $NAME_CNT{'id'} = '(ID) インドネシア'; $NAME_CNT{'ie'} = '(IE) アイルランド'; $NAME_CNT{'il'} = '(IL) イスラエル'; $NAME_CNT{'im'} = '(IM) マン島'; $NAME_CNT{'in'} = '(IN) インド'; $NAME_CNT{'io'} = '(IO) 英領インド洋領'; $NAME_CNT{'iq'} = '(IQ) イラク'; $NAME_CNT{'ir'} = '(IR) イラン'; $NAME_CNT{'is'} = '(IS) アイスランド'; $NAME_CNT{'it'} = '(IT) イタリア'; $NAME_CNT{'je'} = '(JE) ジャージー'; $NAME_CNT{'jm'} = '(JM) ジャマイカ'; $NAME_CNT{'jo'} = '(JO) ヨルダン'; $NAME_CNT{'jp'} = '(JP) 日本'; $NAME_CNT{'ke'} = '(KE) ケニア'; $NAME_CNT{'kg'} = '(KG) キルギスタン'; $NAME_CNT{'kh'} = '(KH) カンボジア'; $NAME_CNT{'ki'} = '(KI) キリバス'; $NAME_CNT{'km'} = '(KM) コモロ'; $NAME_CNT{'kn'} = '(KN) セント・キッツ、ネビス'; $NAME_CNT{'kp'} = '(KP) 北朝鮮'; $NAME_CNT{'kr'} = '(KR) 大韓民国'; $NAME_CNT{'kw'} = '(KW) クゥエート'; $NAME_CNT{'ky'} = '(KY) ケイマン諸島'; $NAME_CNT{'kz'} = '(KZ) カザフスタン'; $NAME_CNT{'la'} = '(LA) ラオス'; $NAME_CNT{'lb'} = '(LB) レバノン'; $NAME_CNT{'lc'} = '(LC) サンタルチァ'; $NAME_CNT{'li'} = '(LI) リヒテンシュタイン'; $NAME_CNT{'lk'} = '(LK) スリランカ'; $NAME_CNT{'lr'} = '(LR) リベリア'; $NAME_CNT{'ls'} = '(LS) レソト'; $NAME_CNT{'lt'} = '(LT) リトアニア'; $NAME_CNT{'lu'} = '(LU) ルクセンブルグ'; $NAME_CNT{'lv'} = '(LV) ラトビア'; $NAME_CNT{'ly'} = '(LY) リビア'; $NAME_CNT{'ma'} = '(MA) モロッコ'; $NAME_CNT{'mc'} = '(MC) モナコ'; $NAME_CNT{'md'} = '(MD) モルドバ'; $NAME_CNT{'mg'} = '(MG) マダガスカル'; $NAME_CNT{'mh'} = '(MH) マーシャル諸島'; $NAME_CNT{'mk'} = '(MK) マケドニア'; $NAME_CNT{'ml'} = '(ML) マリ'; $NAME_CNT{'mm'} = '(MM) ミャンマー'; $NAME_CNT{'mn'} = '(MN) モンゴル'; $NAME_CNT{'mo'} = '(MO) マカオ'; $NAME_CNT{'mp'} = '(MP) マリアナ諸島'; $NAME_CNT{'mq'} = '(MQ) マルチニーク'; $NAME_CNT{'mr'} = '(MR) モーリタニア'; $NAME_CNT{'ms'} = '(MS) モントセルラット'; $NAME_CNT{'mt'} = '(MT) マルタ'; $NAME_CNT{'mu'} = '(MU) モーリシャス'; $NAME_CNT{'mv'} = '(MV) モルジブ'; $NAME_CNT{'mw'} = '(MW) マラウィ'; $NAME_CNT{'mx'} = '(MX) メキシコ'; $NAME_CNT{'my'} = '(MY) マレーシア'; $NAME_CNT{'mz'} = '(MZ) モザンビーク'; $NAME_CNT{'na'} = '(NA) ナミビア'; $NAME_CNT{'nc'} = '(NC) ニューカレドニア'; $NAME_CNT{'ne'} = '(NE) ニジェール'; $NAME_CNT{'nf'} = '(NF) ノンフォーク島'; $NAME_CNT{'ng'} = '(NG) ナイジェリア'; $NAME_CNT{'ni'} = '(NI) ニカラグア'; $NAME_CNT{'nl'} = '(NL) オランダ'; $NAME_CNT{'no'} = '(NO) ノルウェー'; $NAME_CNT{'np'} = '(NP) ネバール'; $NAME_CNT{'nr'} = '(NR) ナウル'; $NAME_CNT{'nt'} = '(NT) 中立地帯'; $NAME_CNT{'nu'} = '(NU) ニウエ'; $NAME_CNT{'nz'} = '(NZ) ニュージーランド'; $NAME_CNT{'om'} = '(OM) オマーン'; $NAME_CNT{'pa'} = '(PA) パナマ'; $NAME_CNT{'pe'} = '(PE) ペルー'; $NAME_CNT{'pf'} = '(PF) 仏領ポリネシア'; $NAME_CNT{'pg'} = '(PG) パプアニューギニア'; $NAME_CNT{'ph'} = '(PH) フィリピン'; $NAME_CNT{'pk'} = '(PK) パキスタン'; $NAME_CNT{'pl'} = '(PL) ポーランド'; $NAME_CNT{'pm'} = '(PM) サンピエールとミクェロン'; $NAME_CNT{'pn'} = '(PN) ピトケアン諸島'; $NAME_CNT{'pr'} = '(PR) プエルトリコ'; $NAME_CNT{'pt'} = '(PT) ポルトガル'; $NAME_CNT{'pw'} = '(PW) パラオ'; $NAME_CNT{'py'} = '(PY) パラグアイ'; $NAME_CNT{'qa'} = '(QA) カタール'; $NAME_CNT{'re'} = '(RE) レユニオン'; $NAME_CNT{'ro'} = '(RO) ルーマニア'; $NAME_CNT{'ru'} = '(RU) ロシア'; $NAME_CNT{'rw'} = '(RW) ルワンダ'; $NAME_CNT{'sa'} = '(SA) サウジアラビア'; $NAME_CNT{'sb'} = '(SB) ソロモン諸島'; $NAME_CNT{'sc'} = '(SC) セイシェル'; $NAME_CNT{'sd'} = '(SD) スーダン'; $NAME_CNT{'se'} = '(SE) スウェーデン'; $NAME_CNT{'sg'} = '(SG) シンガポール'; $NAME_CNT{'sh'} = '(SH) セント・ヘレナ'; $NAME_CNT{'si'} = '(SI) スロベニア'; $NAME_CNT{'sj'} = '(SJ) スバールバル・ヤンマイエン島'; $NAME_CNT{'sk'} = '(SK) スロバキア'; $NAME_CNT{'sl'} = '(SL) シェラレオネ'; $NAME_CNT{'sm'} = '(SM) サンマリノ'; $NAME_CNT{'sn'} = '(SN) セネガル'; $NAME_CNT{'so'} = '(SO) ソマリア'; $NAME_CNT{'sr'} = '(SR) スリナム'; $NAME_CNT{'st'} = '(ST) サントメ'; $NAME_CNT{'su'} = '(SU) ソ連'; $NAME_CNT{'sv'} = '(SV) エルサルバドル'; $NAME_CNT{'sy'} = '(SY) シリア'; $NAME_CNT{'sz'} = '(SZ) スイス'; $NAME_CNT{'tc'} = '(TC) タークスとカイコス群島'; $NAME_CNT{'td'} = '(TD) チャド'; $NAME_CNT{'tf'} = '(TF) 仏南方領'; $NAME_CNT{'tg'} = '(TG) トーゴ'; $NAME_CNT{'th'} = '(TH) タイ'; $NAME_CNT{'tj'} = '(TJ) タジキスタン'; $NAME_CNT{'tk'} = '(TK) トケラウ'; $NAME_CNT{'tm'} = '(TM) トルクメニスタン'; $NAME_CNT{'tn'} = '(TN) チュニジア'; $NAME_CNT{'to'} = '(TO) トンガ'; $NAME_CNT{'tp'} = '(TP) 東ティモール'; $NAME_CNT{'tr'} = '(TR) トルコ'; $NAME_CNT{'tt'} = '(TT) トリニダード・トバコ'; $NAME_CNT{'tv'} = '(TV) ツバル'; $NAME_CNT{'tw'} = '(TW) 台湾'; $NAME_CNT{'tz'} = '(TZ) タンザニア'; $NAME_CNT{'ua'} = '(UA) ウクライナ'; $NAME_CNT{'ug'} = '(UG) ウガンダ'; $NAME_CNT{'uk'} = '(UK) イギリス'; $NAME_CNT{'um'} = '(UM) 米島嶼部'; $NAME_CNT{'us'} = '(US) アメリカ'; $NAME_CNT{'uy'} = '(UY) ウルグアイ'; $NAME_CNT{'uz'} = '(UZ) ウズベキスタン'; $NAME_CNT{'va'} = '(VA) バチカン市国'; $NAME_CNT{'vc'} = '(VC) セントビンセント・グレナダ諸島'; $NAME_CNT{'ve'} = '(VE) ベネズエラ'; $NAME_CNT{'vg'} = '(VG) 英領バージン諸島'; $NAME_CNT{'vi'} = '(VI) 米領バージン諸島'; $NAME_CNT{'vn'} = '(VN) ベトナム'; $NAME_CNT{'vu'} = '(VU) バヌアツ'; $NAME_CNT{'wf'} = '(WF) ワリスとフツナ'; $NAME_CNT{'ws'} = '(WS) サモア'; $NAME_CNT{'ye'} = '(YE) イエメン'; $NAME_CNT{'yt'} = '(YT) マヨテ'; $NAME_CNT{'yu'} = '(YU) ユーゴスラビア'; $NAME_CNT{'za'} = '(ZA) 南アフリカ'; $NAME_CNT{'zm'} = '(ZM) ザンビア'; $NAME_CNT{'zr'} = '(ZR) ザイール'; $NAME_CNT{'zw'} = '(ZW) ジンバブエ'; } # ---------------// 与えられたディレクトリ中のcacheファイルを削除する # そして削除したファイル数とサイズを返す # # 1: $CACHE_DIR sub delete_cache{ my $CACHE_DIR = $_[0]; my $C = 0; my $TARGET = ''; if( $CACHE_DIR !~ m!/$! ){ $CACHE_DIR .= '/'; } opendir( DIR, $CACHE_DIR ); foreach $FILE ( readdir( DIR )){ next if $FILE =~ /^\.$/; next if $FILE =~ /^\..$/; $TARGET = $CACHE_DIR . $FILE; if( -f $TARGET && $FILE =~ /^cache\./ ){ $SIZE += -s $TARGET; unlink( $TARGET ); $C++; } } closedir( DIR ); ($C , $SIZE); } # 数字にコンマを挿入して返す sub add_conma{ $num = $_[0]; $num = reverse(join(',', reverse($num) =~ /((?:^\d+\.)?\d{1,3}[-+]?)/g)) if $num =~ /^[-+]?\d\d\d\d/; $num; } # ---------------// ソートルーチン # 使用注意 # 事前に環境引数 $TEMP_SORT_NAME へ、ソート対象の # "引数名"を代入しておきます。 # # EX: "%DATA" 配列の値を降順ソートしたい場合。 # > $TEMP_SORT_NAME = 'DATA'; # > @SORTED = sort by_down keys(%DATA); sub by_down{ # 大きい順ソート my $NAME = $TEMP_SORT_NAME; # <<-- ソート関数には引数が使えないので # グローバル変数を経由して引数名を渡す。 if($$NAME{$b} != $$NAME{$a}){ $$NAME{$b} <=> $$NAME{$a}; }else{ $a cmp $b; } } sub by_up{ # 小さい順ソート my $NAME = $TEMP_SORT_NAME; # <<-- ソート関数には引数が使えないので # グローバル変数を経由して引数名を渡す。 if($$NAME{$a} != $$NAME{$b}){ $$NAME{$a} <=> $$NAME{$b}; }else{ $a cmp $b; } } sub by_char{ # 小さい順ソート my $NAME = $TEMP_SORT_NAME; # <<-- ソート関数には引数が使えないので # グローバル変数を経由して引数名を渡す。 $a cmp $b; } # ---------------// 統計対象のログファイル名を確定する。 # 第一引数:年(4桁) # 第二引数:月(1桁 or 2桁) sub make_file_name{ my $YEAR = $_[0]; my $MON = $_[1]; if( $MON < 10 ){ $MON = '0'.$MON; } $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"; } # ---------------// FORMデータ読み込み # フォーム入力を %FORM に読み込むサブルーチン。 # POST のみに対応 sub getdata{ my($buf, $dat, $type); my(@input); if ($ENV{REQUEST_METHOD} eq "POST"){ read(STDIN, $buf,$ENV{CONTENT_LENGTH}); if( $buf ){ @input = split(/\&/,$buf); foreach( @input ){ ($type, $dat) = split(/=/,$_); $dat =~ tr/+/ /; $dat =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$type} = $dat; } } } } # ---------------// ログファイル件数を表示する HTML 作成 sub list{ print <<__STRING__; __STRING__ print <<__STRING__ if $AGE; __STRING__ print <<__STRING__ if $URL; __STRING__ print <<__STRING__ if $HOS; __STRING__ print <<__STRING__ if $KEY; __STRING__ print <<__STRING__ if $DAY | $TIME; __STRING__ print <<__STRING__;
ログファイル ログ件数
HTTP_USER_AGENT $AGE
HTTP_REFERER $URL
REMOTE_ADDR $HOS
KEYWORD $KEY
ACC_LOG $DAY
__STRING__ } # ---------------// FORM.SELECT で使用するプルダウンメニューHTML作成 # 年 sub H_YEAR{ $H_YEAR .= "\n"; } # ---------------// FORM.SELECT で使用するプルダウンメニューHTML作成 # 月 # フォーム表示フォーマットはこれ: 1 2 3 ... 9 10 11 12 # データファイルのフォーマット :01 02 03 ... 09 10 11 12 sub H_MONTH{ my $file_mon = 0; $H_MONTH .= "\n"; } # ---------------// FORM.SELECT で使用するプルダウンメニューHTML作成 # 日 sub H_MDAY{ my $file_day = 0; $H_MDAY .= "\n"; } # ---------------// FORM.SELECT で使用するプルダウンメニューHTML作成 # 日z sub H_MDAYz{ my $file_day = 0; $H_MDAYz .= "\n"; } # ---------------// 日時を取得する sub DATE{ my $TIME = $_[0] | time; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( $TIME ); $mon++; $year += 1900; $hour = '0'.$hour if $hour < 10; $min = '0'.$min if $min < 10; $sec = '0'.$sec if $sec < 10; } # その日の AM00:00 の TIME を返す # ・・・やっつけ(死 sub DATE2{ my $TIME = $_[0]; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( $TIME ); &timelocal( 0, 0, 0, $mday , $mon, $year); } __END__