PerlPowerTools

 view release on metacpan or  search on metacpan

bin/chgrp  view on Meta::CPAN


usage() unless @ARGV > 1;

my $group = shift;

if (length($group) == 0) {
    warn "$Program: '' is an invalid group\n";
    exit EX_FAILURE;
}
my $gid = getgrnam $group;
unless (defined $gid) {
    $gid = $group if $group =~ m/\A[0-9]+\z/;
}
unless (defined $gid) {
    warn "$Program: '$group' is an invalid group\n";
    exit EX_FAILURE;
}

my %ARGV;
%ARGV = map {$_ => 1} @ARGV if $options {H};

if (exists $options {R}) {
    # Recursion.
    require File::Find;
    File::Find::find (\&modify_file, @ARGV);
}
else {
    foreach my $file (@ARGV) {
        modify_file($file);
    }
}
exit ($warnings ? EX_FAILURE : EX_SUCCESS);

# File::Find is weird. If called with a directory, it will call
# the sub with "." as file name, while having chdir()ed to the
# directory. But it doesn't do that in recursion, just the top
# level ones. And it ain't true that $File::Find::name eq
# "$File::Find::dir/$_" in all cases.
# But it shouldn't matter in this case.
sub modify_file {
    my $file = @_ ? shift : $_;
    # Now, if this is a symbolic link, it points somewhere,
    # *and* we are following symbolic links, we recurse.
    # This may never end as symlinks can form loops.
    if (-l $file && -e $file &&
                      ($options {L} || $options {H} && $ARGV {$file})) {
        # We don't want to recurse symlinks that just happen to
        # have the same name as one of the arguments, hence the local.
        # Remember that $file is relative to the current directory.
        local $ARGV {readlink $file} = 0;
        File::Find::find (\&modify_file, readlink $file);
        return;
    }
    my @st = stat $file;
    unless (@st) {
        warn "$Program: failed to stat '$file': $!\n";
        $warnings++;
        return;
    };
    my $uid = $st[4];
    unless (chown $uid, $gid, $file) {
        warn "$Program: '$file': $!\n";
	$warnings++;
    }
}

__END__

=pod

=head1 NAME

chgrp - change group ownership of files

=head1 SYNOPSIS

chgrp [-R [-H | -L | -P]] group file [files ...]

=head1 DESCRIPTION

I<chgrp> sets the group ownership of files. The first argument after the
options is the new group.

=head2 OPTIONS

I<chgrp> accepts the options described below. The options I<-L>,
I<-H> and I<-P> are mutually exclusive, and only the last given
option will be honoured. All of I<-L>, I<-H> and I<-P> require the
I<-R> option to be set first.

=over 4

=item -R

Recurse into directories. Any directories are recursively traversed,
and all files and directories will change owner.

=item -L

Follow symbolic links. By default, I<chgrp> will not follow symbolic
links. This is a potential dangerous option, as I<chgrp> will not
check for cycles. Be careful. This option requires the I<-R> option to be set.

=item -H

Follow symbolic links of command line files/directories only. This option
requires the I<-R> option to be set.

=item -P

Do not follow symbolic links at all. This option requires the I<-R> option
to be set.

=back

=head1 ENVIRONMENT

The working of I<chgrp> is not influenced by any environment variables.

=head1 BUGS



( run in 0.478 second using v1.01-cache-2.11-cpan-5511b514fd6 )