#!/usr/bin/perl # # DownCounter+x: CGI Program for counting downloaded times # file: downcntx.cgi # # Copyright (C) 2001 KOMORIYA Takeru # # 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 http://www.paken.org:8080/aaf/download/GPL for more details. # # Contact to author: # KOMORIYA Takeru, AAF Sendai Lab., Japan # E-mail: komoriya@paken.org # URL: http://www.paken.org:8080/ # #--------------------------------------------------------------------- # Ver 1.0(12/15,2001): Changed file invoking method. # Ver 0.9(10/13,2001): Bug fixed for multiple domain. # Ver 0.1(8/21,2001) : First release #------------------------------------------------------------------- # Usage # 1.Save this file as "/cgi-bin/downcntx.cgi". # 2.Edit this file and give correct path to perl(at first line), # give $password, $serverurl and $local_ip. # 3.Change permission of this file "chmod 755 downcntx.cgi" # 4.Create file "touch downcntx.log" and "chmod 666 downcntx.log" # 5.Create directory "mkdir downcntx_data" and "chmod 777 downcntx_data" # # To invoke DownCounter by link: # # ex) # # To show result: # access to "/cgi-bin/downcntx.cgi?mode=view" #------------------------------------------------------------------- # Password for administration $password = 'password'; # Server URL $serverurl ="http://www.yourserver.com"; # Local IP (do not count if accessed from this address) $local_ip ="192.168.1.2"; # Test mode $testmode = 0; # Log file $logfile = './downcntx.log'; # Path for data directory $basedir = './downcntx_data/'; # Lock for inhibit multiple invocation # 0: Don't lock, 1: Lock(symlink), 2: Lock(mkdir) $lock_key = 1; # Lock-file $lockfile = $basedir . ".lock"; #------------------------------------------------------------------- if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $in{$name} = $value; } # Input parameters $url = $in{'url'}; $nickname = $in{'name'}; # Full-path to log file for given name $accesslog = $basedir . $nickname; # View mode if ($in{'mode'} eq "view"){ &report; exit; } # View access-log mode if ($in{'mode'} eq "accesslog"){ if ($password eq $in{'passwd'}){ &report_accesslog; exit; } } # Check wrong file name if ($nickname =~ /[^\w\.+-]|^$/) { &error('ERROR',"Wrong name: $nickname"); } # Accessed from Local PC? if($ENV{'REMOTE_ADDR'} =~ /$local_ip/){ $fromserverurl=0; }else{ $fromserverurl=1; } if (($fromserverurl == 1) || ($testmode == 1)){ # Lock &lock if ($lockkey); # Open and read log-file open(IN,"$logfile") || &error("ERROR","Cannot open logfile."); @lines = ; close(IN); # Increment matched entry $flag=0; @new=(); foreach $line (@lines) { ($name,$count) = split(/\t/, $line); chomp($count); if ($nickname eq "$name") { $flag=1; $count++; $newcount=$count; $line = "$name\t$count\n"; } push(@new,$line); } # Update logfile if ($flag == 1) { open(OUT,">$logfile") || &error("ERROR","Cannot open logfile."); print OUT @new; close(OUT); } # Add to logfile elsif ($flag == 0 && $nickname ne "") { $newcount=1; open(OUT,">>$logfile") || &error("ERROR","Cannot open logfile."); print OUT "$nickname\t$newcount\n"; close(OUT); } # Format Date and Time $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year +=1900; $new_date = sprintf("%04d/%02d/%02d", $year , $mon + 1, $mday); $new_hour = sprintf("%02d:%02d", $hour,$min); # Get remote host if($ENV{'REMOTE_HOST'} !~/[a-zA-Z]/){ $n_host = $ENV{'REMOTE_ADDR'}; $ENV{'REMOTE_HOST'} = gethostbyaddr(pack('C4',split(/\./,$n_host)),2) || $n_host; } # Create access log file for given name if (!-e $accesslog) { if (!open(OUT,"> $accesslog")) { &error('ERROR',"Cannot create: $accesslog"); } $newaccesslog = 1; }else{ if (!open(OUT,">> $accesslog")) { &error('ERROR',"Cannot create: $accesslog"); } } print OUT "$newcount"."\t"; print OUT "$ENV{'REMOTE_HOST'}"."\t"; print OUT "$new_date"."\t"; print OUT "$new_hour"."\n"; close OUT; # Change file permission if ($newaccesslog == 1) { chmod(0666,$accesslog); } # unlock &unlock if ($lockkey); } if($fromserverurl == 1){ $url = $serverurl . $url; }else{ $url = "http://" . $local_ip . $url; } # invoke target file print <<"EOF"; Content-type: text/html ダウンロード
↓右クリックして保存してください.

$url

EOF exit; sub lock { local($retry)=5; # delete old lock (older than 3 minutes) if (-e $lockfile) { ($mtime) = (stat($lockfile))[9]; if ($mtime && $mtime < time - 180) { &unlock; } } # symlink lock if ($lockkey == 1) { while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('Server Busy',"Please retry later."); } sleep(1); } # mkdir lock } elsif ($lockkey == 2) { while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error('Server Busy',"Please retry later."); } sleep(1); } } } sub unlock { if ($lockkey == 1) { unlink($lockfile); } elsif ($lockkey == 2) { rmdir($lockfile); } } sub error { if (-e $lockfile) { unlink($lockfile); } print "Content-type: text/html\n\n"; print "\n"; print "

$_[0]

\n"; print "

$_[1]

\n"; print "\n"; exit; } sub report { # Lock &lock if ($lockkey); # Open and read log-file open(IN,"$logfile") || &error("ERROR","Cannot open logfile."); @lines = ; close(IN); # Unlock &unlock if ($lockkey); print "Content-type: text/html\n"."\n"; print <<"__HEAD__"; Download Count

Download Statistics

__HEAD__ # Print entries foreach $line (@lines) { ($name,$count) = split(/\t/, $line); print ""; if ($password eq $in{'passwd'}){ print ""; }else{ print ""; } print ""; print "\n"; } print <<"__FOOT__";
Name Count
"; print "$name$name$count

__FOOT__ } sub report_accesslog { # Lock &lock if ($lockkey); # Open and read log-file open(IN,"$accesslog") || &error("ERROR","Cannot open access-log file."); @lines = ; close(IN); # Unlock &unlock if ($lockkey); print "Content-type: text/html\n"."\n"; print <<"__HEAD__"; Download Log of $nickname

Download Log of $nickname

__HEAD__ # Print entries foreach $line (@lines) { ($count,$host,$date,$time) = split(/\t/, $line); print ""; print ""; print ""; print ""; print ""; print "\n"; } print <<"__FOOT__";
Count Host Date Time
$count$host$date$time
__FOOT__ }