#!/usr/bin/perl

# ----------------------------------------------------------------------------------
# L_Counter Version 1.01「ログカウンター(CGI用)」
#
# Script written by CGIダウンロード(Nishiyama)
# HomePage http://www.cgi-down.com/
# E-Mail webmaster@cgi-down.com
# (1999/12/15-2001/08/21)
# 改変履歴
#
# V1.00 (2000-01-14) 正式リリース。
# V1.01 (2001-08-21) ロック機能の変更。デザイン変更。
#
# 再配布、商用利用(販売・レンタル等)禁止。
# 使用されたらメールをいただけると光栄です。
# 設置等不明な点は、サポート掲示板へお願いします。
# CGIのカスタマイズ・作成も受け付けております。
# メールマガジンにご登録頂きますと最新情報をお届けします。
# http://www.cgi-down.com/magazin/
# ----------------------------------------------------------------------------------
#
# **********************************************************************************
#                       オプション設定 ↓ここから
# **********************************************************************************
$jcode       = './jcode.pl';             # jcode.plの位置
$gifcat      = './gifcat.pl';            # GIF画像連結ライブラリーの位置
$digit       = 6;                        # カウンターの桁数(メインカウンター)トータル数用
$digit1      = 3;                        # カウンターの桁数(サブカウンター)本日、昨日用
$im          = './image/';               # カウンター画像のディレクトリ(メイン)トータル数用
$im_s        = './image_s/';             # カウンター画像のディレクトリ(サブ)本日、昨日用
$datefile    = './l_counter.dat';        # カウンターデータファイルの位置
$log_day     = '30';                     # ログの最大記録数
$lockfile    = './l_counter.lock';       # ロックファイル名(通常このまま)※複数設置の場合は変更する
$lock_mode   = '1';                      # ロックモード(1=symlink関数使用 2=open関数使用)※1でエラーになる場合は2に設定

# **********************************************************************************
#                     オプション設定終わり ↑ここまで
# ----------------------------------------------------------------------------------
# これ以降書き換えをする場合は、個人の責任で行って下さい。
# **********************************************************************************
# [メイン処理]
binmode(STDOUT);
require $gifcat;
require $jcode;
&read_form;

# ロック開始
if($lock_mode == 1) { &lock1; }
elsif ($lock_mode == 2) { &lock2; }

if (open(FILE,$datefile)) {
  @DATE = <FILE>;
  $log_date = @DATE;
# 最大記録数より多ければ古い記事を削除する
  $m = 0;
  foreach $log (@DATE) {
    $m++;
    if ($m == ($log_day + 1)) { last; }
    push(@NEW,$log);
  }
  @DATE = @NEW;

  $n_count = 1;
  ($date,$count,$total) = split(/,/,$DATE[0]);
  ($now_date) = &time;
  if ($FORM{'t'} == 1) {
    $count = $count + 1;
    $total++;
    $value = "$now_date,$n_count,$total\n";
    if ($now_date eq $date) { $DATE[0] = "$date,$count,$total\n"; }
    else { unshift(@DATE,$value); }
  }
}
if (!open(OUT, ">$datefile")) { &error(bat_file); }
print OUT @DATE;
close (OUT);

# ロック解除
&fileunlock;

foreach $log (@DATE) {
  ($date,$count,$total) = split(/,/,$DATE[0]);
  $count = sprintf("%0" . "$digit1" . "\d",$count);
  $total = sprintf("%0" . "$digit" . "\d",$total);
}
@COUNT_M = split(//, $total);
@COUNT_T = split(//, $count);
$i = 0; $t = 0;
foreach $t (@COUNT_M) {
  $IMG_M[$i] = "$im" . "$t.gif";
  $i ++;
}
$i = 0; $t = 0;
foreach $t (@COUNT_T) {
  $IMG_T[$i] = "$im_s" . "$t.gif";
  $i ++;
}
if ($FORM{'t'} == 3) {
  foreach $log (@DATE) {
    ($date,$count,$total) = split(/,/,$DATE[1]);
    $count = sprintf("%0" . "$digit1" . "\d",$count);
  }
  @COUNT_Y = split(//, $count);
  $i = 0; $t = 0;
  foreach $t (@COUNT_Y) {
    $IMG_Y[$i] = "$im_s" . "$t.gif";
    $i ++;
  }
}

print "Content-type: image/gif\n\n";
if ($FORM{'t'} == 1) { print &gifcat'gifcat(@IMG_M); }
if ($FORM{'t'} == 2) { print &gifcat'gifcat(@IMG_T); }
if ($FORM{'t'} == 3) { print &gifcat'gifcat(@IMG_Y); }

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 time{
  $ENV{'TZ'} = "JST-9";
  ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime();
  $year = $year + 1900;
  $mon = sprintf("%.2d",$mon +1);
  $mday = sprintf("%.2d",$mday);
  $hour = sprintf("%.2d",$hour);
  $min = sprintf("%.2d",$min);
  $sec = sprintf("%.2d",$sec);
# 曜日を日本語化
  @week = ('日','月','火','水','木','金','土');
  $wday = $week[$wday];
  local($date) = "$year年$mon月$mday日";
  return ($date);
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [フォームデータを取得し、文字コード統一]
sub read_form {
  local($pair,$form_date);
  $form_date = $ENV{'QUERY_STRING'};
  local(@pairs) = split(/&/,$form_date);
  foreach $pair (@pairs) {
    local($name,$value) = split(/=/,$pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
    &jcode'convert(*value,'sjis');
    if ($name eq 'get') { push(@DEL,$value); }
    else { $FORM{$name} = $value; }
  }
}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# [エラー関連]
sub error {
  print "Content-type: text/html\n\n";
  print "$_[0]\n";
  # ロック解除
  &fileunlock;
  exit;
}