views:

65

answers:

3

I would like $dir and everything underneath it to be read only. How can I set this using Perl?

+7  A: 

You could do this with a combination of File::Find and chmod (see perldoc -f chmod):

use File::Find;

sub wanted
{
    chmod 0555, $File::Find::name);
}
find(\&wanted, $dir);
Ether
Use this one. Better than mine.
Cfreak
+1  A: 

Untested but it should work. Note your directories themselves have to stay executable

set_perms($dir);

sub set_perms {
     my $dir = shift;
     opendir(my $dh, $dir) or die $!;
     while( (my $entry = readdir($dh) ) != undef ) {
          next if $entry =~ /^\.\.?$/;
          if( -d "$dir/$entry" ) {
              set_perms("$dir/$entry");
              chmod(0555, "$dir/$entry");
          }
          else {

              chmod(0444, "$dir/$entry");
          }
     }
     closedir($dh);
}

Of course you could execute a shell command from Perl as well:

system("find $dir -type f | xargs chmod 444");
system("find $dir -type d | xargs chmod 555");

I use xargs in case you have a lot of entries.

Cfreak
If you're using the shell, `chmod -R` is usually easiest.
Ether
@Ether - the problem with chmod -R is that you cannot distinguish between directories and regular files. You would have to set all files to executable which could be a security risk.
Cfreak
+1  A: 
system("chmod", "--recursive", "a-w", $dir) == 0
  or warn "$0: chmod exited " . ($? >> 8);
Greg Bacon

related questions