#!/usr/bin/perl -w

# $id$
# Copyright (C) 2009 Yuji OKAMURA
# 
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# 
# 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, see <http://www.gnu.org/licenses/>.

use strict;
use vars qw(
	$LogDir
	$LogFileName
	$SentryRelPath
	$ApplicationsDir
	$ClamXavName
	$MaxLogSize
	$MaxLogNum
	$SentrySignal
);
use Sys::Hostname;
use File::Basename;
use POSIX qw(strftime);

$LogDir = "$ENV{HOME}/Library/Logs";
$LogFileName = 'clamXav-scan.log';
$SentryRelPath =
	'Contents/Resources/ClamXavSentry.app/Contents/MacOS/ClamXavSentry'
;

if (exists($ENV{APPLICATIONS_DIR})) {
	$ApplicationsDir = $ENV{APPLICATIONS_DIR};
}
else {
	$ApplicationsDir = '/Applications';
}
if (exists($ENV{CLAMXAV_NAME})) {
	$ClamXavName = $ENV{CLAMXAV_NAME};
}
else {
	$ClamXavName = 'ClamXav.app';
}
if (exists($ENV{MAX_SCAN_LOG_SIZE}) and 0 < int($ENV{MAX_SCAN_LOG_SIZE})) {
	$MaxLogSize = int($ENV{MAX_SCAN_LOG_SIZE}) * 1024;
}
else {
	$MaxLogSize = 100 * 1024;
}
if (exists($ENV{MAX_SCAN_LOG_NUM}) and 0 < int($ENV{MAX_SCAN_LOG_NUM})) {
	$MaxLogNum = int($ENV{MAX_SCAN_LOG_NUM});
}
else {
	$MaxLogNum = 5;
}
if (exists($ENV{SENTRY_SIGNAL}) and 0 < int($ENV{SENTRY_SIGNAL})) {
	$SentrySignal = int($ENV{SENTRY_SIGNAL});
}
else {
	$SentrySignal = 15;
}

if (-f "$LogDir/$LogFileName") {
	my @logStat = stat "$LogDir/$LogFileName";

	if ($MaxLogSize <= $logStat[7]) {
		umask(0177);

		while (0 < $MaxLogNum) {
			my	$dst = sprintf '%s/%s.%d', $LogDir, $LogFileName, $MaxLogNum--;
			my	$src = sprintf '%s/%s.%d', $LogDir, $LogFileName, $MaxLogNum;

			unlink($dst)	if (-f $dst);
			if (-f $src) {
				rename($src, $dst);
			}
		}
		rename("$LogDir/$LogFileName", "$LogDir/$LogFileName.0");

		if (open FH, '>', "$LogDir/$LogFileName") {
			my	@now = localtime(time);

			printf FH "%s %s %s[%d]: logfile turned over due to size>%dK\n",
				strftime('%F %T', @now),
				hostname,
				basename($0),
				$$,
				$MaxLogSize / 1024
			;
			close FH;
		}
		else {
			print STDERR "Can't create $LogDir/$LogFileName\n";
		}
		
		if (open FH, '-|', '/bin/ps', 'xw') {
			my	$sentryPath = sprintf(
				'%s/%s/%s', $ApplicationsDir, $ClamXavName, $SentryRelPath
			);
			my	$line = <FH>;
			my	$sentryPid = undef;

			while ($line = <FH>) {
				chomp $line;
				if (
					$line =~ m/\s*(\d+)\s+\S+\s+\S+\s+\S+\s+\Q$sentryPath\E(?:\s+-psn_[0-9_]+)?$/o
				) {
					$sentryPid = $1;
					last;
				}
			}
			close FH;
			if ($sentryPid) {
				kill $SentrySignal, $sentryPid;
			}
			else {
				print STDERR "ClamXavSentry is not running.\n";
			}
		}
		else {
			print STDERR "Can't execute ps command.\n";
		}
	}
}
