Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Guestbook IP Check Script

Status
Not open for further replies.

xmassey

Programmer
Apr 9, 2007
62
0
0
GB
Hey guys,

I have created a very basic Guestbook script that works effectively. I have one problem, I have a spammer who loves to spam my guestbook with adverts so I needed to change my script so that A) The user has to enter a random digit before the message can be posted, and B) it checks the users IP and if the ip has posted a message already then it won't let them post another. THE ONLY PROBLEM I AM HAVING is that basically once a user posts an entry it creates a txt file named under their IP and writes in the file the word "fail". So if the user posts another the script says that if the file says "fail" then dont let them post another entry else let them post. However, my problem is that the ip checker doesnt work and even though "fail" is printed in the txt file, the script will pass anyone even if they have posted already... Please check my script and suggest what i may need to change (if possible accept my very simple method of perl scripting). Thanks

#! /usr/bin/perl
use strict;
use CGI ':standard';

my ($arandom, $acarryrandom);

$arandom = param('random');
$acarryrandom = param('carryrandom');

my $IP = $ENV{'REMOTE_ADDR'};

open (LOG, ">>/path/TVTown.co.uk/Guestbook/IP/$IP.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
print LOG "";
close (LOG);

open (LOG, "</path/TVTown.co.uk/Guestbook/IP/$IP.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @ip = <LOG>;
close (LOG) || Error ('close', 'file');

if (@ip eq "fail") {
print "Content-type: text/html\n\n";
print "<font face=arial size=2>You cannot post another Guestbook entry at this time.</font>";
}

else {

if ($arandom eq $acarryrandom) {

open (LOG, ">/path/TVTown.co.uk/Guestbook/IP/$IP.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
print LOG "fail";
close (LOG);

my ($aname, $aemail, $acomments, $timedate);
my ($sec, $min, $hour, $mday, $mon, $year)=gmtime;

$aname = param('name');
$aemail = param('email');
$acomments = param('comments');
$timedate = sprintf ('%02d:%02d:%02d <b>(</b>%02d/%02d/%4d<b>)</b> GMT', $hour, $min, $sec, $mday, $mon+1, $year+1900);

open (LOG, ">>/path/TVTown.co.uk/Guestbook/logfile2.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
print LOG " <b>Name</b>--<font color=red>$aname <<b>$timedate</b>></font>\n <b>Email</b>--$aemail\n <b>Comments</b>--$acomments\n<b>_____________________</b>\n";
close (LOG);

print "Content-type: text/html\n\n";
print "<font face=arial size=2><P><font color=blue><b><u>Your entry has been added... @ip</u></b></font>";
print "<font face=arial size=2><P><b>Name:</b> $aname";
print "<font face=arial size=2><P><b>Email:</b> $aemail";
print "<font face=arial size=2><P><b>Comments:</b> $acomments\n";

print qq(<HR><A HREF="index.pl">(Add Entry)</A> <A HREF="view.pl">(View Guestbook)</A>);

sub Error {
print "Content-type: text/html\n\n";
print "The server can't $_[0] the $_[1]: $! \n";
exit;
}
}

else {
print "Content-type: text/html\n\n";
print "<font face=arial size=2>The digits you typed are incorrect - Click back in your browser and try again.</font>";
}

print "";
}
 
Within your method ( A file for each IP address), surely all you need to do is to check for the existence of the file ?

Code:
if( -e "/path/TVTown.co.uk/Guestbook/IP/$IP.txt") {
  #fail code
} else {
  #continue code
}

If you want to actually check that the file contains 'fail' in the first line:

[code]open (LOG, "</path/TVTown.co.uk/Guestbook/IP/$IP.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my $firstline = <LOG>;
close (LOG) || Error ('close', 'file');
if( $firstline =~ /fail/ ) {
  #fail code
} else {
  #continue code
}

Or... if you want to check the whole file for the existence of 'fail':
Code:
open (LOG, "</path/TVTown.co.uk/Guestbook/IP/$IP.txt") || Error('open', 'file');
flock (LOG, 2) || Error('lock', 'file');
my @ip = <LOG>;
close (LOG) || Error ('close', 'file');
if( map {/fail/} @ip ) {
  #fail code
} else {
  #continue code
}
 
Thank you very much - I can now see how you have made use of \fail\ to locate the word fail. I have now also limited the characters to 200 max because the spammer usually uses over 1000, and so the spambot is now unable to spam my guestbook :D
 
how would I do the same thing, but instead of creating a file per IP. Can I use an array from a single file storing all IPs or something?
 
If your file (loggedIPs.txt) is just going to contain IP's:
Code:
[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url] [red]([/red]LOG, [red]"[/red][purple]</path/TVTown.co.uk/Guestbook/IP/loggedIPs.txt[/purple][red]"[/red][red])[/red] || [maroon]Error[/maroon][red]([/red][red]'[/red][purple]open[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
[url=http://perldoc.perl.org/functions/flock.html][black][b]flock[/b][/black][/url] [red]([/red]LOG, [fuchsia]2[/fuchsia][red])[/red] || [maroon]Error[/maroon][red]([/red][red]'[/red][purple]lock[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]@loggedIP[/blue] = <LOG>[red];[/red]
[url=http://perldoc.perl.org/functions/close.html][black][b]close[/b][/black][/url] [red]([/red]LOG[red])[/red] || [maroon]Error[/maroon] [red]([/red][red]'[/red][purple]close[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
[olive][b]if[/b][/olive][red]([/red] [url=http://perldoc.perl.org/functions/map.html][black][b]map[/b][/black][/url] [red]{[/red][red]/[/red][purple][blue]$IP[/blue][purple][b]\n[/b][/purple][/purple][red]/[/red][red]}[/red] [blue]@loggedIP[/blue] [red])[/red] [red]{[/red]
  [gray][i]#fail code[/i][/gray]
[red]}[/red] [olive][b]else[/b][/olive] [red]{[/red]
  [gray][i]#continue code[/i][/gray]
  [black][b]open[/b][/black] [red]([/red]LOG, [red]"[/red][purple]>>/path/TVTown.co.uk/Guestbook/IP/loggedIPs.txt[/purple][red]"[/red][red])[/red] || [maroon]Error[/maroon][red]([/red][red]'[/red][purple]open[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
  [black][b]flock[/b][/black] [red]([/red]LOG, [fuchsia]2[/fuchsia][red])[/red] || [maroon]Error[/maroon][red]([/red][red]'[/red][purple]lock[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
  [url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] LOG, [red]"[/red][purple][blue]$IP[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
  [black][b]close[/b][/black] [red]([/red]LOG[red])[/red] || [maroon]Error[/maroon] [red]([/red][red]'[/red][purple]close[/purple][red]'[/red], [red]'[/red][purple]file[/purple][red]'[/red][red])[/red][red];[/red]
[red]}[/red]

You could probably optimize the file modes so you don't have to open/lock/close the file twice.
 
Code:
my $ip = "127.0.0.6";
my $found ;
open LOG, "+<loggedIPs.txt" or die("Unable to open file");
flock LOG,2 or die("Unable to lock file");
print LOG "$ip\n" unless ($found = map {/$ip\n/} <LOG>);
close LOG;
if($found) {
	# ... IP was found ...
} else {
	# ... IP was added ...
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top