# safeops.pl
#  Should be operations here which will cache returns from
system calls.
#  The effect we are seeking is two fold: 1) we cache
returned values so
#  that there is a chance to speed up the performance
and 2) we provide a
#  restricted set of calls which are available to
"rules" and hence control
#  access to the system as we desire.
#
#  It
should be noted that this routine has access to the "real" namespace
#  in
which "kuangplus" operates. This is in contrast to the "rule" which
#  has
access only to those things (variables and routines) "shared" to it
#  by
the main kuangplus calling routine.

# SafeOps::stat()
#   Routine which
emulates the behaviour of the real "stat()" sub routine.
#   This one
however, will cache lookups and so improve performance of
#   routines
which call it.
sub SafeOps::stat {

    my($name) = $_[0];
    

KuangPlus::pdebug "safe stat($name) called", 10.3;
    if ( $name =~
/^([\w\/\.]+)$/ ) {
        if ( ! defined($KuangPlus::stat_cache{$1}) ) {

KuangPlus::pdebug "caching entry for \"$name\" called", 10.3;

$KuangPlus::stat_cache{$1} = [ stat($1) ];
        }

return @{$KuangPlus::stat_cache{$1}};
    } else {
        return ();

}
} # end of SafeOps::stat()

# SafeOps::uname
#   Front end for the
POSIX::uname call to make it available for "rules"
#   which won't have
access to the POSIX library of routines.
#
# Expects: no arguments
#
Returns: a 5 element array as described below.
# Side Effects: caches the
value of the uname so that subsequent calls will
# get the cached value and
not need to call the library routine again.
#
# POSIX::uname returns the
following list: 
#       ($sysname, $nodename, $release, $version,
$machine)
# 
# discussion: Without the "{local $^W ... }" fiddle around
this, we get a
# > Subroutine KuangPlus::uname redefined at
# >
/home/jhoward/Kuangplus/new-work/wip/safeops.pl line 41.
# This particular
fiddle is suggested on p.589 of "Programming Perl, 1996".

sub
SafeOps::uname {

    pdebug "safeops - uname(): invoked ...", 11.3;
    if
( ! defined(@KuangPlus::uname) ) {
        pdebug "safeops - uname():
caching value ...", 11.3;
        use POSIX;
        @KuangPlus::uname =
POSIX::uname();
    }
    pdebug "safeops - uname(): returning
\"@KuangPlus::uname\".", 11.3;
    return @KuangPlus::uname;
} # end of
SafeOps::uname()

sub SafeOps::getpwent {
    
    my(@pwent_a);


pdebug "SafeOps::getpwent(): invoked ...", 12.3;
    #getpwent returns a
list:
    #   ($name, $pwd, $uid, $gid, $quot, $comment, $gcos, $dir,
$shell) 
    if ( ! defined(%KuangPlus::pwd_cache) ) {
        pdebug
"SafeOps::getpwent(): initialising data ...", 12.3;

$KuangPlus::pwd_max = -1;
        while ( @pwent_a = getpwent() ) {

$KuangPlus::pwd_max++;
            pdebug "SafeOps::getpwent():
$KuangPlus::pwd_max: @pwent_a",
                '12.3';

$KuangPlus::pwd_cache{$KuangPlus::pwd_max} = [ @pwent_a ];

$KuangPlus::pwd_by_name{$pwent_a[0]} = 

$KuangPlus::pwd_cache{$KuangPlus::pwd_max};

$KuangPlus::pwd_by_uid{$pwent_a[2]} = 

$KuangPlus::pwd_cache{$KuangPlus::pwd_max};
        }
        pdebug
"SafeOps::getpwent(): $KuangPlus::pwd_max values", 12.3;

$KuangPlus::counter = 0;
    }
    pdebug "pwd counter is
$KuangPlus::counter, max is $KuangPlus::pwd_max\n",
        12.3;
    if (
$KuangPlus::counter <= $KuangPlus::pwd_max ) {
        pdebug "Should
return @{$KuangPlus::pwd_cache{$KuangPlus::counter}}\n",
            12.3;

return @{$KuangPlus::pwd_cache{$KuangPlus::counter++}};
    } else
{
        $KuangPlus::counter = 0;
        return;
    }
} # end of
SafeOps::getpwent()

sub SafeOps::getpwnam {
    my($v) = $_[0];


pdebug "SafeOps::getpwnam($v): invoked ...", 13.3;
    # getpwnam(NAME)
returns a list:
    #   ($name, $pwd, $uid, $gid, $quota, $comment, $gcos,
$dir, $shell)
    SafeOps::getpwent if ( ! defined(%KuangPlus::pwd_by_name)
);
    
    return @{$KuangPlus::pwd_by_name{$v}};
} # end of
SafeOps::getpwnam()

sub SafeOps::getpwuid {
    my($v) = $_[0];


pdebug "SafeOps::getpwuid($v): invoked ...", 14.3;
    # getpwnam(UID)
returns a list:
    #   ($name, $pwd, $uid, $gid, $quota, $comment, $gcos,
$dir, $shell)
    SafeOps::getpwent if ( ! defined(%KuangPlus::pwd_by_uid)
);

    return @{$KuangPlus::pwd_by_uid{$v}};
} # end of
SafeOps::getpwuid()

1;

