#!/usr/bin/perl
#
# SmoothWall CGIs
#
# This code is distributed under the terms of the GPL
#
# (c) The SmoothWall Team
#
# $Id: urlfilter.dat,v 1.4 2005/05/15 00:00:00 marco Exp $
#

use strict;

# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';

use POSIX();

require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";

my %color = ();
my %mainsettings = ();
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);

my $dbdir = "${General::swroot}/urlfilter/blacklists";
my $logdir = "/var/log/squidGuard";

my %cgiparams=();
my %logsettings=();
my %filtersettings=();
my %selected=();

my $errormessage='';

my @log=();
my $logarch='';
my $date='';
my $time='';
my $pid='';
my @loginfo=();
my @ip=();
my @category=();
my $dsturl='';
my $site='';
my $attr1='';
my $attr2='';

my $start=0;
my $prev=0;
my $next=0;
my $lines=0;
my @slice=();

my @then=();
my @temp=();
my @temp_then=();
my @temp_now=();
my $lastleap='';

my $day='';
my $daystr='';
my $month='';
my $monthstr='';
my $longmonthstr='';
my $year='';

my $logday='';
my $logmonth='';
my $logyear='';

my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
	'Sep', 'Oct', 'Nov', 'Dec' );
my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'},
	$Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'},
	$Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'},
	$Lang::tr{'december'} );

my @now = localtime(time);
my $doy = $now[7];
my $tdoy = $now[7];
my $year = $now[5]+1900;

$cgiparams{'DAY'} = $now[3];
$cgiparams{'MONTH'} = $now[4];
$cgiparams{'LOGTYPE'} = 'urlfilter';

&Header::getcgihash(\%cgiparams);
$logsettings{'LOGVIEW_REVERSE'} = 'off';
&General::readhash("${General::swroot}/logging/settings", \%logsettings);
if (-e "${General::swroot}/urlfilter/settings")
{
	&General::readhash("${General::swroot}/urlfilter/settings", \%filtersettings);
}

$now[4] = $cgiparams{'MONTH'}+1;
if($now[4] < 10) {
        $now[4] = "0$now[4]"; }

$start = -1;

if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'})
{
	@temp = split(',',$ ENV{'QUERY_STRING'});
 	$start = $temp[0];
 	$cgiparams{'MONTH'} = $temp[1];
 	$cgiparams{'DAY'} = $temp[2];  
 	$cgiparams{'LOGTYPE'} = $temp[3];  
}

if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) ||
        !($cgiparams{'DAY'} =~ /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/))
{
        $cgiparams{'DAY'} = $now[3];
        $cgiparams{'MONTH'} = $now[4];
}
elsif($cgiparams{'ACTION'} eq '>>')
{
        @temp_now = localtime(time);
        $temp_now[4] = $cgiparams{'MONTH'};
        $temp_now[3] = $cgiparams{'DAY'};
        @temp_then = localtime(POSIX::mktime(@temp_now) + 86400);
           ## Retrieve the same time on the next day -
           ## 86400 seconds in a day
        $cgiparams{'MONTH'} = $temp_then[4];
        $cgiparams{'DAY'} = $temp_then[3];
}
elsif($cgiparams{'ACTION'} eq '<<')
{
        @temp_now = localtime(time);
        $temp_now[4] = $cgiparams{'MONTH'};
        $temp_now[3] = $cgiparams{'DAY'};
        @temp_then = localtime(POSIX::mktime(@temp_now) - 86400);
           ## Retrieve the same time on the previous day -
           ## 86400 seconds in a day
        $cgiparams{'MONTH'} = $temp_then[4];
        $cgiparams{'DAY'} = $temp_then[3];
}

$monthstr = $shortmonths[$cgiparams{'MONTH'}];
$longmonthstr = $longmonths[$cgiparams{'MONTH'}];

if (($cgiparams{'DAY'} ne $now[3]) || ($cgiparams{'MONTH'} ne $now[4]))
{
	@then = ();
	if ( (  $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) ||
			( $cgiparams{'MONTH'} > $now[4] ) ) {
		@then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 ));
	} else {
		@then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 ));
	}
	$tdoy = $then[7];
	$lastleap=($year-1)%4; 
        if ($tdoy>$doy) {
		if ($lastleap == 0 && $tdoy < 60) {
			$doy=$tdoy+366;
		} else {
			$doy=$doy+365;
		}
	}
}

$day = $cgiparams{'DAY'};
if ($day <= 9) {
	$daystr = " $day";
} else {
	$daystr = $day;
}
if ($day < 10) {
        $day = "0$day";
}

&processevent;

if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
{
	print "Content-type: text/plain\n\n";
	print "IPCop URL filter log\r\n";
	print "Section: $cgiparams{'LOGTYPE'}\r\n";
	print "Date: $daystr $longmonthstr\r\n"; 
	print "\r\n";

	if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }

	foreach (@log)
        {
		($date,$time,$pid,@loginfo) = split(/ /);
		@ip = split(/\//,$loginfo[2]);
		@category = split(/\//,$loginfo[0]);
		$dsturl = $loginfo[1];
		$loginfo[3] =~ s/\%5c/\\/;
		print "$date ";
		print "$time ";
                if ($cgiparams{'LOGTYPE'} eq 'squidGuard')
		{
			print "$pid ";
			print "@loginfo";
		} else {
			print "$category[1] ";
			print "$ip[0] ";
			if ($filtersettings{'ENABLE_USERNAME_LOG'} eq 'on') { print "$loginfo[3] "; }
			print "$dsturl";
                	print "\n";
		}
        }

	exit;
}

&Header::showhttpheaders();

&Header::openpage($Lang::tr{'urlfilter log viewer'}, 1, '');

&Header::openbigbox('100%', 'left', '', $errormessage);

if ($errormessage) {
	&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
	print "<font class='base'>$errormessage&nbsp;</font>\n";
	&Header::closebox();
}

&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:");

$selected{'LOGTYPE'}{$cgiparams{'LOGTYPE'}} = "selected='selected'";

print <<END
<form method='post' action="$ENV{'SCRIPT_NAME'}">
<table width='100%'>
<tr>
	<td width='8%' class='base'>$Lang::tr{'section'}</td>
	<td width='15%' class='base'>
	<select name='LOGTYPE' size='1'>
	<option value='urlfilter' $selected{'LOGTYPE'}{'urlfilter'} = "selected='selected'">$Lang::tr{'urlfilter url filter'}</option>
	<option value='squidGuard' $selected{'LOGTYPE'}{'squidGuard'} = "selected='selected'">squidGuard</option>
	</select>
	</td>

	<td width='8%' class='base'>$Lang::tr{'month'}:</td>
	<td width='15%'>
	<select name='MONTH'>
END
;
for ($month = 0; $month < 12; $month++)
{
	print "\t<option ";
	if ($month == $cgiparams{'MONTH'}) {
		print 'selected="selected" '; }
	print "value='$month'>$longmonths[$month]</option>\n";
}
print <<END
	</select>
	</td>
	<td width='8%' class='base'>$Lang::tr{'day'}:</td>
	<td width='15%'>
	<select name='DAY'>
END
;
for ($day = 1; $day <= 31; $day++) 
{
	print "\t<option ";
	if ($day == $cgiparams{'DAY'}) {
		print 'selected="selected" '; }
	print "value='$day'>$day</option>\n";
}
print <<END
	</select>
	</td>
	<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='&lt;&lt;' /></td>
        <td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='&gt;&gt;' /></td>
	<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
	<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'export'}' /></td>
</tr>
</table>
</form>
END
;

&Header::closebox();

&Header::openbox('100%', 'left', $Lang::tr{'log'});

$lines = @log;

if ($start == -1) { $start = $lines - $Header::viewsize; }
if ($start >= $lines - $Header::viewsize) { $start = $lines - $Header::viewsize; };
if ($start < 0) { $start = 0; }

$prev = $start - $Header::viewsize;
$next = $start + $Header::viewsize;

if ($prev < 0) { $prev = 0; }
if ($next >= $lines) { $next = -1 }
if ($start == 0) { $prev = -1; }

if ($cgiparams{'LOGTYPE'} eq 'urlfilter')
{
	print "<b>$Lang::tr{'urlfilter log summary'} $longmonthstr $daystr: $lines</b><p>\n";
}

@slice = splice(@log, $start, $Header::viewsize);

if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @slice = reverse @slice; }

if ($lines != 0) {

&oldernewer();

if ($lines)
{

	$lines = 0;

	print "<table width='100%' class='tbl'>";
	unless ($cgiparams{'LOGTYPE'} eq 'squidGuard')
	{
		print "<tr>\n";
		print "<th align='center'><b>$Lang::tr{'urlfilter time'}</b></th>\n";
		print "<th align='center'><b>$Lang::tr{'urlfilter category'}</b></th>\n";
		print "<th align='center'><b>$Lang::tr{'urlfilter client'}</b></th>\n";
		if ($filtersettings{'ENABLE_USERNAME_LOG'} eq 'on') { print "<th align='center'><b>$Lang::tr{'urlfilter username'}</b></th>\n"; }
		print "<th align='center'><b>$Lang::tr{'urlfilter dst'}</b></th>\n";
		print "</tr>\n";
	}

	my $col="";
	foreach (@slice)
	{
		undef $attr1; undef $attr2;
		$lines++;
		($date,$time,$pid,@loginfo) = split(/ /);
		@ip = split(/\//,$loginfo[2]);
		@category = split(/\//,$loginfo[0]);
		$dsturl = $loginfo[1];
		$loginfo[3] =~ s/\%5c/\\/;
		if ($cgiparams{'LOGTYPE'} eq 'squidGuard') {
			if (@loginfo[0] =~ /squidGuard/) { $attr1 .= "<b>"; $attr2 .= "</b>"; }
			if (@loginfo[1] =~ /ready/) { $attr1 .= "<b><font color='$Header::colourgreen'>"; $attr2 .= "</font></b>"; }
			if (@loginfo[2] =~ /emergency/) { $attr1 .= "<b><font color='$Header::colourerr'>"; $attr2 .= "</font></b>"; }
			print "<tr>\n";
		} else {
			if ($lines % 2) {
				print "<tr>";
				$col="bgcolor='$color{'color22'}'";
			}else {
				print "<tr>";
				$col="bgcolor='$color{'color20'}'";
			}
		}
		if ($cgiparams{'LOGTYPE'} eq 'squidGuard') {
			print "<td nowrap $col>$time &nbsp; $pid &nbsp; $attr1@loginfo$attr2</td>\n";
		} else {
			print "<td width='10%' align='center' nowrap $col>$time</td>\n";
			print "<td width='11%' align='center' nowrap $col>$category[1]</td>\n";
			print "<td width='15%' align='center' nowrap $col>$ip[0]</td>\n";
			if ($filtersettings{'ENABLE_USERNAME_LOG'} eq 'on')
			{
				print "<td width='12%' align='center' nowrap $col>$loginfo[3]</td>\n";
				$site = substr($dsturl,0,55);
				if (length($dsturl) > 55) { $site .= "..."; }
			} else {
				$site = substr($dsturl,0,69);
				if (length($dsturl) > 69) { $site .= "..."; }
			}
			#print "<td>$site</td>\n";
			print "<td $col><a href='$dsturl' title='$dsturl' target='_blank'>$site</a></td>\n";
		}
		print "</tr>\n";
	}

	print "</table><br>\n";

}
}
&oldernewer();

&Header::closebox();

&Header::closebigbox();

&Header::closepage();

# -------------------------------------------------------------------

sub processevent
{
	my $filestr='';

	undef @log;
	if ($cgiparams{'LOGTYPE'} eq 'squidGuard')
	{
		$filestr = "$logdir/squidGuard.log";
		foreach $logarch (<$filestr.*.gz>)
		{
			open (LOG,"gzip -dc $logarch |");
			foreach (<LOG>) {
				($date,$time,$pid,@loginfo) = split(/ /);
				($logyear,$logmonth,$logday) = split(/-/,$date);
				if (($logyear == $year) && ($logmonth == $cgiparams{'MONTH'}+1) && ($logday == $day)) { push(@log,$_) }
			}
			close(LOG);
		}
		open (LOG,$filestr);
		foreach (<LOG>) {
			($date,$time,$pid,@loginfo) = split(/ /);
			($logyear,$logmonth,$logday) = split(/-/,$date);
			if (($logyear == $year) && ($logmonth == $cgiparams{'MONTH'}+1) && ($logday == $day)) { push(@log,$_) }
		}
		close(LOG);
	} else {
		foreach $logarch (<$logdir/*.gz>)
		{
			if ($logarch !~ /squidGuard\.log/) {
				open (LOG,"gzip -dc $logarch |");
				foreach (<LOG>) {
					($date,$time,$pid,@loginfo) = split(/ /);
					($logyear,$logmonth,$logday) = split(/-/,$date);
					if (($logyear == $year) && ($logmonth == $cgiparams{'MONTH'}+1) && ($logday == $day)) { push(@log,$_) }
				}
				close(LOG);
			}
		}
		foreach $filestr (<$logdir/*.log>)
		{
			if ($filestr !~ /squidGuard\.log/) {
				open (LOG,$filestr);
				foreach (<LOG>) {
					($date,$time,$pid,@loginfo) = split(/ /);
					($logyear,$logmonth,$logday) = split(/-/,$date);
					if (($logyear == $year) && ($logmonth == $cgiparams{'MONTH'}+1) && ($logday == $day)) { push(@log,$_) }
				}
				close(LOG);
			}
		}
		@log = sort { substr($a,11,8) cmp substr($b,11,8) } @log; 

	}
}

# -------------------------------------------------------------------

sub oldernewer
{
	print "<table width='100%'>";
	print "<tr>";

	print "<td align='center' width='50%'>";
	if ($prev != -1) {
		print "<a href='$ENV{'SCRIPT_NAME'}?$prev,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{'LOGTYPE'}'>$Lang::tr{'older'}</a>"; }
	else {
		print "$Lang::tr{'older'}"; }
	print "</td>\n";

	print "<td align='center' width='50%'>";
	if ($next != -1) {
		print "<a href='$ENV{'SCRIPT_NAME'}?$next,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{'LOGTYPE'}'>$Lang::tr{'newer'}</a>"; }
	else {
	        print "$Lang::tr{'newer'}"; }
	print "</td>\n";

	print "</tr>";
	print "</table>";
}

# -------------------------------------------------------------------
