Windows FindACLCache must hold scp write locked
[openafs.git] / src / WINNT / afsd / parsemode.c
1 /*
2  * Copyright 1991 by Vicent Archer. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <afsconfig.h>
24 #include <afs/param.h>
25 #include <roken.h>
26
27 #include <stdlib.h>
28 #include <sys/stat.h>
29 #include "parsemode.h"
30 #include "fs.h"
31
32 afs_uint32
33 parsemode(char *symbolic, afs_uint32 oldmode)
34 {
35     afs_uint32 who, mask, u_mask = 022, newmode, tmpmask;
36     char action;
37
38     newmode = oldmode & ALL_MODES;
39     while (*symbolic) {
40         who = 0;
41         for (; *symbolic; symbolic++) {
42                 if (*symbolic == 'a') {
43                         who |= ALL_MODES;
44                         continue;
45                 }
46                 if (*symbolic == 'u') {
47                         who |= USR_MODES;
48                         continue;
49                 }
50                 if (*symbolic == 'g') {
51                         who |= GRP_MODES;
52                         continue;
53                 }
54                 if (*symbolic == 'o') {
55                         who |= S_IRWXO;
56                         continue;
57                 }
58                 break;
59         }
60         if (!*symbolic || *symbolic == ',') {
61             fs_Die(EINVAL, "invalid mode");
62             exit(1);
63         }
64         while (*symbolic) {
65             if (*symbolic == ',')
66                 break;
67             switch (*symbolic) {
68             default:
69                 fs_Die(EINVAL, "invalid mode");
70                 exit(1);
71             case '+':
72             case '-':
73             case '=':
74                 action = *symbolic++;
75             }
76             mask = 0;
77             for (; *symbolic; symbolic++) {
78                 if (*symbolic == 'u') {
79                     tmpmask = newmode & S_IRWXU;
80                     mask |= tmpmask | (tmpmask << 3) | (tmpmask << 6);
81                     symbolic++;
82                     break;
83                 }
84                 if (*symbolic == 'g') {
85                     tmpmask = newmode & S_IRWXG;
86                     mask |= tmpmask | (tmpmask >> 3) | (tmpmask << 3);
87                     symbolic++;
88                     break;
89                 }
90                 if (*symbolic == 'o') {
91                     tmpmask = newmode & S_IRWXO;
92                     mask |= tmpmask | (tmpmask >> 3) | (tmpmask >> 6);
93                     symbolic++;
94                     break;
95                 }
96                 if (*symbolic == 'r') {
97                     mask |= S_IRUSR | S_IRGRP | S_IROTH;
98                     continue;
99                 }
100                 if (*symbolic == 'w') {
101                     mask |= S_IWUSR | S_IWGRP | S_IWOTH;
102                     continue;
103                 }
104                 if (*symbolic == 'x') {
105                     mask |= EXE_MODES;
106                     continue;
107                 }
108                 if (*symbolic == 's') {
109                     mask |= S_ISUID | S_ISGID;
110                     continue;
111                 }
112                 if (*symbolic == 'X') {
113                     if (S_ISDIR(oldmode) || (oldmode & EXE_MODES))
114                         mask |= EXE_MODES;
115                     continue;
116                 }
117                 if (*symbolic == 't') {
118                     mask |= S_ISVTX;
119                     who |= S_ISVTX;
120                     continue;
121                 }
122                 break;
123             }
124             switch (action) {
125             case '=':
126                 if (who)
127                     newmode &= ~who;
128                 else
129                     newmode = 0;
130             case '+':
131                 if (who)
132                     newmode |= who & mask;
133                 else
134                     newmode |= mask & (~u_mask);
135                 break;
136             case '-':
137                 if (who)
138                     newmode &= ~(who & mask);
139                 else
140                     newmode &= ~mask | u_mask;
141             }
142         }
143         if (*symbolic)
144             symbolic++;
145   }
146   return(newmode);
147 }
148