Description: |
Checks Command Antivirus website for updated virus definition file, and fetches if newer than local copy. Then inflates the self-extracting executable to an 'ms patch' file named for it's release date. This msp file is copied to latest.msp which can be run (outside this program) to update client PCs.
From a perlish perspective, building this has been a great refresher, especially on minimizing the number of global variables, as I've been Away From Perl for months. It's good to be back, even for code as straightforward as this. 8^)
Sample run:
http://download.commandcom.com/CSAV/deffiles/DEFMSP.EXE: 200 OK
PKSFX(R) Version 2.50 FAST! Self Extract Utility for Windows 95/NT 4-15-1998
Extracting files from .ZIP: c:/DEFMSP.EXE
Inflating: 030717.msp
1 valid msp file(s):
030717.msp
Latest msp: 030717.msp
Today: 030723
030717.msp copied to current.msp
Done... <enter> to exit
|
#!c:\perl\bin\perl.exe
# csavfetch.pl
# pod at tail
use strict; # avoid D'oh! bugs
use warnings; # avoid D'oh! bugs
use LWP::UserAgent; # mirror web file
use File::Copy; # copy local file
use File::Basename; # remove extension from filename
use Getopt::Long; # support options+arguments
use Pod::Usage; # avoid redundant &Usage()
$|++; # stdout hot
my (%dir, %file, %www, $opt_help, $opt_man, $opt_versions);
my $csavfetch_VER = '0.02.04';
GetOptions(
'help!' => \$opt_help,
'man!' => \$opt_man,
'versions!' => \$opt_versions,
) or pod2usage(-verbose => 1) && exit;
pod2usage(-verbose => 1) && exit if defined $opt_help;
pod2usage(-verbose => 2) && exit if defined $opt_man;
### START CONFIG PARAMS ###
### START CONFIG PARAMS ###
print "Edit config params first\n" and exit; # comment out this line
+ with a leading #
$dir{dest} = 'c:/'; # trailing /
$file{src} = 'DEFMSP.EXE';
$file{dest} = $file{src};
$file{synt} = ' -o'; # overwrite
$file{ren} = 'latest.msp';
$file{valid} = '^[0-9]{2}[0-1][0-9][0-3][0-9]\.msp$'; # yymmdd.msp
$www{site} = "http://download.commandcom.com"; # proto://host.dom
$www{path} = '/CSAV/deffiles/'; # leading+trailing /
$www{realm} = '';
$www{realmsite} = ''; # host.dom:port
$www{id} = '';
$www{pass} = '';
$www{proxy} = ''; # http://host.dom:port
$www{agent} = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gec
+ko/20030624';
$www{timeout} = 60;
### END CONFIG PARAMS ###
### END CONFIG PARAMS ###
die "ERROR accessing $dir{dest}: $!\n" unless -d $dir{dest} && -w _;
die "ERROR entering $dir{dest}: $!\n" unless chdir $dir{dest};
{ # Check for CSAV update, fetch only if newer than local:
print "$www{site}$www{path}$file{src}: ";
my $browser = new LWP::UserAgent;
$browser->credentials($www{realmsite}, $www{realm}, $www{id} => $www
+{pass},);
$browser->proxy(http => $www{proxy}) unless ($www{proxy} eq '');
$browser->timeout($www{timeout});
$browser->agent($www{agent});
my $response = $browser->mirror("$www{site}$www{path}$file{src}", $f
+ile{dest});
print $response->status_line . "\n";
if($response->is_error()){
die "ERROR accessing $www{site}$www{path}$file{src}";
}
exit unless ($response->status_line eq '200 OK');
}
# run self-extracting executable:
system("$file{dest}$file{synt}") and die "ERROR extracting $file{dest}
+: $!";
{ # read directory for latest msp file:
opendir DESTDIR, $dir{dest} or die "ERROR opening $dir{dest}: $!\n";
my @valid_msps= grep /$file{valid}/, readdir DESTDIR;
closedir DESTDIR or die "ERROR closing $dir{dest}: $!\n";
print "\n" . scalar @valid_msps, " valid msp file(s):\n";
print " $_\n" for @valid_msps;
print "\nLatest msp: ", $file{msp} = (sort @valid_msps)[-1], "\n";
}
{ # filename/date validation:
my %date;
( $date{sec},
$date{min},
$date{hour},
$date{mday},
$date{mon},
$date{year}) = localtime(time);
$date{stamp} = sprintf("%02d%02d%02d", $date{year}-100, $date{mon}+1
+, $date{mday});
$file{basename} = fileparse($file{msp}, '\.msp');
print "Today: $date{stamp}\n";
if($file{basename} > $date{stamp}){
print "ERROR: $file{msp} is named for a future datestamp\n";
exit;
}
}
# copy latest msp to 'latest.msp' for user logon script:
copy($file{msp}, $file{ren})
or die "ERROR copying $file{msp} to $file{ren}: $!";
print "$file{msp} copied to $file{ren}\n";
END{
if(defined $opt_versions){
print
"\nModules, Perl, OS, Program info:\n",
" LWP::UserAgent $LWP::UserAgent::VERSION\n",
" File::Copy $File::Copy::VERSION\n",
" File::Basename $File::Basename::VERSION\n",
" Pod::Usage $Pod::Usage::VERSION\n",
" Getopt::Long $Getopt::Long::VERSION\n",
" strict $strict::VERSION\n",
" warnings $warnings::VERSION\n",
" Perl $]\n",
" OS $^O\n",
" csavfetch.pl $csavfetch_VER\n",
"\n\n";
}
print "Done... <enter> to exit\n"; <>;
}
=head1 NAME
csavfetch.pl
=head1 SYNOPSIS
csavfetch.pl<enter>
Before running this program for the first time, you should
check its config parameters and edit as necessary.
=head1 DESCRIPTION
Checks Command Antivirus website for updated virus
definition file, and fetches if newer than local copy.
Then inflates the self-extracting executable to a 'ms patch'
file named for it's release date. This msp file is copied
to 'latest.msp' which can be run (outside this program) to
update client PCs.
=head1 ARGUMENTS
--help print Options and Arguments instead of fetching CSAV update
--man print complete man page instead of fetching CSAV update
=head1 OPTIONS
--versions print Modules+Perl+OS+Program info after program run
=head1 AUTHOR
ybiC
=head1 CREDITS
Phat props to some guy named vroom
=head1 TESTED
LWP::UserAgent 2.003
File::Copy 2.05
File::Basename 2.71
Pod::Usage 1.14
Getopt::Long 2.32
strict 1.02
warnings 1.00
Perl 5.008
OS WinXPpro, Win98se
=head1 BUGS
None that I know of
=head1 TODO
Test on WinNT
Consolidate filename/date validation
=head1 UPDATES
2003-07-23 08:20 CST
Podify, Manulate, Helpify, Versionalize
Post to Perlmonks Code Catacombs
2003-07-19
Initial working code
=cut
|