Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

simple IP counter..

by coldhawk (Monk)
on Apr 27, 2002 at 16:12 UTC ( #162521=snippet: print w/ replies, xml ) Need Help??

Description: simple counter what counts only one visit from one IP per day...
use strict;
use Fcntl ':flock';
my ($mday,$mon,$year) = (localtime(time))[3,4,5];
$year=$year+1900;
if ($mday < 10) {$mday = "0$mday";}
if ($mon < 10) {$mon = "0$mon";}
my $month = ++$mon;
my $date = "$mday.$month.$year";
my $file = "counter.txt";
my $host = $ENV{'REMOTE_HOST'};
my $ip = $ENV{'REMOTE_ADDR'};
my ($uq,@counter,@counter_data);
open(COUNTER, "$file") || &error("cannot open file for read");
@counter = <COUNTER>;
close(COUNTER);
for(@counter) {
chomp;
@counter_data = split (/\|/, $_);
if ($counter_data[0] eq $date && $counter_data[1] eq $ip && $counter_d
+ata[2] eq $host) { $uq = 1; }
}
if (!$uq) {
open (COUNTER, ">>$file") || &error("cannot open file for write");
flock (COUNTER, 2);
print COUNTER "$date|$ip|$host\n" or die;
close(COUNTER) or die;
}

sub error {
my $error = $_[0];
print "$error\n";
exit;
}
Comment on simple IP counter..
Download Code
Re: simple IP counter..
by Juerd (Abbot) on Apr 27, 2002 at 21:21 UTC

    You do use flock, which is good, but if the file is opened while another instance is in the for()-loop, the counter will in effect only be increased once. To avoid this race condition, you have to write to the file without closeing it after reading. This can be done using a read+write mode.

    sub counter { my ($file) = @_; local *COUNTER; local $/ = undef; open COUNTER, '+<', $file or open COUNTER, '>', $file or return undef; flock COUNTER, 2; seek COUNTER, 0, 0; my $counter = <COUNTER>; seek COUNTER, 0, 0; truncate COUNTER, 0; print COUNTER ++$counter; close COUNTER; return $counter; }
    There are also CPAN modules that do this, but I think modules are overkill for a ++.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: simple IP counter..
by Anonymous Monk on Aug 31, 2009 at 10:30 UTC
    use strict; use Fcntl ':flock'; my ($mday,$mon,$year) = (localtime(time))3,4,5; $year=$year+1900; if ($mday < 10) {$mday = "0$mday";} if ($mon < 10) {$mon = "0$mon";} my $month = ++$mon; my $date = "$mday.$month.$year"; my $file = "counter.txt"; my $host = $ENV{'REMOTE_HOST'}; my $ip = $ENV{'REMOTE_ADDR'}; my ($uq,@counter,@counter_data); open(COUNTER, "$file") || &error("cannot open file for read"); @counter = <COUNTER>; close(COUNTER); for(@counter) { chomp; @counter_data = split (/\|/, $_); if ($counter_data[0] eq $date && $counter_data1 eq $ip && $counter_d +ata2 eq $host) { $uq = 1; } } if (!$uq) { open (COUNTER, ">>$file") || &error("cannot open file for write"); flock (COUNTER, 2); print COUNTER "$date|$ip|$host\n" or die; close(COUNTER) or die; } sub error { my $error = $_[0]; print "$error\n"; exit; }

      For a guess, you're wondering (did you forget to ask a question?) why this won't compile.

      use strict; use Fcntl ':flock'; #792341 my ($mday,$mon,$year) = (localtime(time))[3,4,5]; $year=$year+1900; if ($mday < 10) { $mday = "0$mday"; } if ($mon < 10) { $mon = "0$mon"; } my $month = ++$mon; my $date = "$mday.$month.$year"; my $file = "counter.txt"; my $host = $ENV{'REMOTE_HOST'}; my $ip = $ENV{'REMOTE_ADDR'}; my ($uq,@counter,@counter_data); open(COUNTER, "$file") || &error("cannot open file for read"); @counter = <COUNTER>; close(COUNTER); for(@counter) { chomp; @counter_data = split (/\|/, $_); if ($counter_data[0] eq $date && $counter_data1 eq $ip && $counte +r_d +ata2 eq $host) { $uq = 1; } } if (!$uq) { open (COUNTER, ">>$file") || &error("cannot open file for +write"); flock (COUNTER, 2); print COUNTER "$date|$ip|$host\n" or die; close(COUNTER) or die; } sub error { my $error = $_[0]; print "$error\n"; exit; }

      Some answers, found with perl -c 792341.pl

      Global symbol "$counter_data1" requires explicit package name at 79234 +1.pl line 30. Global symbol "$counter_d" requires explicit package name at 792341.pl + line 30. Bareword "ata2" not allowed while "strict subs" in use at 792341.pl li +ne 30. 792341.pl had compilation errors.

      Please see Writeup Formatting Tips and Markup in the Monastery.

      And it wouldn't hurt to include use warnings; along with strict.

      Update: Missed the missing "[...]". Corrected that and the error messages

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://162521]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (14)
As of 2014-07-23 18:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (150 votes), past polls