# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/perl/libext/StatFS/StatFS.pm 1.1.1.1 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
package LibExt::StatFS;

use 5.006000;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);

my @funcs = qw(statfs mountpt);
my @macros = qw(
                 MNT_AIX
                 MNT_J2
                 MNT_NAMEFS
                 MNT_NFS
                 MNT_JFS
                 MNT_CDROM
                 MNT_PROCFS
                 MNT_USRVFS
                 MNT_SFS
                 MNT_CACHEFS
                 MNT_NFS3
                 MNT_AUTOFS
                 MNT_USRLAST
                 MNT_VXFS
                 MNT_VXODM
                 MNT_UDF
                 MNT_NFS4
                 MNT_RFS4
                 MNT_CIFS
                 MNT_AIXLAST
                 MNT_BADVFS
               );

our @EXPORT_OK = (@funcs, @macros);
our %EXPORT_TAGS = ( func  => [@funcs],
                     macro => [@macros],
                     all   => [@EXPORT_OK] );

our $VERSION = '1.0';

sub mountpt($) {
  my $path = shift;
  my $df = `/usr/bin/df $path 2>&1` or return undef; # $! should be available to the caller
  goto BAIL if $?;
  my @a = split /\n/, $df;
  $#a == 1 or goto BAIL;
  $_ = $a[1];
  @a = split;
  $#a == 6 or goto BAIL;
  $a[6] or goto BAIL;
  return $a[6];
  BAIL: {
    $@ = $df;
    return undef;
  }
}

# At some point, the XS should load these #defines directly via the normal 'constant'
# function.  For now, these are copied from sys/vmount.h
use constant MNT_AIX       =>  0;       # Same as MNT_J2
use constant MNT_J2        =>  0;       # AIX physical fs "jfs2"
use constant MNT_NAMEFS    =>  1;       # AIX pseudo fs "namefs"
use constant MNT_NFS       =>  2;       # SUN Network File System "nfs"
use constant MNT_JFS       =>  3;       # AIX R3 physical fs "jfs"
use constant MNT_CDROM     =>  5;       # CDROM File System "cdrom"
use constant MNT_PROCFS    =>  6;       # PROCFS File System "proc"
use constant MNT_USRVFS    =>  8;       # first 8 (0 - 7) reserved for IBM use
use constant MNT_SFS       => 16;       # AIX Special FS (STREAM mounts)
use constant MNT_CACHEFS   => 17;       # Cachefs file system
use constant MNT_NFS3      => 18;       # NFSv3 file system
use constant MNT_AUTOFS    => 19;       # Automount file system
use constant MNT_USRLAST   => 31;       # last valid user file system
use constant MNT_VXFS      => 32;       # THRPGIO File System "vxfs"
use constant MNT_VXODM     => 33;       # For Veritas File System
use constant MNT_UDF       => 34;       # UDFS file system
use constant MNT_NFS4      => 35;       # NFSv4 file system
use constant MNT_RFS4      => 36;       # NFSv4 Pseudo file system
use constant MNT_CIFS      => 37;       # AIX SMBFS (CIFS client)
use constant MNT_AIXLAST   => 39;       # last valid vfs number
use constant MNT_BADVFS    => -1;       # always illegal vfs type

require XSLoader;
XSLoader::load('LibExt::StatFS', $VERSION);

1;
__END__

=head1 NAME

LibExt::StatFS - Perl extension for C's statfs() functionality

=head1 SYNOPSIS

  use LibExt::StatFS qw/ statfs mountpt    /;
  use LibExt::StatFS qw/ MNT_NFS MNT_CDROM /;
  use LibExt::StatFS qw/ :func             /;
  use LibExt::StatFS qw/ :macro            /;
  use LibExt::StatFS qw/ :all              /;

  $statfs = statfs("/usr");

  # Get the number of free 512-byte blocks, à la df
  $freeblocks = $statfs->{bfree} * $statfs->{bsize} / 512;

  if($statfs->{vfstype} == MNT_NFS) {
    print $statfs->{fname} . " is NFS mounted.\n";
  }

  $mount_point = mountpt("/usr/sys/inst.images");

=head1 DESCRIPTION

Provides a Perl interface to statfs() functionality and certain relevant macro
definitions from C<sys/vmount.h>.  Also provides a convenience method to
determine the mount point given a full path.

=head1 EXPORT_OK

=over 4

=item statfs PATH

Calls the C C<statfs()> function, returning information about the filesystem under
C<PATH>.  The return value is a hash reference
whose keys correspond to C<struct statfs> field names, less the initial "f_".
Currently, this function returns a subset of the fields, specifically as follows:

  version         # version/type of statfs, 0 for now
  type            # type of info, zero for now
  bsize           # optimal file system block size
  blocks          # total data blocks in file system
  bfree           # free block in fs
  bavail          # free blocks avail to non-superuser
  files           # total file nodes in file system
  ffree           # free file nodes in fs
  vfstype         # what type of vfs this is
  fsize           # fundamental file system block size
  fname           # file system name (usually mount pt.)
  fpack           # file system pack name
  name_max        # maximum component name length for posix

=item mountpt PATH

Returns a string representing the mount point of the filesystem underlying the
specified C<PATH>, because sometimes C<<< statfs(...)->{fname} >>> doesn't work.
The current implementation is not much better than C<df | awk ...>;
future implementations may XS into df-like code for a faster solution.
If running under -T, C<PATH> MUST be clean before it is passed in.  The returned string
is tainted.  (I.e. this function presumes nothing about what comprises a valid path.)
On error, this function returns C<undef> and sets C<$@>;

=item Macros

Macros allowing mnemonic identification of vfstype (which is a number) are defined
as importable constants.  The following macros are defined (see C<sys/vmount.h>):

  MNT_AIX         # Same as MNT_J2
  MNT_J2          # AIX physical fs "jfs2"
  MNT_NAMEFS      # AIX pseudo fs "namefs"
  MNT_NFS         # SUN Network File System "nfs"
  MNT_JFS         # AIX R3 physical fs "jfs"
  MNT_CDROM       # CDROM File System "cdrom"
  MNT_PROCFS      # PROCFS File System "proc"
  MNT_USRVFS      # first 8 (0 - 7) reserved for IBM use
  MNT_SFS         # AIX Special FS (STREAM mounts)
  MNT_CACHEFS     # Cachefs file system
  MNT_NFS3        # NFSv3 file system
  MNT_AUTOFS      # Automount file system
  MNT_USRLAST     # last valid user file system
  MNT_VXFS        # THRPGIO File System "vxfs"
  MNT_VXODM       # For Veritas File System
  MNT_UDF         # UDFS file system
  MNT_NFS4        # NFSv4 file system
  MNT_RFS4        # NFSv4 Pseudo file system
  MNT_CIFS        # AIX SMBFS (CIFS client)
  MNT_AIXLAST     # last valid vfs number
  MNT_BADVFS      # always illegal vfs type

=back

=head1 EXPORT_TAGS

The following tags are exported.  To import by tag name, C<use LibExt::StatFS ":tagname">.
See C<Exporter> for details.

=over 4

=item func

 use LibExt::StatFS qw/:func/;

Imports all functions.  Currently, this is equivalent to:

 use LibExt::StatFS qw/statfs/;

=item macro

 use LibExt::StatFS qw/:macro/;

Imports all vfstype macros, as described above.

=item all

 use LibExt::StatFS qw/:all/;

Imports all symbols.  Equivalent to:

 use LibExt::StatFS qw/:func :macro/;

=back

=head1 SEE ALSO

=over 4

=item The C<statfs()> subroutine.

=item The C<sys/statfs.h> header file.

=item The C<sys/vmount.h> header file.

=item The C<sys/vfs.h> header file.

=back

=cut
