#!/usr/bin/perl

# --------------------------------------
# テキストカウンタ
# $ver = 'ffCow v.1.04';
# 2001/6/22
# (C)2000 Fortunefield
# http://www.gem.hi-ho.ne.jp/fortunefield/
# --------------------------------------

# ======================================
# 定数群
# --------------------------------------
$datadir = "./";          # データディレクトリ名
$datafile = "ffcow.dat";  # データファイル名（初期値）
$lockdir = "./lock/";     # ロックディレクトリ名
$lock = 0;                # ロック機能（0=no, 1=yes）
$nocount = 1;             # 重複カウント防止機能（0=no, 1=yes）

# --------------------------------------
# 書式
$pref_total = 'Total: ';             # 接頭辞（累計）
$pref_today = ' Today: ';     # 接頭辞（今日）
$pref_yeste = ' Yesterday: '; # 接頭辞（昨日）
$fig_total = "%04d";          # 表示桁数（累計）
$fig_today = "%03d";          # 表示桁数（今日）
$fig_yeste = "%03d";          # 表示桁数（昨日）

# --------------------------------------
$ENV{'TZ'} = 'JST-9'; # 時間帯（JST-9=日本時間）

# ======================================
# 手続き
# --------------------------------------
# パラメータをデコード
&decode;

if ($in{'dat'}) { $datafile = $in{'dat'}; }
$datafile = "$datadir$datafile";
$filename = $datafile;
$filename =~ s/^(.*)\///;
$filename =~ s/(.*)\.(.*)$/$1/;
$lockdir = "$lockdir$filename.lock";

# ロック開始
&lock;

# データファイルを読み込み
open(IN, "$datafile") || &error("Open Error: $datafile");
$data = <IN>;
close(IN);

# データを分割
($total, $today, $yeste, $lastmday, $lastaddr) = split(/<>/, $data);

# 日付、アドレスを取得
$mday = (localtime(time))[3];
$addr = $ENV{'REMOTE_ADDR'};

$flag = 0;
if ($nocount == 1 && $mday eq $lastmday && $addr eq $lastaddr) { $flag = 1; }

if ($flag == 0) {
  if ($total eq '') { $total = 0; $today = 0; $yeste = 0; }
  $total++;
  if ($mday eq $lastmday) { $today++; }
  else { $yeste = $today; $today = 1; }

  # データファイルを書き込み
  open(OUT, ">$datafile") || &error("Write Error: $datafile");
  print OUT "$total<>$today<>$yeste<>$mday<>$addr<>";
  close(OUT);
}

# ロック解除
&unlock;

# 書式指定
$prn_total = sprintf($fig_total, $total);
$prn_today = sprintf($fig_today, $today);
$prn_yeste = sprintf($fig_yeste, $yeste);

# ヘッダを出力
&header;

# JavaScriptを出力
if ($in{'prn'}) {
  print <<"JS";
  var prn = $in{'prn'};
  var str = "";
  if (prn >= 1) {
    str += "$pref_total$prn_total";
  }
  if (prn == 2) {
    str += "$pref_today$prn_today";
    str += "$pref_yeste$prn_yeste";
  }
  document.write(str);
JS
} else {
  print <<"JS";
  function ffcow() {
    var a = new Array("$prn_total", "$prn_today", "$prn_yeste");
    return a;
  }
JS
}

exit;

# ======================================
# 関数群
# --------------------------------------
# パラメータをデコード
sub decode {
  local($query, @params, $param, $key, $val);
  $query = $ENV{'QUERY_STRING'};
  @params = split(/&/, $query);
  foreach $param (@params) {
    ($key, $val) = split(/=/, $param);
    $in{$key} = $val;
  }
}

# --------------------------------------
# JavaScript形式ヘッダ出力
sub header {
  print "Content-type: text/javascript\n\n";
}

# --------------------------------------
# ロック
sub lock {
  if ($lock > 0) {
    if (-e $lockdir) {
      if (time - (stat($lockdir))[9] > 300) { rmdir($lockdir); }
    }
    local($retry) = 5;
    while (!mkdir($lockdir, 0755)) {
      if (--$retry <= 0) { &error("Lock is busy"); }
      sleep(1);
    }
  }
}

# --------------------------------------
# ロック解除
sub unlock {
  if ($lock > 0) { rmdir($lockdir); }
}

# --------------------------------------
# エラー処理
sub error {
  &unlock;
  &header;
  print "document.write(\"$_[0]\");\n";
  exit;
}

