[hackers] [sbase] chmod: Implement X perm symbol || Michael Forney

From: <git_AT_suckless.org>
Date: Mon, 6 Jan 2020 22:53:47 +0100 (CET)

commit f3d05ffd0ac4226f9064be5c71606ab9b7d12d92
Author: Michael Forney <mforney_AT_mforney.org>
AuthorDate: Mon Jan 6 13:08:38 2020 -0800
Commit: Michael Forney <mforney_AT_mforney.org>
CommitDate: Mon Jan 6 13:47:26 2020 -0800

    chmod: Implement X perm symbol
    
    Instead of clearing the format bits before calling parsemode, leave
    them in so we can differentiate between directories and other files,
    then clear the format bits in the result.

diff --git a/chmod.1 b/chmod.1
index 4805ce0..fa4131d 100644
--- a/chmod.1
+++ b/chmod.1
_AT_@ -47,7 +47,7 @@ If
 .Ar mode
 is
 .Em symbolic
-"[ugoa]*[+-=][rwxst]*"
+"[ugoa]*[+-=][rwxXst]*"
 .Bl -tag -width Ds
 .It u|g|o|a
 owner | group | other (non-group) | everyone
_AT_@ -55,6 +55,8 @@ owner | group | other (non-group) | everyone
 add | remove | set
 .It r|w|x|s|t
 read | write | execute | setuid and setgid | sticky
+.It X
+execute, if directory or at least one execute bit is already set
 .El
 .Sh OPTIONS
 .Bl -tag -width Ds
diff --git a/chmod.c b/chmod.c
index 2a0085d..512a7ea 100644
--- a/chmod.c
+++ b/chmod.c
_AT_@ -13,7 +13,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r)
 {
         mode_t m;
 
- m = parsemode(modestr, st->st_mode & ~S_IFMT, mask);
+ m = parsemode(modestr, st->st_mode, mask);
         if (chmod(path, m) < 0) {
                 weprintf("chmod %s:", path);
                 ret = 1;
_AT_@ -50,8 +50,8 @@ main(int argc, char *argv[])
                         case 'P':
                                 r.follow = (*argv)[i];
                                 break;
- case 'r': case 'w': case 'x': case 's': case 't':
- /* -[rwxst] are valid modes, so we're done */
+ case 'r': case 'w': case 'x': case 'X': case 's': case 't':
+ /* -[rwxXst] are valid modes, so we're done */
                                 if (i == 1)
                                         goto done;
                                 /* fallthrough */
diff --git a/libutil/mode.c b/libutil/mode.c
index 5ba8eb1..b3632ad 100644
--- a/libutil/mode.c
+++ b/libutil/mode.c
_AT_@ -113,6 +113,10 @@ next:
                                 case 'x':
                                         perm |= S_IXUSR|S_IXGRP|S_IXOTH;
                                         break;
+ case 'X':
+ if (S_ISDIR(mode) || mode & (S_IXUSR|S_IXGRP|S_IXOTH))
+ perm |= S_IXUSR|S_IXGRP|S_IXOTH;
+ break;
                                 case 's':
                                         perm |= S_ISUID|S_ISGID;
                                         break;
_AT_@ -144,5 +148,5 @@ apply:
                         goto next;
                 }
         }
- return mode;
+ return mode & ~S_IFMT;
 }
Received on Mon Jan 06 2020 - 22:53:47 CET

This archive was generated by hypermail 2.3.0 : Mon Jan 06 2020 - 23:00:24 CET