#!/usr/bin/perl -w # rch.pl # pod at tail use strict; # avoid D'oh! bugs use User::pwent; # map username to uid/gid use File::Find; # recurse the filesystem $|++; # STDOUT hot my $user = shift; my $baseDir = shift; my $modeFile = oct(shift); my $modeDir = oct(shift); eXit() unless $< == 0; eXit() unless $baseDir && $user && $modeFile && $modeDir; eXit() unless grep /^[0-7]{1,4}$/, $modeFile, $modeDir; eXit() if $baseDir eq '/'; my $pw = getpwnam($user); eXit() unless($pw); my $uid = $pw->uid; my $gid = $pw->gid; sub chMOG { chmod($modeFile, $_) if(-f $_); chmod($modeDir, $_) if(-d $_); chown($uid, $gid, $_); } sub eXit { print "\nD'oh! Invalid/missing input or you're not root."; print "\nperldoc rch.pl and try again."; print "\nBut you can't perldoc as root."; print "\nSo there.\n\n"; exit; } find(\&chMOG, "$baseDir"); =head1 TITLE rch.pl - Recursively ch(mod|own|grp) files and directories =head1 SUMMARY rch.pl user base_dir file_mode dir_mode Base dir can be either relative or absolute, but *can't* be '/'. File and dir modes must be in octal, with or without the leading zero. 0664 = user+group:rw other:r 0775 = user+group:rwx other:rx 0644 = user:rw group+other:r 0755 = user:rwx group+other:rx =head1 USAGE rch.pl user base_dir file_mode dir_mode =head1 COMMENTS =head1 TESTED User::pwent (no VERSION) File::Path (no VERSION) Perl 5.006.01 Debian 3.0 =head1 UPDATES 2002-10-05 09:15 CST Tone down caution, as is no more hazardous than *nix ch(mod|own|grp) Post to PerlMonks Subify abort messages+exit Try and rule out Pod::Usage "Superuser must not run perldoc without security audit and taint checks" Sanity-check user-supplied file/dir modes Automate name-to-uid/gid mapping Accept octal file & dir modes as commandline args 2002-09-18 14:50 CST Fix borken POD 2002-08-04 12:15 CST Initial working code =head1 TODO Sanity-check user-provided username =head1 CREDITS Props to davis, jwest, rob_au, tye, demerphq and zigdon for tips in the CB. And to some guy named vroom. =head1 AUTHOR ybiC =cut