diff --git a/bin/mkdir b/bin/mkdir index ee9964d3..fd30d4ac 100755 --- a/bin/mkdir +++ b/bin/mkdir @@ -17,7 +17,7 @@ use strict; use File::Basename qw(basename dirname); use Getopt::Std qw(getopts); -our $VERSION = '1.3'; +our $VERSION = '1.4'; my $Program = basename($0); $SIG{__WARN__} = sub { warn "$Program: @_\n" }; @@ -126,7 +126,7 @@ foreach my $directory (@ARGV) { my $realmode = $options{'m'}; if ($symbolic) { - $realmode = mod($options{'m'}, $dir) or + $realmode = mod($options{'m'}) or die "invalid mode: $options{m}\n"; } chmod oct($realmode) => $dir or warn "$!\n"; @@ -145,18 +145,12 @@ exit($err ? EX_ERROR : EX_SUCCESS); # # -sub mod ($$) { +sub mod { my $symbolic = shift; my $file = shift; - # Initialization. - # The 'user', 'group' and 'other' groups. - my @ugo = qw /u g o/; - # Bit masks for '[sg]uid', 'sticky', 'read', 'write' and 'execute'. - # Can't use qw // cause silly Perl doesn't know '2' is a number - # when dealing with &= ~$bit. - my %bits = (s => 8, t => 8, r => 4, w => 2, x => 1); - + my @ugo = qw/u g o/; + my %bits = ('s' => 8, 't' => 8, 'r' => 4, 'w' => 2, 'x' => 1); # For parsing. my $who_re = '[augo]*'; @@ -164,7 +158,13 @@ sub mod ($$) { # Find the current permissions. This is what we start with. - my $mode = sprintf "%04o" => (stat $file) [2] || 0; + my $mode = '777'; + if ($symbolic =~ m/[\-\+]/) { + my @st = stat $file; + if (@st) { + $mode = sprintf '%04o', $st[2]; + } + } my $current = substr $mode => -3; # rwx permissions for ugo. my %perms; @@ -248,6 +248,9 @@ sub mod ($$) { else {%perms = %umask;} next; } + if ($operator eq '=') { + $perms{$who} = 0; + } # If we arrive here, $perms is a string. # We can iterate over the characters. @@ -308,9 +311,8 @@ sub mod ($$) { # Apply. foreach my $s (@set) { - do {$perms {$s} |= $bit; next} if $operator eq '+'; + do {$perms {$s} |= $bit; next} if ($operator eq '+' || $operator eq '='); do {$perms {$s} &= ~$bit; next} if $operator eq '-'; - do {$perms {$s} = $bit; next} if $operator eq '='; die "Weird operator `$operator' found\n"; # Should not happen. }