micro-utils/libmu/parse_mode.h

84 lines
1.1 KiB
C

#ifndef _PARSE_MODE_H
#define _PARSE_MODE_H
#include <sys/stat.h>
#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