sourcecode
ybiC
<code>#!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) Gecko/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}", $file{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
</code>
<p>
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 <tt>latest.msp</tt> which can be run <i>(outside this program)</i> to update client PCs.
</p>
<p>
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^)
</p>
<p>
Sample run:<br />
<tt>http://download.commandcom.com/CSAV/deffiles/DEFMSP.EXE: 200 OK<br />
PKSFX(R) Version 2.50 FAST! Self Extract Utility for Windows 95/NT 4-15-1998<br />
Extracting files from .ZIP: c:/DEFMSP.EXE<br />
Inflating: 030717.msp<br />
1 valid msp file(s):<br />
030717.msp<br />
Latest msp: 030717.msp<br />
Today: 030723<br />
030717.msp copied to current.msp<br />
Done... <enter> to exit</tt>
</p>
Utility Scripts
[ybiC]