OSDN Git Service

Make chmod +w respect umask, implement +s and +t, fix ls to show suid/sgid/stid witho...
authorRob Landley <rob@landley.net>
Sun, 22 Jul 2012 03:45:05 +0000 (22:45 -0500)
committerRob Landley <rob@landley.net>
Sun, 22 Jul 2012 03:45:05 +0000 (22:45 -0500)
lib/lib.c
toys/ls.c

index 2b32109..69029a2 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -983,16 +983,20 @@ mode_t string_to_mode(char *modestr, mode_t mode)
 
        // Gaze into the bin of permission...
        for (;;) {
-               int i, j, dowho, dohow, dowhat;
+               int i, j, dowho, dohow, dowhat, amask;
 
-               dowho = dohow = dowhat = 0;
+               dowho = dohow = dowhat = amask = 0;
 
                // Find the who, how, and what stanzas, in that order
                while (*str && (s = strchr(whos, *str))) {
                        dowho |= 1<<(s-whos);
                        str++;
                }
-               if (!dowho) dowho = 8;
+               // If who isn't specified, like "a" but honoring umask.
+               if (!dowho) {
+                       dowho = 8;
+                       umask(amask=umask(0));
+               }
                if (!*str || !(s = strchr(hows, *str))) goto barf;
                dohow = *(str++);
 
@@ -1018,19 +1022,26 @@ mode_t string_to_mode(char *modestr, mode_t mode)
                for (i=0; i<4; i++) {
                        for (j=0; j<3; j++) {
                                mode_t bit = 0;
+                               int where = 1<<((3*i)+j);
+
+                               if (amask & where) continue;
 
                                // Figure out new value at this location
                                if (i == 3) {
-                               } else if (dowhat&(1<<j)) bit++;
+                                       // suid/sticky bit.
+                                       if (j) {
+                                               if ((dowhat & 8) && (dowho&(8|(1<<i)))) bit++;
+                                       } else if (dowhat & 16) bit++;
+                               } else {
+                                       if (!(dowho&(8|(1<<i)))) continue;
+                                       if (dowhat&(1<<j)) bit++;
+                               }
 
                                // When selection active, modify bit
-                               if (dowho&(8|(1<<i))) {
-                                       int where = 1<<((3*i)+j);
 
-                                       if (dohow == '=' || (bit && dohow == '-'))
-                                               mode &= ~where;
-                                       if (bit && dohow != '-') mode |= where;
-                               }
+                               if (dohow == '=' || (bit && dohow == '-'))
+                                       mode &= ~where;
+                               if (bit && dohow != '-') mode |= where;
                        }
                }
 
index 6d0050f..561b353 100644 (file)
--- a/toys/ls.c
+++ b/toys/ls.c
@@ -374,7 +374,7 @@ static void listfiles(int dirfd, struct dirtree *indir)
                 c = i%3;
                 if (!c && (mode & (1<<((d=i/3)+9)))) {
                     c = "tss"[d];
-                    if (!bit) c &= 0x20;
+                    if (!bit) c &= ~0x20;
                 } else c = bit ? "xwr"[c] : '-';
                 perm[9-i] = c;
             }