HOME


sh-3ll 1.0
DIR:/var/qmail/bin/
Upload File :
Current File : //var/qmail/bin/jgreylist-clean
#!/usr/bin/perl -w
#
# jgreylist-clean
# John Simpson <jms1@jms1.net> 2006-08-21
#
# 2006-11-26 jms1 - adding optional check to remove non-revisited entries
#   (i.e. an IP connects exactly one time and then gives up, much like a
#   zombie PC without any kind of "retry" would do) after a given length
#   of time. Thanks to Ron Miller for the suggestion.
#
# 2006-11-29 jms1 - keeping count of entries deleted for $max_age and 
#   $one_age, so i can get a feel for how many IPs are actually zombies.
#   also making the list of what's deleted optional, use "-v" if you want
#   to see the full list, or "-q" if you want to see nothing at all (i.e.
#   no totals.)
#
###############################################################################
#
# Copyright (C) 2006 John Simpson.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# 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 the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# or visit http://www.gnu.org/licenses/gpl.txt
#
###############################################################################

require 5.003 ;
use strict ;

use Getopt::Std ;

###############################################################################
#
# configuration

# directory where entries are stored.
# should be the same as $greydir in the "jgreylist" script.
my $greydir = "/var/qmail/jgreylist" ;

# if a client doesn't connect at all for this number of seconds, their
# file is removed and they become "unknown" again.
my $max_age = 30 * 24 * 60 * 60 ;

# if a client only connected exactly one time, their file is removed
# after this number of seconds and they become "unknown" again.
# if set to zero, this check is not done.
my $one_age = 24 * 60 * 60 ;

###############################################################################
#
# global variables

my $now = time() ;
my $nrf = 0 ;
my $nof = 0 ;
my $nkf = 0 ;
my $do_show = 1 ;

my ( @ent ) ;
our ( $opt_q , $opt_d , $opt_v ) ;

$| = 1 ;

###############################################################################
#
# output functions

sub vdebug(@)
{
	return unless ( $do_show > 2 ) ;
	print @_ ;
}

sub debug(@)
{
	return unless ( $do_show > 1 ) ;
	print @_ ;
}

sub show(@)
{
	return unless ( $do_show > 0 ) ;
	print @_ ;
}

###############################################################################
#
# recursive function to "do the deed"

sub rrmdir($) ;
sub rrmdir($)
{
	my $d = shift ;
	my $ec = 0 ;
	my ( $dh , @df ) ;

	vdebug "$d         \r" ;

	unless ( opendir ( $dh , "$d" ) )
	{
		print "$d: opendir() failed: $!\n" ;
		return 0 ;
	}

	while ( my $f = readdir $dh )
	{
		next if ( $f =~ /^\.\.?$/ ) ;
		push ( @df , $f ) ;
	}
	close $dh ;

	for my $f ( sort @df )
	{
		if ( -d "$d/$f" )
		{
			$ec += rrmdir ( "$d/$f" ) ;
		}
		elsif ( -f "$d/$f" )
		{
			my @s = stat ( "$d/$f" ) ;
			if ( ( $now - $s[8] ) > $max_age )
			{
				if ( unlink ( "$d/$f" ) )
				{
					debug "$d/$f: removed\n" ;
					$nrf ++ ;
				}
				else
				{
					print "$d/$f: unlink(): $!\n" ;
					$ec ++ ;
				}
			}
			elsif (    $one_age
				&& ( $s[8] == $s[9] )
				&& ( ( $now - $s[8] ) > $one_age ) )
			{
				if ( unlink ( "$d/$f" ) )
				{
					debug "$d/$f: removed\n" ;
					$nof ++ ;
				}
				else
				{
					print "$d/$f: unlink(): $!\n" ;
					$ec ++ ;
				}
			}
			else
			{
				$nkf ++ ;
				$ec ++ ;
			}
		}
		else
		{
			$ec ++ ;
		}
	}
	close $dh ;

	if ( 0 == $ec )
	{
		if ( rmdir ( $d ) )
		{
			debug "$d: removed\n" ;
		}
		else
		{
			print "$d: rmdir() failed: $!\n" ;
			$ec ++ ;
		}
	}

	return $ec ;
}

###############################################################################
###############################################################################
###############################################################################
#
# the magic starts here

getopts ( "qdv" ) ;
if ( $opt_q ) { $do_show = 0 ; }
if ( $opt_d ) { $do_show = 2 ; }
if ( $opt_v ) { $do_show = 3 ; }

opendir ( D , $greydir )
	or die "opendir($greydir) failed: $!\n" ;

while ( my $e = readdir D )
{
	next if ( $e =~ /^\.\.?$/ ) ;
	push ( @ent , $e ) ;
}
close D ;

for my $e ( sort @ent )
{
	if ( -d "$greydir/$e" )
	{
		rrmdir ( "$greydir/$e" ) ;
	}
}

show sprintf ( "Removed %8d max_age entries                \n" , $nrf ) ;
if ( $one_age )
{
	show sprintf ( "Removed %8d one-time entries\n" , $nof ) ;
}
show sprintf ( "Kept    %8d entries\n" , $nkf ) ;