diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2020-04-29 23:10:11 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2020-04-29 23:11:06 +1200 |
commit | 4e10a60e49e9e5d5baa06df1fcbeb1b5fdb103ee (patch) | |
tree | 31b4f0c591cecb8755ab859c6b82ae73f250a64e /bin | |
download | inotifymask-4e10a60e49e9e5d5baa06df1fcbeb1b5fdb103ee.tar.gz inotifymask-4e10a60e49e9e5d5baa06df1fcbeb1b5fdb103ee.zip |
First commitv0.01
Diffstat (limited to 'bin')
-rw-r--r-- | bin/inotifymask | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/bin/inotifymask b/bin/inotifymask new file mode 100644 index 0000000..55e6dd7 --- /dev/null +++ b/bin/inotifymask @@ -0,0 +1,69 @@ +#!perl + +use 5.028_001; +use strict; +use warnings; +use utf8; + +use Const::Fast; +use File::stat; +use Linux::Inotify2; + +our $VERSION = '0.01'; + +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; +} |