File-Find-Node

 view release on metacpan or  search on metacpan

lib/File/Find/Node.pm  view on Meta::CPAN

package File::Find::Node;

use 5.006;
use strict;
use warnings;
use Carp;

our $VERSION = '0.03';

#
# constructor
#

use constant PATH     =>  0;
use constant NAME     =>  1;
use constant LEVEL    =>  2;
use constant PRUNE    =>  3;
use constant FOLLOW   =>  4;
use constant PARENT   =>  5;
use constant PROCESS  =>  6;
use constant POSTPROC =>  7;
use constant FILTER   =>  8;
use constant ERRPROC  =>  9;
use constant STAT     => 10;
use constant ARG      => 11;
use constant USER     => 12;
use constant GROUP    => 13;
use constant MAXFORK  => 14;

sub new {
    my ($class, $path) = @_;
    defined($path) or $path = ".";
    $path =~ s{/+}{/}g;
    $path =~ s{/$}{} if $path ne "/";
    my $self = [
        $path,  # PATH
        $path,  # NAME
        0,      # LEVEL
        0,      # PRUNE
        0,      # FOLLOW
        undef,  # PARENT
        undef,  # PROCESS
        undef,  # POSTPROC
        undef,  # FILTER
        undef,  # ERRPROC
        undef,  # STAT
        undef,  # ARG
        {},     # USER  cache for getpwuid()
        {},     # GROUP cache for getgrgid()
        0       # MAXFORK
    ];
    $self->[NAME] =~ s{.*/}{};
    bless($self);
}

#
# private object methods
#

# _error calls error callback function or calls carp().

sub _error {
    my ($self, $what) = @_;
    if ($self->[ERRPROC]) {
        $self->[ERRPROC]->($self, $what);
    }
    else {
        my $path = $self->[PATH];
        carp(__PACKAGE__, " - $what($path) - $!");
    }
}

# _cycle returns true if this directory is in the parent chain

sub _cycle {
    my $self = shift;
    my ($inum, $dev) = ($self->inum, $self->dev);
    for (my $p = $self->[PARENT]; $p; $p = $p->[PARENT]) {
        return 1 if $dev == $p->dev && $inum == $p->inum;
    }
    0;
}

#
# public object methods
#

sub process {
    my $self = shift;
    $self->[PROCESS] = shift;
    $self;
}

sub post_process {
    my $self = shift;
    $self->[POSTPROC] = shift;
    $self;
}

sub filter {
    my $self = shift;
    $self->[FILTER] = shift;
    $self;
}

sub error_process {
    my $self = shift;
    $self->[ERRPROC] = shift;

lib/File/Find/Node.pm  view on Meta::CPAN

}

sub level {
    shift->[LEVEL];
}

# These methods return saved stat info

sub stat {
    @{shift->[STAT]};
}

sub dev {
    shift->[STAT]->[0];
}

sub inum {
    shift->[STAT]->[1];
}

sub ino {
    shift->[STAT]->[1];
}

sub mode {
    shift->[STAT]->[2];
}

sub perm {
    shift->[STAT]->[2] & 07777;
}

sub type {
    my $idx = (shift->[STAT]->[2] >> 12) & 017;
    ("?", "p", "c", "?", "d", "?", "b", "?",
     "f", "?", "l", "?", "s", "?", "?", "?")[$idx];
}

sub links {
    shift->[STAT]->[3];
}

sub nlink {
    shift->[STAT]->[3];
}

sub uid {
    shift->[STAT]->[4];
}

sub gid {
    shift->[STAT]->[5];
}

sub user {
    my $self = shift;
    my $uid = $self->uid;
    if (exists($self->[USER]->{$uid})) {
        return $self->[USER]->{$uid};
    }
    my $user = getpwuid($uid);
    $self->[USER]->{$uid} = defined($user) ? $user : $uid;
}

sub group {
    my $self = shift;
    my $gid = $self->gid;
    if (exists($self->[GROUP]->{$gid})) {
        return $self->[GROUP]->{$gid};
    }
    my $group = getgrgid($gid);
    $self->[GROUP]->{$gid} = defined($group) ? $group : $gid;
}

sub rdev {
    shift->[STAT]->[6];
}

sub size {
    shift->[STAT]->[7];
}

sub atime {
    shift->[STAT]->[8];
}

sub mtime {
    shift->[STAT]->[9];
}

sub ctime {
    shift->[STAT]->[10];
}

sub blksize {
    shift->[STAT]->[11];
}

sub blocks {
    shift->[STAT]->[12];
}

# empty returns true for an empty directory or a zero length regular file,
# otherwise false.

sub empty {
    my $self = shift;
    my $ftype = $self->type;
    if ($ftype eq "f") {
        return $self->size == 0;
    }
    elsif ($ftype eq "d") {
        my $dirh;
        if (!opendir($dirh, $self->[PATH])) {
            $self->_error("opendir");
            return 0;
        }
        my $ret = 1;
        while (my $name = readdir($dirh)) {
            if ($name ne "." && $name ne "..") {
                $ret = 0;

lib/File/Find/Node.pm  view on Meta::CPAN

Returns the device number of the filesystem containing
the item.  You can determine when you cross mount points
with

  if ($f->parent &&  $f->dev != $f->parent->dev) { ... }

=item $f->inum

=item $f->ino

Returns the inode number.

=item $f->mode

Returns the mode bits.

=item $f->type

Returns a lower case letter indicating the type of the item:
  "f" - regular file
  "d" - directory
  "l" - symbolic link
  "b" - block device file
  "c" - character device file
  "p" - named pipe (FIFO)
  "s" - socket
  "?" - unknown (probably an error)

=item $f->perm

Returns the permission bits ($f->mode masked with 07777).
Here are the Unix permission bit definitions in octal:

            user  group other
          +------------------
  read    | 0400   040    04
  write   | 0200   020    02
  execute | 0100   010    01

  set user:   04000
  set group:  02000
  sticky:     01000

For example, to see if write is enabled for group or other:

  if (($f->perm & 022) != 0) { ... }

=item $f->links

=item $f->nlink

Returns the number of hard links.

=item $f->uid

Returns the user id number.

=item $f->user

Returns the user name or else returns the user id
number if getpwuid() fails.  Uses a cache to avoid
extra calls to getpwuid().

=item $f->gid

Returns the group id number.

=item $f->group

Returns the group name or else returns the group id
number if getgrgid() fails.  Uses a cache to avoid
extra calls to getgrgid().

=item $f->rdev

Returns the device number of a device file.

=item $f->size

Returns the size in bytes.

=item $f->atime

Returns the access time.

=item $f->mtime

Returns the modification time.

=item $f->ctime

Returns the inode change time.

=item $f->blksize

Returns the I/O block size of the containing filesystem.

=item $f->blocks

Returns the number of 512 byte blocks allocated for
the item.

=item $f->stat

Returns the array of saved stat information.

  @stat = $f->stat;

=item $f->refresh

Calls stat() or lstat() (depending on $f->follow) to refresh
the saved stat information.  Returns the object.  For
example, you may want to call $f->refresh after changing the
permissions of an object with chmod() or else $f->perm returns
the old saved permissions.

=back

=head1 Efficiency

File::Find::Node is both space and time efficient.  Although it
creates an object for each item in the traversal, at any given time



( run in 0.579 second using v1.01-cache-2.11-cpan-e1769b4cff6 )