Selective CHMOD in Perl with pattern matching

Simple problems can become quite tricky to solve. Recently, I had to give FTP access to a large folder in which I had some private information.

I did not want to reorganize the folder just because of this access, and I was already using group permission that I couldn't change.

TIMTOWTDI applied, I choosed to created a small perl script that would check the name of a folder/file and, if this name matches some predefined pattern, would apply a specific chmod permission to it.

For example: pattern is “doh” and attached permission is “740”.

In the list below, directory todohpoh and file azodihazodihdoh will match and permission 740 will be applied to them.

$ ls -al /tmp  
total 64 
drwxrwxrwt 13 root     root     12288 oct 28 15:57 .
drwxr-xr-x 25 root     root     4096  fev 16  2009 .. 
-rw-r--r--  1 julien   julien   0     oct 28 15:57 azodihazodihdoh 
-rw-r--r--  1 julien   julien   2513  oct 13 14:30 dokulist  
drwxr-xr-x  2 julien   julien   4096  oct 27 18:18 prv 
drwxr-xr-x  2 alfresco hugetlb  4096  oct 27 10:46 sv728.tmp 
drwxr-xr-x  2 julien   julien   4096  oct 28 15:57 todohpoh  
drwxrwxrwt  2 root     root     4096  oct 12 07:58 .X11-unix 
drwxr-xr-x  2 julien   julien   4096  oct 27 18:19 xxXXprvfdz
drwxr-xr-x  2 julien   julien   4096  oct 27 18:19 xxzzzazzdazd
  • Program: chmod_selected_folders.pl
  • OS : Debian Lenny - Linux 2.6.26-1-686 #1 SMP
  • Tested on: v5.10.0 built for i486-linux-gnu-thread-multi
#! /usr/bin/perl -w
use strict;
# julien vehent - oct. 2009
# browse a list of folder and change the permission
# according to a defined list of patterns and perms

# perm_list contain pattern + associated chmod perm (user|group|others)
# the first pattern that matches is the one applied
# "default" is mandatory and applied when no pattern match the entry
#
my %perm_list = ( 
                  "prv" => "770", 
                  "default"=> "775" 
                );

my $verbose = 0;

sub check_recursively
{
   my $folder_name = $_[0];

   print "entering $folder_name\n";

   # open folder and loop on each entry
   opendir my($folder), $folder_name or die "Couldn't open $folder_name: $!\n";

   for my $entry (readdir($folder))
   {
      if(($entry eq ".") or ($entry eq ".."))
      {
         next;
      }

      my $entry_chmoded = 0;

      my $entry_full_path = $folder_name."/".$entry;

      # check entry with all patterns, except default
      foreach my $pattern (keys %perm_list)
      {
         # entry matches pattern, apply corresponding chmod and mark entry
         if (($entry =~ /$pattern/) and ($pattern ne "default"))
         {
            print "$pattern matches -> chmod $perm_list{$pattern} $entry_full_path\n" if $verbose == 1;

            system("chmod $perm_list{$pattern} \"$entry_full_path\"");

            $entry_chmoded = 1;
         }
      }

      # entry didn't match any pattern, apply default permission
      if($entry_chmoded == 0)
      {
         print "default -> chmod $perm_list{'default'} $entry_full_path\n" if $verbose == 1;

         system("chmod $perm_list{'default'} \"$entry_full_path\"");
      }

      #if entry is a folder, go visit it
      if ((-d $entry_full_path) and ($entry ne ".") and ($entry ne ".."))
      {
         check_recursively($entry_full_path);
      }

   }
   closedir($folder);
}


#--- MAIN CODE ---
unless(defined @ARGV)
{
   print "\nchmod_selected_folders.pl\njve - oct.2009\n\nusage: ./chmod_selected_folders.pl <folder 1> ... <folder n>\n\n";
}

print "using perm list:\n";
foreach my $pattern (keys %perm_list)
{
   print "  * pattern $pattern will be applied permission $perm_list{$pattern}\n";
}

# list of folder in stdin, loop on it
foreach my $folder_name (@ARGV)
{
   print "processing entries starting at $folder_name\n";

   check_recursively($folder_name);
}

If no pattern matches an entry, the one called default will be applied to it.

Discussion

Enter your comment
If you can't read the letters on the image, download this .wav file to get them read to you.
 
en/ressources/articles/perl_selective_chmod.txt · Last modified: 2011/03/16 01:30 (external edit)
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0