diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-26 22:54:01 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-26 22:54:01 +0000 |
commit | e90dd432cbb7cbaeded7253f04bf6fe464ba645d (patch) | |
tree | 72795b59063127982c40626a18aebb58461596bc | |
parent | 6324554beeab7889ab2e56e756eed1d1a67e4b21 (diff) | |
download | busybox-w32-e90dd432cbb7cbaeded7253f04bf6fe464ba645d.tar.gz busybox-w32-e90dd432cbb7cbaeded7253f04bf6fe464ba645d.tar.bz2 busybox-w32-e90dd432cbb7cbaeded7253f04bf6fe464ba645d.zip |
bb_parse_mode: do not do umask() needlessly.
git-svn-id: svn://busybox.net/trunk/busybox@17542 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | libbb/parse_mode.c | 52 |
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 | ||
19 | int bb_parse_mode(const char *s, mode_t *current_mode) | 16 | int 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 | } |