#!/usr/bin/perl use Sys::Syslog; $SophosRoot = shift || "/usr/local/Sophos"; $IDELink = "$SophosRoot/ide"; $VDLDir = "../lib"; #$Lynx = "/usr/local/bin/lynx -dump"; $Lynx = "/usr/bin/wget -q -O-"; # On Linux use this $Unzip = "/usr/bin/unzip -joqq"; $rm = "/bin/rm"; $LockFile = "/tmp/SophosBusy.lock"; $LOCK_SH = 1; $LOCK_EX = 2; $LOCK_NB = 4; $LOCK_UN = 8; Sys::Syslog::openlog("Sophos-autoupdate", 'pid, nowait', 'mail'); # Work out the current VDL (and hence Sophos Sweep) version number unless (chdir "$SophosRoot/bin/$VDLDir") { &BailOut("Could not find directory \"$SophosRoot/bin/$VDLDir\""); } opendir(LIBDIR, ".") || &BailOut("Cannot open Sophos/lib directory"); foreach $vdlname (sort readdir(LIBDIR)) { next unless $vdlname =~ /^vdl-(\d+)\.(\d+)([a-zA-Z]*)\.dat$/; $MajorVer = $1; $MinorVer = $2; $NSVFlag = $3; } closedir(LIBDIR); &BailOut("Could not calculate Sophos version number") unless defined($MajorVer) && defined($MinorVer); $SophosVersion = "$MajorVer$MinorVer"; $VDLVersion = "$MajorVer.$MinorVer"; # Derive other variables, filenames and URLs from the version numbers $ZipName = $SophosVersion . "_ides.zip"; $URL = "http://www.sophos.com/downloads/ide/$ZipName"; ($min,$hour,$date,$month,$year) = (localtime)[1,2,3,4,5]; $month++; $year+=1900; $IDEDir = "$SophosRoot/$SophosVersion." . sprintf("%04d%02d%02d%02d%02d", $year, $month, $date, $hour, $min); # If the directory already exists, then we have already done the update # for today, so quietly exit. Sys::Syslog::syslog('info', "Sophos already up-to-date"),exit 0 if -d $IDEDir; # Create the IDE files directory umask 0022; mkdir $IDEDir, 0755; chdir $IDEDir or &BailOut("Cannot cd $IDEDir, $!"); # Fetch and unpack the IDE zip file from Sophos #print STDERR "URL is $URL\n"; $result = system("$Lynx $URL > $ZipName"); if (($result>>8)==1) { Sys::Syslog::syslog('err', "Your Sophos installation may be too old. Please install the latest release of Sophos"); print STDERR "Your Sophos installation may be too old. Please install the latest release of Sophos"; } &BailOut("Lynx failed with error return " . ($result>>8) . "\n") if $result>>8; $result = system("$Unzip $ZipName"); if ($result>>8) { Sys::Syslog::syslog('err', "Unzipping the new Sophos IDE files failed. This may well be because your Sophos installation is too old. Please install the latest release of Sophos"); print STDERR "Unzipping the new Sophos IDE files failed. This may well be because your Sophos installation is too old. Please install the latest release of Sophos"; &BailOut("Unzip failed with error return " . ($result>>8) . "\n"); } symlink("$VDLDir/vdl-$VDLVersion$NSVFlag.dat", "vdl.dat"); # Add the new vdl*.vdb files if they are there foreach $number (1..99) { $string = "vdl" . sprintf("%02d", $number) . ".vdb"; symlink("$VDLDir/$string", $string) if -f "$VDLDir/$string"; } # Add the new swpmess.dat and svext.dat files too symlink("$VDLDir/swpmess.dat", "swpmess.dat") if -f "$VDLDir/swpmess.dat"; symlink("$VDLDir/svext.dat", "svext.dat") if -f "$VDLDir/svext.dat"; # Link in this new directory to Sophos chdir $SophosRoot or &BailOut("Cannot cd $SophosRoot, $!"); $OldLinkTarget = readlink $IDELink; &LockSophos(); unlink $IDELink if -l $IDELink; symlink $IDEDir, $IDELink; &UnlockSophos(); system("$rm -rf $OldLinkTarget") if defined $OldLinkTarget && -e $OldLinkTarget; Sys::Syslog::syslog('info', "Sophos successfully updated in $IDEDir"); Sys::Syslog::closelog(); exit 0; sub BailOut { Sys::Syslog::syslog('err', @_); Sys::Syslog::closelog(); warn "@_, $!"; chdir $SophosRoot or die "Cannot cd $SophosRoot, $!"; system("$rm -rf $IDEDir") if -d $IDEDir; exit 1; } sub LockSophos { open(LOCK, ">$LockFile") or return; flock(LOCK, $LOCK_EX); print LOCK "Locked for updating Sophos IDE files by $$\n"; } sub UnlockSophos { print LOCK "Unlocked after updating Sophos IDE files by $$\n"; unlink $LockFile; flock(LOCK, $LOCK_UN); close LOCK; }