aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-26 22:54:01 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-26 22:54:01 +0000
commit86724af484ec1b28410afb6457dd0be7c9bc16fb (patch)
tree72795b59063127982c40626a18aebb58461596bc
parentf98d637ba4763e296491bc298df5d99f1105bd19 (diff)
downloadbusybox-w32-86724af484ec1b28410afb6457dd0be7c9bc16fb.tar.gz
busybox-w32-86724af484ec1b28410afb6457dd0be7c9bc16fb.tar.bz2
busybox-w32-86724af484ec1b28410afb6457dd0be7c9bc16fb.zip
bb_parse_mode: do not do umask() needlessly.
-rw-r--r--libbb/parse_mode.c52
1 files changed, 18 insertions, 34 deletions
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c
index 356d95db6..3ab4eb6fc 100644
--- a/libbb/parse_mode.c
+++ b/libbb/parse_mode.c
@@ -9,49 +9,40 @@
9 9
10/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */ 10/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
11 11
12#include <stdlib.h>
13#include <assert.h>
14#include <sys/stat.h>
15#include "libbb.h" 12#include "libbb.h"
16 13
17#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 14#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
18 15
19int bb_parse_mode(const char *s, mode_t *current_mode) 16int bb_parse_mode(const char *s, mode_t *current_mode)
20{ 17{
21 static const mode_t who_mask[] = { 18 static const mode_t who_mask[] = {
22 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ 19 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
23 S_ISUID | S_IRWXU, /* u */ 20 S_ISUID | S_IRWXU, /* u */
24 S_ISGID | S_IRWXG, /* g */ 21 S_ISGID | S_IRWXG, /* g */
25 S_IRWXO /* o */ 22 S_IRWXO /* o */
26 }; 23 };
27
28 static const mode_t perm_mask[] = { 24 static const mode_t perm_mask[] = {
29 S_IRUSR | S_IRGRP | S_IROTH, /* r */ 25 S_IRUSR | S_IRGRP | S_IROTH, /* r */
30 S_IWUSR | S_IWGRP | S_IWOTH, /* w */ 26 S_IWUSR | S_IWGRP | S_IWOTH, /* w */
31 S_IXUSR | S_IXGRP | S_IXOTH, /* x */ 27 S_IXUSR | S_IXGRP | S_IXOTH, /* x */
32 S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */ 28 S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */
33 S_ISUID | S_ISGID, /* s */ 29 S_ISUID | S_ISGID, /* s */
34 S_ISVTX /* t */ 30 S_ISVTX /* t */
35 }; 31 };
36
37 static const char who_chars[] = "augo"; 32 static const char who_chars[] = "augo";
38 static const char perm_chars[] = "rwxXst"; 33 static const char perm_chars[] = "rwxXst";
39 34
40 const char *p; 35 const char *p;
41
42 mode_t wholist; 36 mode_t wholist;
43 mode_t permlist; 37 mode_t permlist;
44 mode_t mask;
45 mode_t new_mode; 38 mode_t new_mode;
46 char op; 39 char op;
47 40
48 assert(s);
49
50 if (((unsigned int)(*s - '0')) < 8) { 41 if (((unsigned int)(*s - '0')) < 8) {
51 unsigned long tmp; 42 unsigned long tmp;
52 char *e; 43 char *e;
53 44
54 tmp = strtol(s, &e, 8); 45 tmp = strtoul(s, &e, 8);
55 if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ 46 if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
56 return 0; 47 return 0;
57 } 48 }
@@ -59,16 +50,12 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
59 return 1; 50 return 1;
60 } 51 }
61 52
62 mask = umask(0);
63 umask(mask);
64
65 new_mode = *current_mode; 53 new_mode = *current_mode;
66 54
67 /* Note: We allow empty clauses, and hence empty modes. 55 /* Note: we allow empty clauses, and hence empty modes.
68 * We treat an empty mode as no change to perms. */ 56 * We treat an empty mode as no change to perms. */
69 57
70 while (*s) { /* Process clauses. */ 58 while (*s) { /* Process clauses. */
71
72 if (*s == ',') { /* We allow empty clauses. */ 59 if (*s == ',') { /* We allow empty clauses. */
73 ++s; 60 ++s;
74 continue; 61 continue;
@@ -76,8 +63,7 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
76 63
77 /* Get a wholist. */ 64 /* Get a wholist. */
78 wholist = 0; 65 wholist = 0;
79 66 WHO_LIST:
80 WHO_LIST:
81 p = who_chars; 67 p = who_chars;
82 do { 68 do {
83 if (*p == *s) { 69 if (*p == *s) {
@@ -95,7 +81,7 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
95 return 0; 81 return 0;
96 } 82 }
97 /* Since op is '=', clear all bits corresponding to the 83 /* Since op is '=', clear all bits corresponding to the
98 * wholist, of all file bits if wholist is empty. */ 84 * wholist, or all file bits if wholist is empty. */
99 permlist = ~FILEMODEBITS; 85 permlist = ~FILEMODEBITS;
100 if (wholist) { 86 if (wholist) {
101 permlist = ~wholist; 87 permlist = ~wholist;
@@ -124,13 +110,12 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
124 110
125 /* It was not a permcopy, so get a permlist. */ 111 /* It was not a permcopy, so get a permlist. */
126 permlist = 0; 112 permlist = 0;
127 113 PERM_LIST:
128 PERM_LIST:
129 p = perm_chars; 114 p = perm_chars;
130 do { 115 do {
131 if (*p == *s) { 116 if (*p == *s) {
132 if ((*p != 'X') 117 if ((*p != 'X')
133 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH)) 118 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
134 ) { 119 ) {
135 permlist |= perm_mask[(int)(p-perm_chars)]; 120 permlist |= perm_mask[(int)(p-perm_chars)];
136 } 121 }
@@ -140,15 +125,15 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
140 goto PERM_LIST; 125 goto PERM_LIST;
141 } 126 }
142 } while (*++p); 127 } while (*++p);
143 128 GOT_ACTION:
144 GOT_ACTION:
145 if (permlist) { /* The permlist was nonempty. */ 129 if (permlist) { /* The permlist was nonempty. */
146 mode_t tmp = ~mask; 130 mode_t tmp = wholist;
147 if (wholist) { 131 if (!wholist) {
148 tmp = wholist; 132 mode_t u_mask = umask(0);
133 umask(u_mask);
134 tmp = ~u_mask;
149 } 135 }
150 permlist &= tmp; 136 permlist &= tmp;
151
152 if (op == '-') { 137 if (op == '-') {
153 new_mode &= ~permlist; 138 new_mode &= ~permlist;
154 } else { 139 } else {
@@ -159,6 +144,5 @@ int bb_parse_mode(const char *s, mode_t *current_mode)
159 } 144 }
160 145
161 *current_mode = new_mode; 146 *current_mode = new_mode;
162
163 return 1; 147 return 1;
164} 148}