#!/usr/local/bin/perl
# (Change first line to the perl file on your Web server.)
# program name : gcl (graphic counter by cgi and gif images using lock file)
#
# function : count the number of guests and send counter gif file to
# browser.
#
# note : This counter is made for web site where cgi written by perl
# is available and flock of Perl is not available.
# Instead of flock of Perl, symlink is used in this cgi
# If symlik is not available, use link. If link is not
# available, use lock file rename procedure for lock, which
# may not be atomic.
#
# programmer : makoto takenaka : takesoft@mxs.meshnet.or.jp
#
# copyright : (c) 1997 by Takesoft
#
# version(date):
# 1.0(Jan 18, 1997) Made from gcounter version 1.2
# 1.1(Jan 29, 1997) Change (6) to delete lock file even if open
# $countfile failed.
#
# calling form :
#
# or
#
# ,where n means the n-th digit of the counter from the right.
# If cf is not specified, cf=count.txt is supporsed.
#
#(1) set constants.
#
$max_digit = 10;
#
# If absolute dir is required, change $count_dir and $gif_dir such as
# "/home*/user_id/public_html/" or "/home/usr*/user_id/public_html/image/",
# where * is a number.
#
$count_dir = "./"; #directory of count file
$lock_dir = "./lock/"; # directory of lock file
$target_file = $lock_dir."gcltrgt.txt"; # target file of lock
$lock_file = $lock_dir."gcllock.txt"; # lock file
$gif_dir = "./image/"; # directory of gif files
#
#(2) get parameters from string.
#
$buffer = $ENV{'QUERY_STRING'};
#
@pairs = split(/&/, $buffer);
#
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$parameters{$name} = $value;
}
#
$digit = $parameters{'digit'};
$cf = $parameters{'cf'};
unless($cf)
{$cf = "count.txt";} # default value of cf
#
$countfile = $count_dir.$cf; # file of count number
#
#(3) Set $count.
#
open(COUNTFILE, $countfile)
|| &error_mail("(3): Unable to open $countfile as read only file");
$count = ;
close(COUNTFILE);
#
# add ten "0" ahead of $count.
#
$count = "0000000000".$count;
#
#(4) get n-th digit from right in $count
# and send the gif image of the digit.
#
if($digit<1 || $digit > $max_digit)
{&error_mail("(4) wrong position in counter from right, digit = $digit")}
#
$d = substr($count, (-1)*($digit), 1);
#
if($d < 0 || $d > 9)
{&error_mail("(5) wrong number d, d = $d")}
#
$gif_file = $gif_dir."${d}.gif";
#
#(5) send gif file to browser.
#
print "Content-type: image/gif\n\n";
#
# next part is equivalent to
#
# system("/bin/cat $gif_file"); or `/bin/cat $gif_file`;
#
# but not available in meshnet.
#
open(GIF_FILE, $gif_file)
||&error_mail("(5) Unable to open gif file.");
while(read(GIF_FILE, $buf, 16384))
{
print $buf;
}
# print ;
close(GIF_FILE);
#
#(6) Increment $count if $digit is 1.
#
if ($digit == 1)
{
#
#(6.1) Wait a while to be the last completed cgi if $digit is 1.
# If select is not supported in your server, use "sleep(1);"
# to wait 0-1 sec.
#
select(undef, undef, undef, 0.3); # Wait 0.3 sec.
#
#(6.2) Open $countfile and increment $count.
#
if(symlink($target_file, $lock_file))
{
if(open(COUNTFILE, "+< $countfile"))
{
$count = ;
$count = $count + 1;
seek(COUNTFILE, 0, 0);
print COUNTFILE $count;
close(COUNTFILE);
unlink($lock_file);
}
else
{
unlink($lock_file);
&error_mail("(6): Unable to open $countfile");
}
}
}
exit 0;
#
sub error_mail
{
local($message) = @_;
#
#(sub routine) Send error mail.
#
# If you want to use error mail, change mail address to yours
# and uncomment(remove #) next four lines.
# But at some provider such as rimnet, sending mail from cgi may not
# be allowed. At some provider simple mail command may not available.
# In such case, do not mail, but print on some file, which is to be
# prepared with access mask "606".
#
# open(MAIL, "|mail user-id\@xxx.yyyyyyy.or.jp");
# print MAIL "Error Message from gcl.cgi of home page: \n";
# print MAIL "$message\n";
# close(MAIL);
#
# stop this perl program.
#
exit(1);
}