aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--METADATA4
-rw-r--r--lib/lib.c13
-rw-r--r--lib/lib.h4
-rwxr-xr-xtests/chmod.test2
4 files changed, 12 insertions, 11 deletions
diff --git a/METADATA b/METADATA
index 7cace572..4b21f3bd 100644
--- a/METADATA
+++ b/METADATA
@@ -9,12 +9,12 @@ third_party {
last_upgrade_date {
year: 2024
month: 5
- day: 23
+ day: 30
}
homepage: "https://landley.net/toybox/"
identifier {
type: "Git"
value: "https://github.com/landley/toybox"
- version: "2043855a4bd540e374f172778c37364a25f24d20"
+ version: "3c276ac106a4e3c0955149cc4a800ab95c1f296a"
}
}
diff --git a/lib/lib.c b/lib/lib.c
index 9561848a..dc578804 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -950,11 +950,11 @@ void list_signals(void)
}
// premute mode bits based on posix mode strings.
-mode_t string_to_mode(char *modestr, mode_t mode)
+unsigned string_to_mode(char *modestr, unsigned mode)
{
char *whos = "ogua", *hows = "=+-", *whats = "xwrstX", *whys = "ogu",
*s, *str = modestr;
- mode_t extrabits = mode & ~(07777);
+ unsigned extrabits = mode & ~(07777), bit;
// Handle octal mode
if (isdigit(*str)) {
@@ -966,9 +966,7 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// Gaze into the bin of permission...
for (;;) {
- int i, j, dowho, dohow, dowhat, amask;
-
- dowho = dohow = dowhat = amask = 0;
+ int i, j, dowho = 0, dohow = 0, dowhat, amask = 0;
// Find the who, how, and what stanzas, in that order
while (*str && (s = strchr(whos, *str))) {
@@ -984,6 +982,7 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// Repeated "hows" are allowed; something like "a=r+w+s" is valid.
for (;;) {
if (-1 == stridx(hows, dohow = *str)) goto barf;
+ dowhat = 0;
while (*++str && (s = strchr(whats, *str))) dowhat |= 1<<(s-whats);
// Convert X to x for directory or if already executable somewhere
@@ -998,12 +997,12 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// Loop through what=xwrs and who=ogu to apply bits to the 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
+ bit = 0;
if (i == 3) {
// suid and sticky
if (!j) bit = dowhat&16; // o+s = t but a+s doesn't set t, hence t
@@ -1031,7 +1030,7 @@ barf:
}
// Format access mode into a drwxrwxrwx string
-void mode_to_string(mode_t mode, char *buf)
+void mode_to_string(unsigned mode, char *buf)
{
char c, d;
int i, bit;
diff --git a/lib/lib.h b/lib/lib.h
index 5bc21f01..147bcf2f 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -410,8 +410,8 @@ void exit_signal(int signal);
void sigatexit(void *handler);
void list_signals(void);
-mode_t string_to_mode(char *mode_str, mode_t base);
-void mode_to_string(mode_t mode, char *buf);
+unsigned string_to_mode(char *mode_str, unsigned base);
+void mode_to_string(unsigned mode, char *buf);
char *getbasename(char *name);
char *fileunderdir(char *file, char *dir);
void *mepcpy(void *from, void *to, unsigned long len);
diff --git a/tests/chmod.test b/tests/chmod.test
index 97c9e939..8c4f5e63 100755
--- a/tests/chmod.test
+++ b/tests/chmod.test
@@ -114,6 +114,8 @@ SKIP=0
chtest +t "drwxr-xr-t\n-rw-r--r-T\n"
chtest a=r+w+x "drwxrwxrwx\n-rwxrwxrwx\n"
+chtest u+rwX-s,g+rX-ws,o+rX-wt "drwxr-xr-x\n-rw-r--r--\n"
+chtest u+rwX,u-s,g+rX,g-ws,o+rX,o-wt "drwxr-xr-x\n-rw-r--r--\n"
# (chtest starts off with a directory that's +x...)
testing "+X" \