#!/usr/bin/perl # chexec: turns a file's executability on or off, same semantics as rsync's --executability # usage: chexec { + | - | --reference= } [...] # Rename from setexec for consistency with chmod, etc. and cadaver's chexec - Matt 2009-07-02 $cmd = $ARGV[0]; shift @ARGV; if ($cmd =~ /^--reference=(.*)$/) { $ref_file = $1; @stbuf = stat($ref_file); if (@stbuf == 0) { die "chexec: stat($ref_file): $!\n"; } $ref_perms = $stbuf[2] & 07777; if (($ref_perms & 0111) == 0) { $cmd = '-'; } else { $cmd = '+'; } } elsif ($cmd ne '+' && $cmd ne '-') { die "usage: chexec { + | - | --reference= } [...]\n"; } sub docmd($$) { my ($cmd, $perms) = @_; if ($cmd eq '+') { return $perms | ($perms & 0444) >> 2; } elsif ($cmd eq '-') { return $perms & ~0111; } } file: foreach $file (@ARGV) { @stbuf = stat($file); if (@stbuf == 0) { warn "chexec: stat($file): $!, skipping file\n"; next file; } $perms = $stbuf[2] & 07777; $perms = docmd($cmd, $perms); chmod($perms, $file) or warn "chexec: chmod($perms, $file): $!, skipping file\n"; }