#ifndef _PARSE_MODE_H #define _PARSE_MODE_H #include #define U(x) (x << 6) #define G(x) (x << 3) #define O(x) (x) #define A(x) (U(x) | G(x) | O(x)) #define WR_PERM (2) #define EX_PERM (1) #define RD_PERM (4) #define FULL_PERM (7) mode_t mu_parse_mode(const char *s, mode_t cur_mode) { char *p = NULL; mode_t mode = (mode_t)strtol(s, &p, 8); if (!*p && mode < 07777U) return mode; else if (mode > 07777U) return 0; mode = 0; int append = 1; mode_t mask = 0; for (size_t i = 0; i < strlen(s); i++) { switch (s[i]) { case 'r': mode |= A(RD_PERM); break; case 'w': mode |= A(WR_PERM); break; case 'x': mode |= A(EX_PERM); break; case '+': append = 1; break; case '-': append = 0; break; case 'g': mask |= G(FULL_PERM); break; case 'u': mask |= U(FULL_PERM); break; case 'o': mask |= O(FULL_PERM); break; case 'a': mask |= A(FULL_PERM); break; default: return 0; } } if (mask == 0) mask = U(FULL_PERM); mask = mask & mode; if (!append) mode = ~mode; return (cur_mode & ~mask) | (mode & mask); } #endif