#!/usr/local/bin/perl
# Visitor counter for SSI-exec usage
# (c)1997,1999 by HIROSE Yuuji [yuuji@gentei.org]
# $Id: countup,v 1.7 2002/12/01 15:53:44 yuuji Exp $
# Last modified Mon Dec  2 00:45:14 2002 on firestorm
# 
# Usage:  <!--#exec cmd="./countup CounterName"-->
# Options:
#	-l		display link for counter file
#	-lm MSG		change anchor string to MSG
# 			%d is replaced to count number itself
#	-s		display counter number itself silently
#	-j		japanese message(jis)
#	-je		japanese message(euc)
#	-n		no increment
#	-x PTN		ignore access from the address matching with PTN
#	-d DIR		set couter file's directory to DIR(default = ".")
#	-unko		display unko message
#	-gif -png -jpg	display counter in <img src> format
#			You need 0.jpg through 9.jpg or so.  This option
#			should be combined with -unko
#	-b DIR		set counter image file location to directory DIR
# Install:
#	o Put this script into your WWW contents directory.
#	o Determine the counter name of html file.  `foo' for example.
#	o Create `count-foo' file and make it writable by httpd.
#	  (ex.)% touch count-foo; chgrp www count-foo; chmod g+w count-foo
#	o Write SSI-exec line in the file you want to count access.
#	  <!--#exec cmd="./countup foo"-->
# 入れ方:
#	o カウントを取りたいhtmlのあるディレクトリにこれを入れる。
#	o そのhtml専用のカウンタ名を決める。たとえば「hoge」とする。
#	o count-hogeというファイルを作る。
#	  % touch count-hoge; chmod a+w count-hoge
#	o 数えたいhtmlに以下の行を埋め込む。
#	  <!--#exec cmd="./countup hoge"-->
#	o すると count-hoge というファイルにアクセス数が保存される。
# Lamborghini Countach


$nkf		= "/usr/local/bin/nkf";
$countdir	= ".";
$countprefix	= "count-";
$excludefile	= "count_x";
$imagebase	= ".";
$imageext	= "";

$retry		= 10;

while ($_=$ARGV[0] =~ /^-[A-z]/ && shift) {
    last if /^--$/;
    while (/^-[A-z]/) {
	$optlen = 1;
	if (/^-lm/) {
	    $linkmessage = shift; $_='';
	} elsif (/^-l/) {
	    $displink = 1;
	} elsif (/^-s/) {
	    $simple = $unko = 1;
	} elsif (/^-je/) {
	    $japanese = $optlen = 2;
	} elsif (/^-j/) {
	    $japanese = $jis = 1;
	} elsif (/^-unko/) {
	    $unko = $optlen = 4;
	} elsif (/^-n/) {
	    $noincrement = 1;
	} elsif (/^-x/) {
	    $exclude = shift; $_='';
	} elsif (/^-d/) {
	    $countdir = shift; $_='';
	} elsif (/^-b/) {
	    $imagebase = shift; $_='';
	} elsif (/^-(gif|jpg|png)/) {
	    s/-//;
	    $imageext = $_;
	}
	for ($i=0; $i<$optlen; $i++) {
	    s/^-.(.*)/-$1/;
	}
    }
}

unless ($ARGV[0]) {
    print("Usage: coutup CounterName\n");
    exit(0);
}


$countfile	= "$countdir/$countprefix$ARGV[0]";
$lockfile	= "/tmp/$countprefix$ARGV[0]";

if ($ENV{"REMOTE_ADDR"}) {
    $remoteaddr = "$ENV{REMOTE_ADDR}";
} else {
    $remoteaddr = "Unknown";
}
while (-f $lockfile && $retry-- > 0) {
    sleep 1;
}
if (-f $lockfile) {
    if (time - (lstat($lockfile))[10] > 300) { # 5分くらいかな
	unlink($lockfile);		  # 初回は消すだけで終わっとこう
    }
    exit 1;
}
symlink($countfile, $lockfile);		#すぐlock

if (open(CNT, "< $countfile")) {
    while (<CNT>) {
	chop;
	if (/^(\d+) accesses since (\d+)/) {
	    ($count, $since) = ($1, $2);
	} elsif (/ast access from (\S+)/) {
	    $lastaccess = $1;
	}
    }
    close(CNT);
}
unless ($since) {
    $since = `/bin/date '+%Y%m%d'`;
    chop($since);
}
if (open(X, "< $countdir/$excludefile")) {
    while (<X>) {
	chop;
	$exclude .= $_;
    }
    close(X);
}

unless ("$lastaccess" eq "$remoteaddr"
	|| $noincrement
	|| ($exclude && $remoteaddr =~ /$exclude/)) {
    $count++;
}

open(CNT, "> $countfile") || die "Cannot open $countfile to write\n";
print CNT "$count accesses since $since\n";
print CNT "Last access from $remoteaddr";
print CNT " $ENV{REMOTE_HOST}" if ($ENV{"REMOTE_HOST"});
print CNT "\n";
close(CNT);
unlink($lockfile);
#chmod(0666, $countfile);

if ($displink) {
    print("<a href=$countfile>",
	  ($linkmessage) ?
	  (($linkmessage eq '%d' ? $count : $linkmessage))
	  : ($japanese) ? "何人が見てくれたか"
	  : "How many visitors on this page..",
	  "</a>\n");
} elsif ($unko) {
    if ($simple) {
	print "$count\n";
    } elsif ($japanese) {
  	($y, $m, $d) = ($since=~/(\d\d)(\d\d)(\d\d)/);
  	$m+=0; $d+=0;			  # Numerize
  	$message =
	  sprintf("%4d年%d月%d日から数えて%d回目の参照\n",
	    $y+1900, $m, $d, $count);
  	$message = `echo -n "$message" | $nkf -n` if ($jis);
  	print $message;
    } elsif ($imageext) {
	$message = "";
	local($cstring, $p);
	$cstring = sprintf("%d", $count);
	$len = length($cstring);
	for ($p=0; $p < length($cstring); $p++) {
	    $_ = substr($cstring, $p, 1);
	    $message
	      .= sprintf("<img src=\"$imagebase/%s.$imageext\" ALT=\"%s\">",
			 $_, $_);
	}
	print "$message\n";
    } else {
	print "$countdata\n";
    }
}

__END__
Local variables:
fill-prefix: "# "
file-coding-system: *euc-japan*
End:
