trusty (3) Paranoid::Filesystem.3pm.gz

Provided by: libparanoid-perl_0.34-1_all bug

NAME

       Paranoid::Filesystem - Filesystem Functions

VERSION

       $Id: Filesystem.pm,v 0.20 2011/12/20 02:45:21 acorliss Exp $

SYNOPSIS

         use Paranoid::Filesystem;

         $rv = pmkdir("/foo", 0750);
         $rv = prm(\%errors, "/foo", "/bar/*");
         $rv = prmR(\%errors, "/foo/*");

         $rv = preadDir("/etc", \@dirList);
         $rv = psubdirs("/etc", \@dirList);
         $rv = pfiles("/etc", \@filesList);
         $rv = pglob("/usr/*", \@matches); # deprecated
         $rv = pglob(\%errors, \@matches, @globs);

         $noLinks = ptranslateLink("/etc/foo/bar.conf");
         $cleaned = pcleanPath($filename);

         $rv = ptouch(\%errors, $epoch, @files);
         $rv = ptouchR(1, \%errors, $epoch, @files);

         $rv = ptranslatePerms("ug+rwx");
         $rv = pchmod(\%errors, "ug+rw", "/foo", "./bar*");
         $rv = pchmodR(1, \%errors, $perms, @files);

         $rv = pchown(\%errors, $user, $group, @files);
         $rv = pchownR(1, \%errors, $user, $group, @files);

         $fullname = pwhich('ls');

DESCRIPTION

       This module provides a few functions to make accessing the filesystem a little easier, while instituting
       some safety checks.  If you want to enable debug tracing into each function you must set PDEBUG to at
       least 9.

       pcleanPath, ptranslateLink, and ptranslatePerms are only exported if this module is used with the :all
       target.

       NOTE: Previous versions of this module used the rather restrictive filename regexes for detainting
       arguments.  This is now handled by the Paranoid::Glob module, which detaints to pretty much everything a
       filesystem can handle.  Many of what used to be fatal errors are no longer so.  Programmatic errors are
       still fatal, but errors which may be due to user input are safely errored out, allowing program execution
       to continue.

SUBROUTINES/METHODS

   pmkdir
         $rv = pmkdir("/foo", 0750);

       This function simulates a 'mkdir -p {path}', returning false if it fails for any reason other than the
       directory already being present.  The second argument (permissions) is optional, but if present should be
       an octal number.  Shell-style globs are supported as the path argument.

       If you need to make a directory that includes characters which would normally be interpreted as shell
       expansion characters you can offer a Paranoid::Glob object as the path argument instead.  Creating such
       an object while passing it a literal boolean true value will prevent any shell expansion from happening.

       This method also allows you to call pmkdir with a list of directories to create, rather than just relying
       upon shell expansion to construct the list.

   prm
         $rv = prm(\%errors, "/foo", "/bar/*");

       This function unlinks non-directories and rmdir's directories.  File arguments are processed through
       pglob and expanded into multiple targets if globs are detected.

       The error message from each failed operation will be placed into the passed hash ref using the filename
       as the key.

       NOTE:  If you ask it to delete something that's not there it will silently succeed.  After all, not being
       there is what you wanted anyway, right?

   prmR
         $rv = prmR(\%errors, "/foo/*");

       This function works the same as prm but performs a recursive delete, similar to "rm -r" on the command
       line.

   preadDir
         $rv = preadDir("/etc", \@dirList);

       This function populates the passed array with the contents of the specified directory.  If there are any
       problems reading the directory the return value will be false and a string explaining the error will be
       stored in Paranoid::ERROR.

       All entries in the returned list will be prefixed with the directory name.  An optional third boolean
       argument can be given to filter out symlinks from the results.

   psubdirs
         $rv = psubdirs("/etc", \@dirList);

       This function calls preadDir in the background and filters the list for directory (or symlinks to)
       entries.  It also returns a true if the command was processed with no problems, and false otherwise.

       Like preadDir an optional third boolean argument can be passed that causes symlinks to be filtered out.

   pfiles
         $rv = pfiles("/etc", \@filesList);

       This function calls preadDir in the background and filters the list for file (or symlinks to) entries.
       It also returns a true if the command was processed with no problems, and false otherwise.

       Like preadDir an optional third boolean argument can be passed that causes symlinks to be filtered out.

   pcleanPath
         $cleaned = pcleanPath($filename);

       This function takes a filename and cleans out any '.', '..', and '//+' occurences within the path.  It
       does not remove '.' or '..' as the first path element, however, in order to preserve the root of the
       relative path.

       NOTE: this function does not do any checking to see if the passed filename/path actually exists or is
       valid in any way.  It merely removes the unnecessary artifacts from the string.

       If you're resolving an existing filename and want symlinks resolved to the real path as well you might be
       interested in Cwd's realpath function instead.

   ptranslateLink
         $noLinks = ptranslateLink("/etc/foo/bar.conf");

       This functions tests if passed filename is a symlink, and if so, translates it to the final target.  If a
       second argument is passed and evaluates to true it will check every element in the path and do a full
       translation to the final target.

       The final target is passed through pcleanPath beforehand to remove any unneeded path artifacts.  If an
       error occurs (like circular link references or the target being nonexistent) this function will return
       undef.  You can retrieve the reason for failure from Paranoid::ERROR.

       Obviously, testing for symlinks requires testing against the filesystem, so the target must be valid and
       present.

       Note: because of the possibility that relative links are being used (including levels of '..') all links
       are translated fully qualified from /.

   pglob
         $rv = pglob("/usr/*", \@matches);
         $rv = pglob(\%errors, \@matches, @globs);

       This function populates the passed array ref with any matches to the shell glob function.  This differs
       from that function, however, in that it only returns those files or directories that actually exist on
       the filesystem.

         *          Expanding wildcard (can be zero-length)
         ?          Single character wildcard (mandatory character)
         [a-z]      Character class
         {foo,bar}  Ellipsis list

       This returns a false if there is any problem processing the request, such as if there is an illegal
       globbing construct in the request or other types of errors.  Paranoid::ERROR will store a string
       explaining the failure, as well as an associated value in the passed hash reference (in the latter
       calling incarnation).

       Two forms of the function call are supported, primarily for backward compatibility purposes.  The latter
       is the preferred incarnation.

       NOTE: This function is now just a wrapper around Paranoid::Glob.  It may be advantageous for you to use
       it directly in lieu of pglob.

   ptouch
         $rv = ptouch(\%errors, $epoch, @files);

       Simulates the UNIX touch command.  Like the UNIX command this will create zero-byte files if they don't
       exist.  The first argument is the timestamp to apply to targets.  If undefined it will default to the
       current value of time().

       Shell-style globs are supported.

       The error message from each failed operation will be placed into the passed hash ref using the filename
       as the key.

   ptouchR
         $rv = ptouchR(1, \%errors, $epoch, @files);

       This function works the same as ptouch, but requires one additional argument (the first argument),
       boolean, which indicates whether or not the command should follow symlinks.

       You cannot use this function to create new, non-existant files, this only works to update an existing
       directory heirarchy's mtime.

   ptranslatePerms
         $rv = ptranslatePerms("ug+rwx");

       This translates symbolic mode notation into an octal number.  It fed invalid permissions it will return
       undef.  It understands the following symbols:

         u            permissions apply to user
         g            permissions apply to group
         o            permissions apply to all others
         r            read privileges
         w            write privileges
         x            execute privileges
         s            setuid/setgid (depending on u/g)
         t            sticky bit

       EXAMPLES

         # Add user executable privileges
         $perms = (stat "./foo")[2];
         chmod $perms | ptranslatePerms("u+x"), "./foo";

         # Remove all world privileges
         $perms = (stat "./bar")[2];
         chmod $perms ^ ptranslatePerms("o-rwx"), "./bar";

   pchmod
         $rv = pchmod(\%errors, "ug+rw", "/foo", "./bar*");

       This function takes a given permission and applies it to every file given to it.  The permission can be
       an octal number or symbolic notation (see ptranslatePerms for specifics).  If symbolic notation is used
       the permissions will be applied relative to the current permissions on each file.  In other words, it
       acts exactly like the chmod program.

       File arguments are processed through pglob and expanded into multiple targets if globs are detected.

       The error message from each failed operation will be placed into the passed hash ref using the filename
       as the key.

       The return value will be true unless any errors occur during the actual chmod operation including
       attempting to set permissions on non-existent files.

   pchmodR
         $rv = pchmodR(1, \%errors, $perms, @files);

       This function works the same as pchmod, but requires one additional argument (the first argument),
       boolean, which indicates whether or not the command should follow symlinks.

   pchown
         $rv = pchown(\%errors, $user, $group, @files);

       This function takes a user and/or a named group or ID and applies it to every file given to it.  If
       either the user or group is undefined it leaves that portion of ownership unchanged.

       File arguments are processed through pglob and expanded into multiple targets if globs are detected.

       The error message from each failed operation will be placed into the passed hash ref using the filename
       as the key.

       The return value will be true unless any errors occur during the actual chown operation including
       attempting to set permissions on non-existent files.

   pchownR
         $rv = pchownR(1, \%errors, $user, $group, @files);

       This function works the same as pchown, but requires one additional argument (the first argument),
       boolean, which indicates whether or not the command should follow symlinks.

   pwhich
         $fullname = pwhich('ls');

       This function tests each directory in your path for a binary that's both readable and executable by the
       effective user.  It will return only one match, stopping the search on the first match.  If no matches
       are found it will return undef.

DEPENDENCIES

       o   Carp

       o   Cwd

       o   Errno

       o   Fcntl

       o   Paranoid

       o   Paranoid::Debug

       o   Paranoid::Input

       o   Paranoid::Glob

BUGS AND LIMITATIONS

       ptranslateLink is probably pointless for 99% of the uses out there, you're better off using Cwd's
       realpath function instead.  The only thing it can do differently is translating a single link itself,
       without translating any additional symlinks found in the preceding path.  But, again, you probably won't
       want that in most circumstances.

       All of the *R recursive functions have the potential to be very expensive in terms of memory usage.  In
       an attempt to be fast (and reduce excessive function calls and stack depth) it utilizes Paranoid::Glob's
       recurse method.  In essence, this means that the entire directory tree is loaded into memory at once
       before any operations are performed.

       For the most part functions meant to simulate userland programs try to act just as those programs would
       in a shell environment.  That includes filtering arguments through shell globbing expansion, etc.  Should
       you have a filename that should be treated as a literal string you should put it into a Paranoid::Glob
       object as a literal first, and then hand the glob to the functions.

AUTHOR

       Arthur Corliss (corliss@digitalmages.com)

       This software is licensed under the same terms as Perl, itself.  Please see http://dev.perl.org/licenses/
       for more information.

       (c) 2005, Arthur Corliss (corliss@digitalmages.com)