#!/usr/bin/perl

# ----------------------------------------------------------------------------------
# G_Counter Version 1.20「グラフィックカウンター(CGI用)」
#
# Script written by CGIダウンロード(Nishiyama)
# This script is free
# HomePage http://www.cgi-down.com/
# E-Mail webmaster@cgi-down.com
# (1999/12/17-2001/08-19)
#
# 改変履歴
#
# V1.00 (1999-12-22) 正式リリース。
# V1.10 (2001-06-23) 一定時間中の再訪問者カウント拒否機能追加。
# V1.20 (2001-08-19) ロック機能の変更。
#
# 再配布、商用利用(販売・レンタル等)禁止。
# 使用されたらメールをいただけると光栄です。
# 設置等不明な点は、サポート掲示板へお願いします。
# ----------------------------------------------------------------------------------
#
# **********************************************************************************
#                       オプション設定 ↓ここから
# **********************************************************************************

$gifcat      = './gifcat.pl';            # GIF画像連結ライブラリーの位置
$digit       = 7;                        # カウンターの桁数
$im          = './image/';               # カウンター画像のディレクトリ
$datafile    = './g_counter.dat';        # カウンターデータファイルの位置
$lockfile    = './g_counter.lock';       # ロックファイル名(通常このまま)※複数設置の場合は変更する
$lock_mode   = '2';                      # ロックモード(1=symlink関数使用 2=open関数使用)※1でエラーになる場合は2に設定
$non_count   = '1';                      # 指定時間内の再訪問カウント拒否(拒否=1 常にカウントする=0)
$cookie_name = 'G_COUNTER';              # 再訪問拒否用クッキーネーム(通常このままで結構です)
$cook_limit  = '720';                      # ここで指定した時間は再訪問でもカウントしない(単位:分)

# **********************************************************************************
#                     オプション設定終わり ↑ここまで
# ----------------------------------------------------------------------------------
# これ以降書き換えをする場合は、個人の責任で行って下さい。
# **********************************************************************************
# [メイン処理]
binmode(STDOUT);
require $gifcat;
# クッキー呼び出し
if($non_count) {
  &read_cookie;
}
# ロック開始
if($lock_mode == 1) { &lock1; }
elsif ($lock_mode == 2) { &lock2; }

# データファイル読み込み
@DATA = &read_file($datafile);
$count = $DATA[0];
# 新しい訪問者であれば
if($COOKIE{'name'} eq '') {
  $count = $DATA[0] + 1;
  # ファイル更新
  open(DB,">$datafile") || &error("カウントを記録出来ませんでした。");
  print DB $count;
  close(DB);
}

# ロック解除
&fileunlock;

# クッキーに記録
&set_cookie;

# カウント表示
$count = sprintf("%0" . "$digit" . "\d",$count);
@COUNT = split(//, $count);
$i = 0;
foreach $t (@COUNT) {
  $IMG[$i] = "$im" . "$t.gif";
  $i ++;
}

print "Content-type: image/gif\n\n";
print &gifcat'gifcat(@IMG);

exit;
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [ファイルロック(symlink)]
sub lock1 {
  local($retry) = 5;
  while (!symlink(".", $lockfile)) {
    if(--$retry <= 0) { &error("ただ今混雑中です。しばらくしてアクセスしてください。"); }
    sleep(1);
  }
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [ファイルロック(open)]
sub lock2 {
  foreach (1 .. 5) {
    if (-e $lockfile) { sleep(1); }
    else {
      open(LOCK,">$lockfile");
      close(LOCK);
      return;
    }
  }
  &error("ただ今混雑中です。しばらくしてアクセスしてください。");
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [ファイルロック解除]
sub fileunlock {
  if (-e $lockfile) { unlink($lockfile); }
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [記録ファイルの読み込み]
sub read_file {
  local($data_file) = $_[0];
  if (!open(IN,$data_file)) { &error("ファイルの読み取りに失敗しました。"); }
  local(@Data_Files) = <IN>;
  close(IN);
  return @Data_Files;
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [クッキー呼び出し]
sub read_cookie {
  local($cookies) = $ENV{'HTTP_COOKIE'};
  local($pair,%DUMMY);
  local(@pairs) = split(/;/,$cookies);
  foreach $pair (@pairs) {
    local($name,$value) = split(/=/,$pair);
    $name =~ s/ //g;
    $DUMMY{$name} = $value;
  }
  @pairs = split(/,/,$DUMMY{$cookie_name});
  foreach $pair (@pairs) {
    local($name,$value) = split(/#/,$pair);
    $COOKIE{$name} = $value;
  }
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [クッキー記録]
sub set_cookie {
  local($csec,$cmin,$chour,$cmday,$cmon,$cyear,$cwday) = gmtime(time + $cook_limit * 60);
  $cyear = $cyear + 1900;
  $cmday = sprintf("%.2d",$cmday);
  $chour = sprintf("%.2d",$chour);
  $cmin = sprintf("%.2d",$cmin);
  $csec = sprintf("%.2d",$csec);
  $cmon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$cmon];
  $cwday = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[$cwday];
  $date_gmt = "$cwday, $cmday\-$cmon\-$cyear $chour:$cmin:$csec GMT";
  local($cook) = "name\#CGIダウンロードカウンター用クッキー";
  print "Set-Cookie: $cookie_name=$cook; expires=$date_gmt\n";
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [エラー関連]
sub error {
  print "Content-type: text/html\n\n";
  print "$_[0]\n";
  # ロック解除
  &fileunlock;
  exit;
}