#!/usr/bin/perl

# script to update mcafee automatically by Sam Pratt
# based on sophos update script by jkf



############################################################
# 11/08/2000: 	ftp problem has been fixed to use Net::FTP
# 		.netrc entry no longer required
#
# 21/09/2000:	Modified to work in delphi test mailscanner
#
############################################################

use strict;
#use Sys::Syslog;
use Net::FTP;
my($LockFile) = "/tmp/McAfeeBusy.lock";

my($LOCK_SH) = 1;
my($LOCK_EX) = 2;
my($LOCK_NB) = 4;
my($LOCK_UN) = 8;





my($ftp);
my($tar) = '/bin/tar';
my($rm) = '/bin/rm';
#my($ftpsite) = 'ftpeur.nai.com'; # Use faster European mirror instead of
my($ftpsite) = 'ftp.nai.com'; # busy US site
my($ftplogin) = 'anonymous';
my($ftppassword) = "user123\@ecs.soton.ac.uk";

my($mcafeeroot) = '/usr/local/mcafee';
my($DATlink) = "$mcafeeroot/dat";
my($datfile);
my($mcafee) = "$mcafeeroot/uvscan";

#Sys::Syslog::openlog("McAfee-autoupdate", 'pid, nowait', 'mail');


my($date,$month,$year) = (localtime)[3,4,5];
$month++;
$year+=1900;
my($DATdir) = "$mcafeeroot/" . sprintf("%04d%02d%02d", $year, $month, $date);

# If the directory already exists, then we have already done the update
# for today, so quietly exit.

#Sys::Syslog::syslog('info', "Mcafee already up-to-date"),exit 0 if -d $DATdir;
die('already done it') if -d $DATdir;


#umask(0022);
mkdir($DATdir, 0755);

chdir($DATdir) or die("Cannot cd $DATdir $!");

# get the update file from fpt.nai.com
# this script assumes that there is only one file
# to download I think this is the case but the documentation is
# not very clear on the matter

$ftp = Net::FTP->new($ftpsite) or BailOut('McAfee update failed: cannnot connect to ftp site');
$ftp->login($ftplogin,$ftppassword ) or Bailout('McAfee update failed: cannot login to ftp site');
$ftp->cwd('/pub/antivirus/datfiles/4.x/') or BailOut('McAfee update failed: cannot cd ftp update dir');
my(@files)= $ftp->ls();
my($file);
foreach $file (@files){
	if ($file =~ /dat-.*\.tar/){
		$datfile = $file;
	}
}

BailOut('McAfee update failed: cannot find the update file') if (!($datfile=~ /dat-.*\.tar/));

$ftp->binary() or BailOut('McAfee update failed: cannot download update files');
$ftp->get($datfile) or BailOut('McAfee update failed: cannot download update files');

system("$tar \-xf $datfile");


# to see if the new dat's are o.k attempt to run mcafee with them and 
# check for errors
open(MCAFEETEST, "$mcafee -d $DATdir | ");
while(<MCAFEETEST>){
	chomp;
	print "$_\n";
	if (/Missing or invalid DAT/){
		BailOut('Mcafee update failed due to a problem with the dat files');
	}
	if (/Data file not found/){
		BailOut('Mcafee update failed due to a problem with the dat files');
	}
	if (/Removal datafile clean.dat not found/){
		BailOut('Mcafee update failed due to a problem with the dat files');
	}
	if (/Unable to remove viruses/){
		BailOut('Mcafee update failed due to a problem with the dat files');
	}
}

close(MCAFEETEST);

# if we've got this far then the update works so link it to 
# where the virus scanner will look for it
	
chdir $mcafeeroot or &BailOut("Cannot cd $mcafeeroot, $!");
my($OldLinkTarget) = readlink($DATlink);
&LockMcafee();

# JKF 11/02/2002 Remove dat directory if it exists and isn't a symlink
system("$rm -rf $DATlink") if -d $DATlink && !(-l $DATlink);

unlink $DATlink if -l $DATlink;
symlink $DATdir, $DATlink;
&UnlockMcafee();
system("$rm -rf $OldLinkTarget") if defined $OldLinkTarget && -e $OldLinkTarget;
#Sys::Syslog::syslog('info', "Mcafee successfully updated in $DATdir");
#Sys::Syslog::closelog();
print "$DATlink\n";
print "$OldLinkTarget\n";
print "$DATdir\n";
exit 0;

sub BailOut {
        #Sys::Syslog::syslog('err', @_);
        #Sys::Syslog::closelog();
        warn "@_, $!";
        chdir $mcafeeroot or die "Cannot cd $mcafeeroot, $!";
        system("rm -rf $DATdir") if -d $DATdir;
        exit 1;
}

sub LockMcafee {
        open(LOCK, ">$LockFile") or return;
        flock(LOCK, $LOCK_EX);
        print LOCK "Locked for updating Mcafee DAT files by $$\n";
}

sub UnlockMcafee {
        print LOCK "Unlocked after updating Mcafee DAT files by $$\n";
        flock(LOCK, $LOCK_UN);
        close LOCK;
}
