1 /* mode.c - parse and apply symbolic modes (mode_t)
2 Copyright (c) 2022, Alan Potteiger
3 See `LICENSE` for copyright and license details */
5 #define _POSIX_C_SOURCE 200809L
6 #define _XOPEN_SOURCE 700 /* Single UNIX Specification, Version 4
7 required for `t` perm, S_ISVTX bits */
16 /* Following is an excerpt from the POSIX definition of `chmod` containing a
17 grammar for symbolic modes.
19 symbolic_mode : clause
20 | symbolic_mode ',' clause
31 who : 'u' | 'g' | 'o' | 'a'
43 permcopy : 'u' | 'g' | 'o'
52 perm : 'r' | 'w' | 'x' | 'X' | 's' | 't'
55 /* Accepts symbolic mode string `modestr` and applies its changes to `modeset`
56 Returns > 0 for any syntax errors */
58 modeset(char *modestr
, mode_t
*modeset
)
63 mode_t copy
, work
, who
, mode
;
67 /* if octal number we set the mode absolutely and return */
69 mode
= (mode_t
) strtol(ptr
, &end
, 8);
78 copy
= work
= who
= 0;
80 /* Find who's permissions we're editing */
81 for (; *ptr
!= '\0'; ptr
++) {
93 who
|= S_IRWXU
| S_IRWXG
| S_IRWXO
;
102 /* if no who specified, default to all */
104 who
|= S_IRWXU
| S_IRWXG
| S_IRWXO
;
119 /* find permissions/permcopy and setup mask to be used */
120 for (; *ptr
!= '\0'; ptr
++) {
123 work
= who
& (S_IRUSR
| S_IRGRP
| S_IROTH
);
126 work
= who
& (S_IWUSR
| S_IWGRP
| S_IWOTH
);
129 work
= who
& (S_IXUSR
| S_IXGRP
| S_IXOTH
);
164 /* invalid or missing permission character */
170 /* do our work on the given mode depending on our operator */
173 /* + operator: turn selected bits on */
177 /* - operator: turn selected bits off */
182 /* = operator: clear user permissions mentioned, then set */