The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Paraniod::Filesystem - Filesystem Functions

MODULE VERSION

$Id: Filesystem.pm,v 0.11 2008/02/27 06:48:12 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);

  Paranoid::Filesystem::MAXLINKS = 20;
  $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');

REQUIREMENTS

Cwd Paranoid Paranoid::Debug

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.

VARIABLES

  Paranoid::Filesystem::MAXLINKS = 20;

This sets the maximum number of symlinks that will be tolerated in a filename for translation purposes. This prevents a runaway process due to circular references between symlinks.

FUNCTIONS

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.

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.

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.

  $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 exceeding the MAXLINKS threshold 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);

This function populates the passed array ref with any matches to the shell glob. The glob is a shell-style glob, but only a subset of the syntax is currently supported.

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

Shell meta-characters are not supported as filename characters (escaped), nor are back ticks, quotes, dollar and signs. Embedding globbing constructs within other constructs (like having a character class as part of a list element within an ellipsis) is not supported, nor are directory elements within ellipsis.

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.

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().

File arguments are processed through pglob which allows you to use globs to specify multiple existing files at once. Don't use globbing to create multiple new files at once -- it won't work the way that you think it will.

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.

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.

HISTORY

None as of yet.

AUTHOR/COPYRIGHT

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