#!/usr/bin/perl
#
# BANNERMATIC 3 - Version using IP Addresses
#
# Operates rotating banners and tracks display and click-thru stats.
# IMG<->URL associated by session IP addresses and banner numbers.
#
# Filename: banmat3.cgi
# Copyright: 1997-2006 Joe DePasquale
# Last Revised: September 15, 2006
# E-Mail: crypt@getcruising.com
# Website: http://www.getcruising.com
#
# See the document 'how2ban.txt' for set-up instructions.
#
########################################################################
# #
# This script and accompanying files may be distributed freely #
# and modified, provided this header with my name, E-Mail address and #
# this notice remain intact. Ownership rights remain with me. You may #
# not sell this script without my approval. #
# #
# This script comes with no guarantee or warranty except for my good #
# intentions. By using this code you agree to indemnify me from any #
# liability that might arise from it's use. #
# #
# There is no technical support for this script, neither am I a #
# professional programmer. Refer to 'HELPME.TXT' for general guidance.
# #
########################################################################
# CONFIGURE SCRIPT -
#
# Change the sample paths to the actual paths on your server:
# Your Unix system sendmail command and email address
$mailCmd = '/usr/lib/sendmail';
$myMail = 'yourmail@yourdomain.com';
# Unix path to banmat data directory
$banmatDir = '/usr/home/yourpath/banmat';
# OPTIONAL - YOU CAN EDIT THESE VARIABLES IF DESIRED:
$headTitle = "BANNERMATIC3: IP Version";
$bodyTag = qq|<body class=g>|;
$bodyTitle = qq|<b><i><font size=5><font color="#0000FF">BANNERMATIC3 </font><font color="#006600">IP Version</font></font></i></b>|;
# [Optional] URL to the styleheet
$styleUrl = '/www.css';
# If you use 'group' codes and no banner is found with the required
# code, which banner number (in ban.dat) should be defaulted to?
$failBan = 0;
# If you want a signature file attached to mail messages,
# uncomment the next line and enter its Unix path ..
# $MYSIG = '/usr/home/yourpath/mysig.txt';
# .. otherwise uncomment the next 2 lines and replace with your info ..
# $myName = "Bonzo Clone";
# $homeUrl = "http://www.getcruising.com";
# Go to this URL when exiting manager
$exitUrl = '/';
# Browser will keep retrieving same banner associated with a pagecode
# until banner is deleted from cache. If using animated GIF's you should
# set to 'Y' to avoid 'slideshow'. Otherwise use 'N' (but try both!)
$cacheFlag = 'Y';
# Daily maintenance of banip.dat is done when the first visitor runs
# the script between $admon and $admoff. Use 24-hour time from
# 1 to 23 (1 AM to 11PM). If confooosed, just use the defaults.
$admon = 1; $admoff = 23;
# END OF INSTALLATION - SHOULD NOT CHANGE STUFF BELOW THIS LINE
########################################################################
($ss,$mm,$hh,$dd,$mo,$yyyy,$d,$jjj,$b) = localtime (time);
$mo++; $yyyy+=1900;
$timeStamp = localtime (time);
$dateStamp = $yyyy.sprintf("%02d",$mo).sprintf("%02d",$dd);
$hourStamp = sprintf("%02d",$hh);
$dowStamp = $d;
$scriptUrl = $ENV{'SCRIPT_NAME'};
$BANDAT = "$banmatDir/bandat.txt";
$BANFLK = "$banmatDir/banflk.txt";
$BANLOG = "$banmatDir/ban.log";
$BANUNDO = "$banmatDir/banbak.txt";
$BANPWD = "$banmatDir/banpwd.txt";
$IPCNT = "$banmatDir/banipcnt.txt";
$IPDAT = "$banmatDir/banipdat.txt";
########################################################################
# Get stuff and read input from query string
if ($ENV{'QUERY_STRING'} eq 'manager' || $ENV{'REQUEST_METHOD'} eq 'POST')
{ require "banman.pl";
&banman;
exit;
} elsif ($ENV{'QUERY_STRING'} =~ /(\S+?)(\+(\S))?=(\S+?)(&.*|$)/)
{ $pagecode =$1; $group =$3; $command =$4;
} else
{ &endIt;
}
open (LOCK,">$BANFLK") || &endIt;
if (!flock (LOCK,2)) { &endIt; }
######################################################################
# Case: Send banner Image to browser
if ($command eq 'IMG')
{
# Get the banner info
open (DAT,"+<$BANDAT") || &endIt;
flock (DAT,2); seek (DAT,0,0);
@banFile = <DAT>;
srand (time^$$);
@ndx = (0..$#banFile);
while ((!defined $banNbr) && $#ndx >=0)
{
$x = int (rand($#ndx +1));
@banLine = split(/\|/,$banFile[$ndx[$x]]);
if ($banLine[4] =~ /$group/)
{ $banNbr = $ndx[$x];
} else
{ splice (@ndx,$x,1);
}
}
if (!defined $banNbr)
{ $banNbr = $failBan;
@banLine = split(/\|/,$banFile[$banNbr]);
}
# count the impression
$banLine[3] ++;
$banFile[$banNbr] = join ("\|",@banLine);
seek (DAT,0,0);
print (DAT @banFile);
truncate (DAT,tell(DAT)); close (DAT);
$imageExt = substr ($banLine[1],rindex ($banLine[1],".")+1);
if (!$imageExt) { $imageExt = 'jpeg'; }
# send image to browser
if ($cacheFlag eq "N")
{ print "Expires: Wed, 01 Jan 1997 12:00:00 GMT\n";
}
print "Content-type: image/$imageExt\n";
print "Location: $banLine[1]\n\n";
# record the IP nbr and banner nbr
open (IPDAT,"+<$IPDAT") || &endIt;
flock (IPDAT,2); seek (IPDAT,0,0);
@ipFile = <IPDAT>;
# IP file maintenance if due
if ($admoff > $hourStamp && $admon <=$hourStamp)
{ @oldIpFile = @ipFile;
open (IPCNT,"+<$IPCNT") || &endIt;
flock (IPCNT,2); seek (IPCNT,0,0);
$ipDay = <IPCNT>;
chop ($ipDay) if ($ipDay =~ /\n$/);
if ($ipDay +0 != $dowStamp +0)
{ foreach $test (@oldIpFile)
{ @ipLine = split (/\|/,$test);
if ($ipLine[3]+0 != $dowStamp+0) { $test = ""; }
}
@ipFile = sort {$a cmp $b} @oldIpFile;
seek (IPDAT,0,0);
print (IPDAT @ipFile);
truncate (IPDAT,tell(IPDAT));
seek (IPCNT,0,0);
print (IPCNT "$dowStamp\n");
truncate (IPCNT,tell(IPCNT));
}
close (IPCNT);
}
$remote = $ENV{'REMOTE_ADDR'};
$foundFlag = 0; $recNbr = 0;
do
{ @ipLine = split (/\|/,$ipFile[$recNbr]);
if ("$remote\|$pagecode" eq "$ipLine[0]\|$ipLine[1]")
{ $ipFile[$recNbr] = join ("\|",$remote,$pagecode,$banNbr,$dowStamp,"\n");
$foundFlag = 1;
} else
{ $recNbr ++;
}
} while (!$foundFlag && $remote ge $ipLine[0] && $recNbr <= $#ipFile);
if (!$foundFlag)
{ $newLine = join ("\|",$remote,$pagecode,$banNbr,$dowStamp,"\n");
push @ipFile, $newLine;
}
@newIpFile = sort {$a cmp $b} @ipFile;
seek (IPDAT,0,0);
print (IPDAT @newIpFile);
truncate (IPDAT,tell(IPDAT)); close (IPDAT);
} # end IMG
######################################################################
# Case: Get bannerNbr from address file or fail. Send browser to URL
elsif ($command eq "URL")
{
open (IPDAT,"+<$IPDAT") || &endIt;
flock (IPDAT,2); seek (IPDAT,0,0);
@ipFile = <IPDAT>;
$remote = $ENV{'REMOTE_ADDR'};
$foundFlag = 0; $recNbr = 0;
do
{ @ipLine = split (/\|/,$ipFile[$recNbr]);
if ($remote eq $ipLine[0] && $pagecode eq $ipLine[1])
{ $banNbr = $ipLine[2];
$ipFile[$recNbr] = join ("\|",$remote,$pagecode,$banNbr,$dowStamp,"\n");
$foundFlag = 1;
@newIpFile = sort {$a cmp $b} @ipFile;
seek (IPDAT,0,0);
print (IPDAT @newIpFile);
truncate (IPDAT,tell(IPDAT));
} else
{ $recNbr ++;
}
} while (!$foundFlag && $remote ge $ipLine[0] && $recNbr <= $#ipFile);
close (IPDAT);
if ($foundFlag)
{ open (DAT,"+<$BANDAT") || &endIt;
flock (DAT,2); seek (DAT,0,0);
@banFile = <DAT>;
@banLine = split(/\|/,$banFile[$banNbr]);
# count the click-thru
$banLine[2] ++;
$banFile[$banNbr] = join ("\|",@banLine);
seek (DAT,0,0);
print (DAT @banFile);
truncate (DAT,tell(DAT)); close (DAT);
# send browser to URL for IMG
print "Content-type: text/html\n";
print "Location: $banLine[0]\n\n";
# log the click-thru
$banLog = join ("\|",$timeStamp,$banLine[0],$pagecode,$group,$ENV{'REMOTE_ADDR'});
open (LOG,">>$BANLOG");
flock (LOG,2); seek (LOG,0,2);
print (LOG "$banLog\n");
close (LOG);
} else # ip address not in file
{ print "Content-type: text/html\n\n";
print qq|<html>\n<body bgcolor="#FFFFFF" text="#000099">\n|;
print "<font size=5>SORRY</font><p>";
print "<b>Unable to associate banner with sponsor location.<br>\n";
print "Please use your browser's [BACK] button and [RELOAD] a new banner.</b>\n";
print "<p>\n</body></html>\n";
}
} # end URL
close (LOCK);
exit; # end program
######################################################################
sub endIt # error handling for user script
{ exit;
}