#!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... to exit\n"; <>; } =head1 NAME csavfetch.pl =head1 SYNOPSIS csavfetch.pl 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