#!/usr/bin/perl

#check_dir.pl
#
#Description:
#--------------------------------------------------
# Agente monitora o tamanho de arquivos /var/log e seus subdiretórios
# para alarmar mediante parâmetros de warning e critical e informa o número de arquivos
# encontrados e listar eles.
# sintaxe: ./check_dir.pl -w 1048576 -c 1572864 -D "/var/log"
# OBS: Thresholds passados em KB
# ticket 1029061
#--------------------------------------------------
#
#Author:
#        Boris Vasquez (boris.vasquez@opservices.com.br)
#
#13-04-2009 : Created
#

use strict;
use Getopt::Long;
use POSIX;
use File::Basename;
use English;
use POSIX;

#--------------------------------------------------
# Setting environment
#--------------------------------------------------
$ENV{"USER"}="opuser";
$ENV{"HOME"}="/home/opuser";

#--------------------------------------------------
# Global variables
#--------------------------------------------------
our $name = basename($0, ".pl");
our $version = "2.0";
our $path = "/usr/local/opmon/libexec";
our $temp_log = "$path/$name.log";

our ( $opt_help, $opt_version, $opt_dir);
our ( $opt_verbose, $opt_warn, $opt_crit, $opt_long_output) = (0, -1, -1, 0);

my $metric = ""; # Generate performance data
my $perf = "$metric=value;$opt_warn;$opt_crit;;"; # Change 'value' to your '$return'

sub convertSizeAndAddSuffix($) {
    my $size = shift;

    if ($size >=1048576) {
        return sprintf("%4.2f", ($size / 1048576)) . " GB";
    }

    if($size >= 1024) {
        return sprintf("%4.2f", ($size / 1024)) . " MB";
    }

    return $size . " KB";
}

sub convertSizesAndAddSuffix(@) {
    my @sizes = @ARG;
    foreach (@sizes) {
        $_ = convertSizeAndAddSuffix($_)
    }

    return @sizes;
}

sub main {

    getoption();
    my @command = "/usr/bin/du -a $opt_dir/* 2>&-";
    my @out = `@command`;
    my (@tamanho, @arquivo);
    chomp (@out);

    my $count;
    foreach $count (0 .. $#out){
        ($tamanho[$count], $arquivo[$count]) = split (/\t/,$out[$count]);
    }

    my @result;

    $count = 0;
    foreach (@arquivo) {
        @result = `/usr/bin/stat $_`;
        if ($result[1] =~ /directory/i){
            splice (@arquivo, $count, 1);
            splice (@tamanho, $count, 1);
        }
        $count++;
    }

    my $filesQtd = @arquivo;
    if ($opt_long_output) {
        if ($filesQtd > 0) {
            print "CRITICAL - Diretorio contem $filesQtd arquivo (s)\n";
            print '<table border=1 cellpadding=5 bgcolor="#FFFFFF"><tr><th colspan="2">Arquivos</th></tr><tr><td>Data de Criacao</td><td>Nome do Arquivo</td></tr>';
            foreach my $filename (@arquivo) {
			    my (
					$dev,
					$ino,
					$mode,
					$nlink,
					$uid,
					$gid,
					$rdev,
					$size,
					$atime,
					$mtime,
					$ctime,
					$blksize,
					$blocks
				) = stat($filename);
                printf("<tr><td>%s</td><td>%s</td></tr>", strftime("%F %T", localtime($mtime)), $filename);
            }
            print "</table>";
            exit (2);
        }

        print "OK - Diretorio nao contem arquivos";
        exit(0);
    }

    my (
        @arq_crit,
        @arq_warn,
        $count_crit,
        $count_warn,
        @tam_warn,
        @tam_crit
    );

    $count_crit = 0;
    $count_warn = 0;

    $count = 0;
    foreach (@tamanho) {
        if ($_ >= $opt_crit) {
            $arq_crit[$count_crit] = $arquivo[$count];
            $tam_crit[$count_crit] = $_;
            $count_crit++
        } elsif($_ >= $opt_warn and $_ < $opt_crit) {
            $arq_warn[$count_warn] = $arquivo[$count];
            $tam_warn[$count_warn] = $_;
            $count_warn++;
        }
        $count++;
    }

    @tam_crit = convertSizesAndAddSuffix(@tam_crit);
    @tam_warn = convertSizesAndAddSuffix(@tam_warn);

    my @result_crit;
    my @result_warn;
    if ($count_crit > 0){
        foreach $count (0 .. $#arq_crit) {
            $result_crit[$count] = "$arq_crit[$count] Tamanho: $tam_crit[$count]";
        }
        print "CRITICAL - $count_crit arquivo(s) com tamanho inesperado: @result_crit\n";
        exit(2);
    }

    if($count_warn > 0) {
        foreach $count (0 .. $#arq_warn){
            $result_warn[$count] = "$arq_warn[$count] Tamanho: $tam_warn[$count]";
        }
        print "WARNING - $count_warn arquivo(s) com tamanho inesperado: @result_warn\n";
        exit(1);
    }

    print "OK - Arquivos com tamanho dentro dos limites.\n";
    exit(0);
}
#--------------------------------------------------------------------------------------
sub getoption  {
    Getopt::Long::Configure('bundling');
    GetOptions(
        'V|version' => \$opt_version,
        'c|critical=f' => \$opt_crit,
        'h|help' => \$opt_help,
        'v|verbose=i' => \$opt_verbose,
        'w|warning=f' => \$opt_warn,
        'D|directory=s' => \$opt_dir,
        'L|long-plugin-output' => \$opt_long_output
    );

    if($opt_help){
        printHelp();
        exit(1);
    }

    if($opt_version){
        print "$name.pl - '$version'\n";
        exit(1);
    }

    if($opt_verbose){
        $opt_verbose = 1;
    }

    if($opt_long_output){
        $opt_long_output = 1;
    }

    if (! $opt_dir){
        printUsage();
        exit(1);
    }
}

#--------------------------------------------------------------------------------------
sub logger {
    return (0) if (not defined $opt_verbose);
    my $msg = shift (@_);
    my $log = "$path/$name.log";

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
    $wday++;
    $yday++;
    $mon++;
    $year+=1900;
    $isdst++;

    if ($opt_verbose == 0){
        if ($metric =~ /\w/){
            print "$msg | $perf\n";
        } else {
            print "$msg\n";
        }
    } else {
        open(LOG, ">>$log");
        printf LOG ("%02i/%02i/%i - %02i:%02i:%02i => %s\n",$mday,$mon,$year,$hour,$min,$sec,$msg);
        close(LOG);
    }
}
#--------------------------------------------------------------------------------------

sub printUsage {

    print <<EOB

Usage: $name.pl -D <dir path> [-w <warning size in kbytes> -c <critical size in kbytes> -v <level> -V ]

        -V, --version              Show version
        -c, --critical             Threshold to critical
        -h, --help                 Show help
        -w, --warning              Threshold to warning
        -D, --directory            Directory that will be scanned
        -L, --long-plugin-output   Check if the given directory has some file and generate a html table with their names and creation date

        -v, --verbose              0 = Print out in screen
                                   1 = Send log to file

EOB

}
#--------------------------------------------------------------------------------------

sub printHelp {

    my $help = <<'HELP';
        Insert help program


HELP

    print $help;

}
#--------------------------------------------------------------------------------------
&main


