#!/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:
# 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 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.
#
# 入れ方:
# o カウントを取りたいhtmlのあるディレクトリにこれを入れる。
# o そのhtml専用のカウンタ名を決める。たとえば「hoge」とする。
# o count-hogeというファイルを作る。
# % touch count-hoge; chmod a+w count-hoge
# o 数えたいhtmlに以下の行を埋め込む。
#
# 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 () {
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 () {
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("",
($linkmessage) ?
(($linkmessage eq '%d' ? $count : $linkmessage))
: ($japanese) ? "何人が見てくれたか"
: "How many visitors on this page..",
"\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("",
$_, $_);
}
print "$message\n";
} else {
print "$countdata\n";
}
}
__END__
Local variables:
fill-prefix: "# "
file-coding-system: *euc-japan*
End: