#! /usr/local/bin/perl -w # # recurse755dir.pl ############################################################## # A simple program to recurse directories and make sure that # # any directories owned by the user are mode 755. # ############################################################## use strict; use Cwd; # Get the current working directory ############# # Variables # ############# my $args = ""; # to parse arguments my $confirm = 1; # confirm = 1, no confirm = 2 my $dirname = ""; # a scalar to hold the filename # Accept a directory as an argument to begin parsing on, # else assume ./ $args = "\t" . ( join "\t", @ARGV ) . "\t"; if ( $args =~ /\t-h\t/ ) { &print_usage(); } if ( $args =~ /\t-nc\t/ ) { print STDERR "Confirm is turned off!\n"; $confirm = 0; } if ( $args =~ /\t([^\t]+?)\t$/ ) { if ( -d $1 ) { $dirname = getcwd . "/$1"; $dirname =~ s'/$''; } else { &print_usage("The supplied argument was not a directory: >$1<"); } } else { $dirname = getcwd; } print "Welcome to $0\n\n"; print "This program will recurse through your directory structure and prompt you\n"; print "to change your directory permissions to 755. Every attempt will be made\n"; print "to accurately log the actions performed and to create an UNDO file. If\n"; print "you agree to do this please type in \"yes\" now: "; chomp( my $answer = ); &print_usage("You changed your mind") if ( $answer ne "yes" ); if ( !$confirm ) { print "You have also selected to turn off confirmation! This is a dumb idea, but\n"; print "if you would like to proceed type in \"yes\" now :"; chomp( $answer = ); &print_usage("You wisely decided not to run in unconfirm mode") if ( $answer ne "yes" ); } # Two arrays - one will store the work done, one will store the undo information my ( @log, @undo ); push @log, "+-- recurse755dir began --+\n"; push @undo, "cd " . getcwd . "\n"; &recurse_dirs( $dirname, $confirm, \@log, \@undo ); push @log, "+-- recurse755dir ended --+\n"; # Save the two arrays to disk open( FILEHANDLE, ">>recurse755dir.log" ) or &print_usage("Could not open log"); print FILEHANDLE join "", @log; close(FILEHANDLE); open( FILEHANDLE, ">>recurse755dir.UNDO" ) or &print_usage("Could not open log"); print FILEHANDLE join "", @undo; close(FILEHANDLE); exit; sub recurse_dirs { my ( $dir, $confirm, $logref, $undoref ) = @_; my ( $mode, @contents ); my $answer = "N"; # Converts the mode returned into a standard format $mode = sprintf( "%04o", ( stat($dir) )[2] & 07777 ); return if ( !-d _ ); push @$logref, "| $dir : $mode\n"; if ( $mode ne "0755" ) { if ($confirm) { print "$dir is mode $mode, change (y/N)? "; chomp( $answer = ); } else { $answer = "y"; } if ( $answer eq "y" ) { push @$logref, "+-" . "-" x ( length($dir) ) . " : 0755\n"; push @$undoref, "chmod $mode $dir\n"; chmod 0755, $dir; } } opendir DIRHANDLE, $dir; @contents = readdir(DIRHANDLE); closedir DIRHANDLE; foreach (@contents) { next if /^\.+$/; # Skip ./ and ../ &recurse_dirs( "$dir/$_", $confirm, $logref, $undoref ); } } sub print_usage { my $message = shift; if ( defined($message) && ( $message ne "" ) ) { print "$message\n\n"; } print "$0 <-h> <-nc> \n"; print "\n"; print "This program recurses directories and prompts to change their mode\n"; print "to 755. Start a level above where you wish to begin the recurse.\n"; print "\n"; print "usage: $0 -h # print this message\n"; print " $0 /home/mike/lib/perl # make all dirs under this mode 0755\n"; print " $0 # start within current dir\n"; print " $0 -nc # same, but disable confirm mode change\n"; print "\n"; exit; }