#! /usr/bin/perl -w # check_archive Copyright (C) 2014 Tim Kiselev # # Asks 7-Zip to try to list contents of all vhd files in # directory tree passed with -p PATH, checks output for errors # # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # you should have received a copy of the GNU General Public License # along with this program (or with Nagios); if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA # $Id: check_archive 671 2014-06-10 20:06:19Z tik $ use strict; use English; use Getopt::Long qw(:config no_ignore_case no_auto_abbrev); use File::Find::Rule; use File::Basename qw(basename); use vars qw($PROGNAME); use lib "/usr/local/nagios/libexec"; use utils qw(%ERRORS &print_revision &support); sub print_help(); sub print_usage(); my $TEST_CMD = '/usr/bin/7z l'; my $VERSION = '1.0'; $PROGNAME = 'check_archive'; my (@opt_d, @opt_f, @opt_p, $opt_t, $opt_h, $opt_V); my (@files); GetOptions ( 'd|dir=s' => \@opt_d, 'f|file' => \@opt_f, 'p|pattern=s' => \@opt_p, 't|test' => \$opt_t, 'h|help' => \$opt_h, 'V|version' => \$opt_V); if ($opt_V) { print_revision($PROGNAME, $VERSION); exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } unless (@opt_f or (@opt_d and @opt_p)) { print "UNKNOWN: Must specify either --file or --dir and --pattern\n"; exit $ERRORS{'UNKNOWN'}; } # First try directory/pattern combo, then explicit files, then fail if (@opt_d and @opt_p) { foreach my $dir (@opt_d) { foreach my $pattern (@opt_p) { push @files, File::Find::Rule->file->name($pattern)->in($dir); } } } elsif (@opt_f) { push @files, @ARGV; } # Give up if there are no files to test, dump arg info unless (@files) { print "CRITICAL: No files found, see detailed output\n"; if (@opt_d) { print "Passed directories (-d):\n"; foreach my $dir (@opt_d) { print "\t$dir\n"; } print "Passed patterns (-p):\n"; foreach my $pattern (@opt_p) { print "\t$pattern\n"; } } else { print "Passed files (-f):\n"; foreach my $file (@ARGV) { print "\t$file\n"; } } exit $ERRORS{'CRITICAL'}; } $TEST_CMD = '/usr/bin/7z t' if ($opt_t); # Call the test command on each file and check if the # first 10 lines (unless test option is on) of output contain 'Errors:' # (Designed for 7zip, might not work for other programs) foreach my $file (@files) { open ZIPOUT, "$TEST_CMD '$file' |"; my $num_lines = 0; while (($opt_t || $num_lines < 10) and defined(my $line = )) { chomp($line); if ($line =~ /Errors?:/) { print "CRITICAL: ", $line, "\n"; exit $ERRORS{'CRITICAL'}; } $num_lines++; } close ZIPOUT; } # Success! Print short info for Nagios and file list for debug print "OK: all " . scalar @files . " archives valid\n"; print "Tested files:\n"; foreach my $file (@files) { print "\t$file\n"; } # Command-line docs sub print_usage () { print "Usage:\n"; print " $PROGNAME [-t] -f /path/to/first/file [/path/to/second/file ...]\n"; print " $PROGNAME [-t] -d /search/directory -p filename-pattern\n"; print " $PROGNAME [-h | --help]\n"; print " $PROGNAME [-V | --version]\n"; } sub print_help () { print_revision($PROGNAME, $VERSION); print "Copyright (c) 2014 Tim Kiselev\n\n"; print "Asks 7zip (/usr/bin/7z) to list archive header and checks for errors.\n"; print_usage(); print "\n"; print " -t --test Performs a full test of archive's contents instead of listing files\n"; print " -f --file File(s) to test.\n"; print " -d --dir Search path (must be used with -p).\n"; print " Can be repeated for multiple dirs\n"; print " -p --pattern Filename pattern, shell-style (must be used with -d).\n"; print " Can be repeated for multiple patterns\n"; print "\n"; support(); }