#!/usr/bin/perl -w

#
# Loosely Hacked version of Mike Cathey's clamdwatch.pl
# Allows a command to be sent to a running clamd process
# eg 
#	clamdctl -q -c shutdown 
#	clamdctl -q -c reload 
#
# See ./clamd/session.h for commands
#
use IO::Socket::UNIX;
use Getopt::Std;

my %options;
getopts('s:c:t:qh', \%options);

if ( $options{h} ) {
    print("  clamdctl [ -c CMD ] [-s socket ] [ -t timeout ]\n");
}
# "CONFIG" section
#
# $Socket values:

#   = "/path/to/clamd/socket"
my $Socket = $options{s} || "/var/run/clamav/clamd.socket";
my $timeout = $options{t} || 15;
my $lockFile = "/var/lock/subsys/clamd";
my $quiet = $options{q} || 0;
my $cmd	= $options{c} || "PING";
my $sock;
$cmd =~ tr/a-z/A-Z/;

sub print_message($) {
    my ($message) = @_;
    if ( !$quiet ) {
        print "$message";
    }
}

# If the lockfile isn't there we assume that clamd was
# shutdown administratively.
unless ( !defined($lockFile) || ($lockFile eq "") ) {
    if ( ! -e $lockFile ) {
        print_message("$lockFile not present. clamd not tested.");
        exit 1;
    }
}


# why waste time creating the IO::Socket instance if the socket isn't there
#
    if ( ! -e $Socket ) {
        print_message("$Socket missing! It doesn't look like clamd is running.");
        exit 0;
    } else {
        $sock = new IO::Socket::UNIX(Type => SOCK_STREAM,
                                        Timeout => $timeout,
                                        Peer => $Socket );
    }

if (!$sock || $@ ) { # there could be a stale file from a dead clamd
    print_message("Clamd Not Running");
    exit 1;
}

if ( $sock->connected ) { 

    my $err = "";
   $sock->send("$cmd");

    # set the $timeout and die with a useful error if
    # clamd isn't responsive
    eval {
        local $SIG{ALRM} = sub { die "timeout\n" };
	alarm($timeout);
        $sock->recv($err, 200);
	alarm(0);
    };
    if ($@) {

    	die unless $@ eq "timeout\n";
        print_message("timed out");
	exit 1;

    } else { # clamd responded to the request
	print_message($err);
	if ( "$err" eq "UNKNOWN COMMAND\n") {
		exit 1;
	}
	exit 0;
    } 
}
print_message("socket not connected");
exit 1;

