#!/usr/local/bin/perl
#######################################################################
# Multicount Version 2.1 #
# Copyright 1998-2000 by Matt Riffle All Rights Reserved. #
# Initial Full Release: 7/4/98 This Release: 4/28/00 #
# pingPackets Script Archive http://www.pingpackets.com/ #
#######################################################################
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 2 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. It is included in #
# this distribution in the file "license.txt". #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #
# 02111-1307, USA. #
#######################################################################
## Set the variables below accordingly ##
# This is the directory in which the script will keep its data files.
# It should be chmod 777, or what is needed to ensure the server can write
# to it.
$data_dir = './user';
# If your system can use "flock" to lock data files, set this to 1.
# Otherwise, set it to zero. If you are unsure, try 1 first, and if
# the script is failing try setting it to 0. If, and only if, you
# are having counter reset problems, set this to 2. See the manual
# for more details on the alternate locking scheme (the server must be
# able to create subdirectories in your data directory for it to work).
$locking = 1;
# The counts can be reported in various styles. To use normal numbers,
# specify 'numeric' or do not set this variable. To use numbers with
# commas inserted at the correct points, specify 'commas'. To use
# Roman numerals, specify 'roman'. For hexadecimal numbers, specify
# 'hex'. For binary, use 'binary'.
$style = 'numeric';
# This is the format in which the output will be result. Put
# OVERALL where you want the total count, DAILY where you want the
# daily count, and WEEKLY where the weekly count should go, MONTHLY
# for monthly count, and YEARLY for yearly count. If you
# don't want a certain count, just omit its keyword.
$format = '
 |
วันนี้ |
DAILY คน |
 |
สัปดาห์นี้ |
WEEKLY คน |
 |
เดือนนี้ |
MONTHLY คน |
 |
ปีนี้ |
YEARLY คน |
 |
รวมทั้งหมด |
OVERALL คน |
';
# If this is set to 1, the last IP address to access the counter will be
# cached to prevent one person from repeatedly updating the counter. If
# it is set to 0, one person can increment the counter multiple times in
# succession.
$ip_caching = 0;
###### DO NOT EDIT BELOW THIS LINE ######
&init;
exit;
sub init {
my ($name,$file,$dstamp,$wstamp);
if ((!$ENV{'DOCUMENT_URI'}) && (!$ENV{'REQUEST_URI'})) {
&error('Web Server Missing Vital ENV Vars!'); # hopeless
}
if (!$ENV{'DOCUMENT_URI'}) {
$ENV{'DOCUMENT_URI'} = $ENV{'REQUEST_URI'}; # catch weird cases
}
$ENV{'DOCUMENT_URI'} =~ s/[^\w]/_/g;
$ENV{'DOCUMENT_URI'} =~ s/[\0]//g;
if (length($ENV{'DOCUMENT_URI'}) > 240) {
$name = substr($ENV{'DOCUMENT_URI'},0,240);
} else {
$name = $ENV{'DOCUMENT_URI'};
}
$name .= '.cnt';
$file = "$data_dir/$name";
if (!-e $file) {
open (FILE,">$file") || &error('creating file');
if ($locking == 2) { &lock($file) || &error('locking file'); }
elsif ($locking) { flock(FILE,2) || &error('locking file'); }
$dstamp = &dstamp;
$wstamp = &wstamp;
print FILE "1:1:1:1:1:$dstamp:$wstamp:$ENV{'REMOTE_ADDR'}";
if ($locking == 1) { flock(FILE,8) || &error('unlocking file'); }
close (FILE) || &error('closing file');
if ($locking == 2) { &unlock($file) || &error('unlocking file'); }
return &init_report;
} else {
return &update($file);
}
}
sub update {
my $file = shift;
if ($locking == 2) { &lock($file) || &error("locking file $!"); }
open (FILE,"<$file") || &error('reading file');
if ($locking == 1) { flock(FILE,2) || &error('locking file'); }
my $line = ;
if ($locking == 1) { flock(FILE,8) || &error('unlocking file'); }
close(FILE);
if ($locking == 2) { &unlock($file) || &error('unlocking file'); }
my ($overall,$daily,$weekly,$monthly,$yearly,$fdstamp,$fwstamp,$ip)
= split(/:/,$line);
my $dstamp = &dstamp;
my $wstamp = &wstamp;
my ($y,$m) = ($dstamp =~ /^(\d\d\d\d)(\d\d)/);
my ($fy,$fm) = ($fdstamp =~ /^(\d\d\d\d)(\d\d)/);
if ($fy < $y) { $yearly = 0; }
if ($fm < $m) { $monthly = 0; }
if ($fdstamp < $dstamp) { $daily = 0; $fdstamp = $dstamp; }
if ($fwstamp < $wstamp) { $weekly = 0; $fwstamp = $wstamp; }
if ((!$ip_caching) || ($ENV{'REMOTE_ADDR'} ne $ip)) {
$overall++; $daily++; $weekly++; $monthly++; $yearly++;
}
if ($locking == 2) { &lock($file) || &error('locking file'); }
open (FILE,">$file") || &error("writing file");
if ($locking == 1) { flock(FILE,2) || &error('locking file'); }
print FILE "$overall:$daily:$weekly:$monthly:$yearly";
print FILE ":$fdstamp:$fwstamp:$ENV{'REMOTE_ADDR'}";
if ($locking == 1) { flock(FILE,8) || &error('unlocking file'); }
close (FILE) || &error("closing file");
if ($locking == 2) { &unlock($file) || &error('unlocking file'); }
&report($overall,$daily,$weekly,$monthly,$yearly);
}
sub dstamp {
local($day,$mon,$year,$z1,$z2);
$z1 = $z2 = "";
(undef,undef,undef,$day,$mon,$year,undef,undef,undef) = localtime(time);
$mon++; $year += 1900;
if ($mon < 10) { $z1 = '0'; }
if ($day < 10) { $z2 = '0'; }
return "$year$z1$mon$z2$day";
}
sub wstamp {
local($check,$jump,$day,$mon,$year,$z1,$z2);
(undef,undef,undef,undef,undef,undef,$check,undef,undef) = localtime(time);
$check = 7 - $check;
$jump = $check * 86400;
$z1 = $z2 = "";
(undef,undef,undef,$day,$mon,$year,undef,undef,undef) = localtime(time+$jump);
$mon++; $year += 1900;
if ($mon < 10) { $z1 = '0'; }
if ($day < 10) { $z2 = '0'; }
return "$year$z1$mon$z2$day";
}
sub report {
my ($overall,$daily,$weekly,$monthly,$yearly);
if ($style) {
if ($style eq 'commas') {
($overall,$daily,$weekly,$monthly,$yearly) = &commas(@_);
} elsif ($style eq 'roman') {
($overall,$daily,$weekly,$monthly,$yearly) = &roman(@_);
} elsif ($style eq 'hex') {
($overall,$daily,$weekly,$monthly,$yearly) = &hex(@_);
} elsif ($style eq 'binary') {
($overall,$daily,$weekly,$monthly,$yearly) = &binary(@_);
} else {
($overall,$daily,$weekly,$monthly,$yearly) = @_;
}
} else {
($overall,$daily,$weekly,$monthly,$yearly) = @_;
}
print 'Content-type: text/html',"\n\n";
$format =~ s/OVERALL/$overall/ig;
$format =~ s/DAILY/$daily/ig;
$format =~ s/WEEKLY/$weekly/ig;
$format =~ s/MONTHLY/$monthly/ig;
$format =~ s/YEARLY/$yearly/ig;
print $format;
exit;
}
sub init_report {
if ($style eq 'roman') { $one = "I"; }
else { $one = 1; }
print 'Content-type: text/html',"\n\n";
$format =~ s/(OVERALL|DAILY|WEEKLY|MONTHLY|YEARLY)/$one/ig;
print $format;
}
sub error {
my $error = shift;
print 'Content-type: text/html',"\n\n";
print "[Error : $error]";
exit;
}
sub commas {
my ($num,@result);
foreach $num (@_) {
$num = reverse $num;
$num =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
push(@result,scalar reverse $num);
}
return @result;
}
sub hex {
my ($num,@result);
foreach $num (@_) {
$num = sprintf("%x",$num);
$num =~ tr/a-f/A-F/;
push (@result,$num);
}
return @result;
}
sub binary {
my ($num,@result);
foreach $num (@_) {
$num = unpack("B32", pack("N",$num));
$num =~ s/^0+(?=\d)//;
push (@result,$num);
}
return @result;
}
sub roman {
my ($num,@result);
@roman1 = ('I','II','III','IV','V','VI','VII','VIII','IX');
@roman10 = ('X','XX','XXX','XL','L','LX','LXX','LXXX','XC');
@roman100 = ('C','CC','CCC','CD','D','DC','DCC','DCCC','CM');
foreach $num (@_) {
my $rnum = '';
my $n1 = $num % 10; $num = ($num-$n1) / 10;
my $n10 = $num % 10; $num = ($num-$n10) / 10;
my $n100 = $num % 10; $num = ($num-$n100) / 10;
my $c = 0;
while ($c < $num) { $rnum .= 'M'; $c++; }
if ($n100) { $rnum .= @roman100[$n100-1]; }
if ($n10) { $rnum .= @roman10[$n10-1]; }
if ($n1) { $rnum .= @roman1[$n1-1]; }
push (@result,$rnum);
}
return @result;
}
sub lock {
my $file = shift;
$file .= ".lock";
if (mkdir($file,0755)) { return 1; }
for ($i = 0; $i < 5; $i++) {
sleep(1);
if (mkdir($file,0755)) { return 1; }
}
return 0;
}
sub unlock {
my $file = shift;
$file .= ".lock";
return rmdir($file);
}