#!perl use 5.010_001; use strict; use warnings; use utf8; use Const::Fast; use File::stat; use Linux::Inotify2; our $VERSION = '0.03'; const our $SELF => 'inotifymask'; # Mask to remove the bits of stat->mode that we don't care about const our $STAT_MASK => oct '07777'; # Check argument count if ( @ARGV < 2 ) { printf {*STDERR} "%s: Need a mask and at least one file\n", $SELF; exit 2; } # Shift off mask as octal, remaining arguments are files my $mask = oct shift; my @files = @ARGV; # Process creation and move-in events my $cb = sub { my ($event) = @_; my $name = $event->fullname; # File must exist -e $name or return; # Must not be a directory not -d $name or return; # Get stats or give up my $stat = stat $name or return; # Get the mode we want for the file, masking off irrelevant file type bits my $mode = $stat->mode & $STAT_MASK; # Check that at least one bit of the mask coincides with one bit of the # present mode, i.e. that we'll be changing anything $mode & $mask or return; # Using the masked mode, change the permissions and log to stderr for ( $mode & ~$mask ) { chmod $_, $name or return; printf {*STDERR} "secured %s %o\n", $name, $_; } }; # Create object and set up watches with callback, start polling my $in = Linux::Inotify2->new; for (@files) { $in->watch( $_, IN_CREATE | IN_MOVED_TO, $cb ); } while (1) { $in->poll; }