#!/usr/bin/perl -w # # mode.pl, a program for setting permission on files and directories recursively. # # Copyright (c) 2006 Marcus Libäck <marcus@terminal.se> # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # use strict; use Getopt::Std; # Variables # ------------- my ( %opts, $dirmode, $filemode, ); my $recursive = 1; my $dircount = 0; my $filecount = 0; my $version = "1.1-051212"; # Main # ------------- getopts('d:f:Rh', \%opts); if (exists $opts{'h'}) { help(); } # Either -f, -d or both must be present. unless (exists $opts{'f'} or exists $opts{'d'}) { help(); } # Recursive unless (exists $opts{'R'}) { undef $recursive; } # Directory mode if (exists $opts{'d'}) { if ($opts{'d'} =~ m/^[0-7]{3,4}$/ ) { $dirmode = oct $opts{'d'}; } else { die "Invalid directory mode $opts{'d'}"; } } # File mode if (exists $opts{'f'}) { if ($opts{'f'} =~ m/^[0-7]{3,4}$/ ) { $filemode = oct $opts{'f'}; } else { die "Invalid file mode $opts{'f'}"; } } # Run mode() on each file specified in @ARGV. foreach (@ARGV) { if (defined $recursive) { mode_r ("$_"); } else { mode_n ("$_"); } } print "Mode adjusted for $dircount directories and $filecount files\n"; # Subroutines # ------------- # mode_r(), sets recursive permissions. sub mode_r { # Recursive my $entry = shift; if (opendir (DIR, $entry)) { # We end up here if $entry is a dir... if (defined $dirmode ) { chmod ($dirmode, $entry) or die $!; $dircount++; } foreach (sort readdir (DIR)) { next if $_ eq "." or $_ eq ".."; next if -l $_; # Recursive magic happens here. mode_r ("$entry/$_"); } } else { # ...and here if it is a file. if (defined $filemode) { chmod ($filemode, $entry) or die $!; $filecount++; } } closedir (DIR); } # mode_n(), sets non-recursive permissions. sub mode_n { # Non recursive my $entry = shift; # Regular file if (not -d $entry and defined $filemode) { chmod ($filemode, $entry) or die $!; $filecount++; # Directory, descends into $entry and chmods non-recursive. } elsif (-d $entry) { chdir "$entry"; opendir (DIR, "."); foreach (sort readdir (DIR)) { next if $_ eq ".."; next if -l $_; if (-d $_ and defined $dirmode) { chmod ($dirmode, $_) or die $!; $dircount++; } elsif (not -d $_ and defined $filemode) { chmod ($filemode, $_) or die $!; $filecount++; } } closedir (DIR); chdir ".."; } } # Help function. sub help { print "Version $version Usage: $0 [options] [files] Options: -h display this text. -R set modes recursively. -d NN directory mode. -f NN file mode.\n"; exit; }