#! /usr/bin/perl -w
##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

use strict;

# Update the module include path
BEGIN
{
    my $Dir = $0;
    if ( $Dir =~ /(.*)\/.*/ )
    {
	push @INC, "$1";
    }
}
use HawkeyePublish;
use HawkeyeLib;

# My Hawkeye object
my $Hawkeye;
my $OsInfo = ();
my $OS;
my @OsInfo = (
	      # Any version of HP-UX
	      { ostype => "HP-UX", osrev => ".*",
		df =>
		{
		 Command => "bdf",
		 BlockSize => 1024,
		 Fields =>
		 {
		  fs => 0,
		  size => 1,
		  used => 2,
		  avail => 3,
		  pused => 4,
		  mnt => 5,
		 },
		},
	      },
	      # Solaris
	      { ostype => "SunOS", osrev => "5",
	        df =>
		{
		 Command => "/usr/bin/df -k",
		 BlockSize => 1024,
		 Fields =>
		 {
		  fs => 0,
		  size => 1,
		  used => 2,
		  avail => 3,
		  pused => 4,
		  mnt => 5,
		 },
		},
	      },
	      # SunOS 4.x
	      { ostype => "SunOS", osrev => "4",
		df =>
		{
		 Command => "df",
		 BlockSize => 512,
		 Fields =>
		 {
		  fs => 0,
		  size => 1,
		  used => 2,
		  avail => 3,
		  pused => 4,
		  mnt => 5,
		 },
		},
	      },
	      # Any Linux
	      { ostype => "Linux", osrev => ".*",
		df =>
		{
		 Command => "df",
		 BlockSize => 1024,
		 Fields =>
		 {
		  fs => 0,
		  size => 1,
		  used => 2,
		  avail => 3,
		  pused => 4,
		  mnt => 5,
		 },
		},
	      },
	      # Apple OS/X
	      { ostype => "Darwin", osrev => ".*",
		df =>
		{
		 Command => "df",
		 BlockSize => 512,
		 Fields =>
		 {
		  fs => 0,
		  size => 1,
		  used => 2,
		  avail => 3,
		  pused => 4,
		  mnt => 5,
		 },
		},
	      },
	  );

my @MountProgs = (
		  "/bin/mount",
		  "/sbin/mount",
		  "/usr/sbin/mount",
		  "/usr/bin/mount",
		 );

my @DfFields = (
		{
		 Name => "fs",
		 Field => "fs",
		 Type => HawkeyePublish::TypeString,
		},
		{
		 Name => "size",
		 Field => "size",
		 Type => HawkeyePublish::TypeNumber,
		},
		{
		 Name => "used",
		 Field => "used",
		 Type => HawkeyePublish::TypeNumber,
		},
		{
		 Name => "avail",
		 Field => "avail",
		 Type => HawkeyePublish::TypeNumber,
		},
		{
		 Name => "pct_used",
		 Field => "pused",
		 Type => HawkeyePublish::TypePercent,
		},
		{
		 Name => "mnt",
		 Field => "mnt",
		 Type => HawkeyePublish::TypeString,
		},
	       );

main();

# Main
sub main
{
    $| = 1;
    Init();
    RunIt();
}

# Initialize
sub Init
{
    HawkeyeLib::DoConfig( );

    $Hawkeye = HawkeyePublish->new;
    $Hawkeye->Quiet( 1 );
    $Hawkeye->AutoIndexSet( 0 );

    # Learn about our O/S
    $OS = HawkeyeLib::DetectOs( \@OsInfo );

    # Did we find a match?
    if ( ! $OS )
    {
	die "O/S Not defined\n";
    }
}

# ***********************************************
# Do the actual work
sub RunIt
{

    # Read the file system list (FSLIST)
    my $FsList = HawkeyeLib::ReadConfig(  "_fslist", "" );
    my @MountPoints = split( /,/, $FsList );


    # Get the real mount points
    my $Mount = "";
    foreach my $Tmp ( @MountProgs )
    {
	if ( -x $Tmp )
	{
	    $Mount = $Tmp;
	}
    }
    die "Can't find a mount program" if ( $Mount eq "" );

    # Run mount, store it's output in @Lines
    my %RealMountPoints;
    my $CheckMountPoints = 0;
    my @Lines;
    my $MountFs = 0;
    if ( open ( MOUNT, "$Mount |" ) )
    {
	while ( <MOUNT> )
	{
	    chomp;
	    if ( ! /on/ )
	    {
		print STDERR "df: I don't understand '$_'\n";
		next;
	    }
	    push( @Lines, $_ );
	}
    }
    close( MOUNT );

    # Which type of mount do we have ( 'dev on mp' or 'mp on dev' ) ?
    my @Tmp1a = grep( /^\/dev[\w\/]+\s+on\s+\//, @Lines );
    my @Tmp1b = grep( /^[\w\#]+\s+on\s+\//, @Lines ); # OS/F 'usr_domain#usr'
    my @Tmp2 = grep( /^\/[\w\/]+\s+on\s+\/dev/, @Lines );
    if ( scalar(@Tmp1a) or scalar(@Tmp1b) )
    {
	foreach my $Line ( @Lines )
	{
	    if ( $Line =~ /(\S+)\s+on\s+(\S+)/ )
	    {
		$CheckMountPoints++;
		my $Fs = $1;
		my $MPoint = $2;
		$RealMountPoints{$MPoint} = $Fs;
	    }
	}
    }
    elsif ( scalar( @Tmp2 ) )
    {
	foreach my $Line ( @Lines )
	{
	    if ( $Line =~ /(\S+)\s+on\s+(\S+)/ )
	    {
		$CheckMountPoints++;
		my $MPoint = $1;
		my $Fs = $2;
		$RealMountPoints{$MPoint} = $Fs;
	    }
	}
    }
    else
    {
	die "I can't understand the output of $Mount";
    }

    my %DfOut;
    foreach my $MP (@MountPoints)
    {
	# Verify it
	if ( ! -d $MP )
	{
	    print STDERR "df: '$MP' is not a directory! (skipping)\n";
	    next;
	}
	if ( ( $CheckMountPoints ) && ( ! exists $RealMountPoints{$MP} ) )
	{
	    print STDERR "df: '$MP' is not a mount point! (skipping)\n";
	    next;
	}

	# Run df on it
	my $DF = $OS->{df};
	my $Cmd = $DF->{Command} . " $MP | grep -v Filesystem";
        chop( my $df_out = `$Cmd` );

	my @Tmp = split (/\s+/, $df_out);

        # Clean up the published name...
	my $PublishName = $MP;
	$PublishName = "root" if ( $PublishName eq "/" );
        $PublishName =~ s/^\/$/root/;
        $PublishName =~ s/^\///;
        $PublishName =~ s/[\/\.]/_/g;

	# Store into the 'DfOut' hash
	my $Mult = $DF->{BlockSize} / 1024;
	print "BlockSize = " . $DF->{BlockSize} . "\n";
	print "Mult = $Mult\n";
	foreach my $Field ( @DfFields )
	{
	    my $FieldName = $Field->{Field};
	    my $Offset = $DF->{Fields}{$FieldName};
	    my $Value = $Tmp[$Offset];
	    my $Name = $PublishName . "_" . $Field->{Name};
	    if ( $Field->{Type} == HawkeyePublish::TypeNumber )
	    {
		$Value = int( $Value * $Mult );
	    }
	    $Hawkeye->StoreValue( $Name,
				  $Value,
				  $Field->{Type} );
	}
    }

    # Store the fields used
    my @Fields;
    foreach my $Field ( @DfFields )
    {
	push( @Fields, $Field->{Name} );
    }
    $Hawkeye->StoreValue( "FIELDS" ,
			  join( " ", @Fields ),
			  HawkeyePublish::TypeString );

    $Hawkeye->Publish( );
}
