| 1 | #!/usr/bin/perl |
| 2 | # chexec: turns a file's executability on or off, same semantics as rsync's --executability |
| 3 | # usage: chexec { + | - | --reference=<file> } <file> [...] |
| 4 | # Rename from setexec for consistency with chmod, etc. and cadaver's chexec - Matt 2009-07-02 |
| 5 | |
| 6 | $cmd = $ARGV[0]; |
| 7 | shift @ARGV; |
| 8 | |
| 9 | if ($cmd =~ /^--reference=(.*)$/) { |
| 10 | $ref_file = $1; |
| 11 | @stbuf = stat($ref_file); |
| 12 | if (@stbuf == 0) { |
| 13 | die "chexec: stat($ref_file): $!\n"; |
| 14 | } |
| 15 | $ref_perms = $stbuf[2] & 07777; |
| 16 | if (($ref_perms & 0111) == 0) { |
| 17 | $cmd = '-'; |
| 18 | } else { |
| 19 | $cmd = '+'; |
| 20 | } |
| 21 | } elsif ($cmd ne '+' && $cmd ne '-') { |
| 22 | die "usage: chexec { + | - | --reference=<file> } <file> [...]\n"; |
| 23 | } |
| 24 | |
| 25 | sub docmd($$) { |
| 26 | my ($cmd, $perms) = @_; |
| 27 | if ($cmd eq '+') { |
| 28 | return $perms | ($perms & 0444) >> 2; |
| 29 | } elsif ($cmd eq '-') { |
| 30 | return $perms & ~0111; |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | file: foreach $file (@ARGV) { |
| 35 | @stbuf = stat($file); |
| 36 | if (@stbuf == 0) { |
| 37 | warn "chexec: stat($file): $!, skipping file\n"; |
| 38 | next file; |
| 39 | } |
| 40 | $perms = $stbuf[2] & 07777; |
| 41 | $perms = docmd($cmd, $perms); |
| 42 | chmod($perms, $file) or warn "chexec: chmod($perms, $file): $!, skipping file\n"; |
| 43 | } |