Introduction
Introduction Statistics Contact Development Disclaimer Help
mode.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
mode.c (2800B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6
7 #include "../util.h"
8
9 mode_t
10 getumask(void)
11 {
12 mode_t mask = umask(0);
13 umask(mask);
14 return mask;
15 }
16
17 mode_t
18 parsemode(const char *str, mode_t mode, mode_t mask)
19 {
20 char *end;
21 const char *p = str;
22 int octal, op;
23 mode_t who, perm, clear;
24
25 octal = strtol(str, &end, 8);
26 if (*end == '\0') {
27 if (octal < 0 || octal > 07777)
28 eprintf("%s: invalid mode\n", str);
29 return octal;
30 }
31 next:
32 /* first, determine which bits we will be modifying */
33 for (who = 0; *p; p++) {
34 switch (*p) {
35 /* masks */
36 case 'u':
37 who |= S_IRWXU|S_ISUID;
38 continue;
39 case 'g':
40 who |= S_IRWXG|S_ISGID;
41 continue;
42 case 'o':
43 who |= S_IRWXO|S_ISVTX;
44 continue;
45 case 'a':
46 who |= S_IRWXU|S_ISUID|S_IRWXG|S_ISGID|S_IRWXO|S…
47 continue;
48 }
49 break;
50 }
51 if (who) {
52 clear = who;
53 } else {
54 clear = S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO;
55 who = ~mask;
56 }
57 while (*p) {
58 switch (*p) {
59 /* opers */
60 case '=':
61 case '+':
62 case '-':
63 op = (int)*p;
64 break;
65 default:
66 eprintf("%s: invalid mode\n", str);
67 }
68
69 perm = 0;
70 switch (*++p) {
71 /* copy */
72 case 'u':
73 if (mode & S_IRUSR)
74 perm |= S_IRUSR|S_IRGRP|S_IROTH;
75 if (mode & S_IWUSR)
76 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
77 if (mode & S_IXUSR)
78 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
79 if (mode & S_ISUID)
80 perm |= S_ISUID|S_ISGID;
81 p++;
82 break;
83 case 'g':
84 if (mode & S_IRGRP)
85 perm |= S_IRUSR|S_IRGRP|S_IROTH;
86 if (mode & S_IWGRP)
87 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
88 if (mode & S_IXGRP)
89 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
90 if (mode & S_ISGID)
91 perm |= S_ISUID|S_ISGID;
92 p++;
93 break;
94 case 'o':
95 if (mode & S_IROTH)
96 perm |= S_IRUSR|S_IRGRP|S_IROTH;
97 if (mode & S_IWOTH)
98 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
99 if (mode & S_IXOTH)
100 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
101 p++;
102 break;
103 default:
104 for (; *p; p++) {
105 switch (*p) {
106 /* modes */
107 case 'r':
108 perm |= S_IRUSR|S_IRGRP|S_IROTH;
109 break;
110 case 'w':
111 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
112 break;
113 case 'x':
114 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
115 break;
116 case 'X':
117 if (S_ISDIR(mode) || mode & (S_I…
118 perm |= S_IXUSR|S_IXGRP|…
119 break;
120 case 's':
121 perm |= S_ISUID|S_ISGID;
122 break;
123 case 't':
124 perm |= S_ISVTX;
125 break;
126 default:
127 goto apply;
128 }
129 }
130 }
131
132 apply:
133 /* apply */
134 switch (op) {
135 case '=':
136 mode &= ~clear;
137 /* fallthrough */
138 case '+':
139 mode |= perm & who;
140 break;
141 case '-':
142 mode &= ~(perm & who);
143 break;
144 }
145 /* if we hit a comma, move on to the next clause */
146 if (*p == ',') {
147 p++;
148 goto next;
149 }
150 }
151 return mode & ~S_IFMT;
152 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.