Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/libbb/parse_mode.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (hide annotations) (download)
Sun May 30 11:32:42 2010 UTC (13 years, 11 months ago) by niro
File MIME type: text/plain
File size: 3433 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * parse_mode implementation for busybox
4     *
5     * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6     *
7     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8     */
9    
10     /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
11    
12     #include "libbb.h"
13    
14 niro 816 /* This function is used from NOFORK applets. It must not allocate anything */
15 niro 532
16 niro 816 #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
17    
18     int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
19 niro 532 {
20     static const mode_t who_mask[] = {
21     S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
22 niro 816 S_ISUID | S_IRWXU, /* u */
23     S_ISGID | S_IRWXG, /* g */
24     S_IRWXO /* o */
25 niro 532 };
26     static const mode_t perm_mask[] = {
27     S_IRUSR | S_IRGRP | S_IROTH, /* r */
28     S_IWUSR | S_IWGRP | S_IWOTH, /* w */
29     S_IXUSR | S_IXGRP | S_IXOTH, /* x */
30     S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */
31 niro 816 S_ISUID | S_ISGID, /* s */
32     S_ISVTX /* t */
33 niro 532 };
34 niro 816 static const char who_chars[] ALIGN1 = "augo";
35     static const char perm_chars[] ALIGN1 = "rwxXst";
36 niro 532
37     const char *p;
38     mode_t wholist;
39     mode_t permlist;
40     mode_t new_mode;
41     char op;
42    
43 niro 984 if ((unsigned char)(*s - '0') < 8) {
44 niro 532 unsigned long tmp;
45     char *e;
46    
47 niro 816 tmp = strtoul(s, &e, 8);
48 niro 532 if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
49     return 0;
50     }
51     *current_mode = tmp;
52     return 1;
53     }
54    
55     new_mode = *current_mode;
56    
57 niro 816 /* Note: we allow empty clauses, and hence empty modes.
58 niro 532 * We treat an empty mode as no change to perms. */
59    
60     while (*s) { /* Process clauses. */
61     if (*s == ',') { /* We allow empty clauses. */
62     ++s;
63     continue;
64     }
65    
66     /* Get a wholist. */
67     wholist = 0;
68 niro 816 WHO_LIST:
69 niro 532 p = who_chars;
70     do {
71     if (*p == *s) {
72     wholist |= who_mask[(int)(p-who_chars)];
73     if (!*++s) {
74     return 0;
75     }
76     goto WHO_LIST;
77     }
78     } while (*++p);
79    
80     do { /* Process action list. */
81     if ((*s != '+') && (*s != '-')) {
82     if (*s != '=') {
83     return 0;
84     }
85     /* Since op is '=', clear all bits corresponding to the
86 niro 816 * wholist, or all file bits if wholist is empty. */
87 niro 532 permlist = ~FILEMODEBITS;
88     if (wholist) {
89     permlist = ~wholist;
90     }
91     new_mode &= permlist;
92     }
93     op = *s++;
94    
95     /* Check for permcopy. */
96     p = who_chars + 1; /* Skip 'a' entry. */
97     do {
98     if (*p == *s) {
99     int i = 0;
100     permlist = who_mask[(int)(p-who_chars)]
101     & (S_IRWXU | S_IRWXG | S_IRWXO)
102     & new_mode;
103     do {
104     if (permlist & perm_mask[i]) {
105     permlist |= perm_mask[i];
106     }
107     } while (++i < 3);
108     ++s;
109     goto GOT_ACTION;
110     }
111     } while (*++p);
112    
113     /* It was not a permcopy, so get a permlist. */
114     permlist = 0;
115 niro 816 PERM_LIST:
116 niro 532 p = perm_chars;
117     do {
118     if (*p == *s) {
119     if ((*p != 'X')
120 niro 816 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
121 niro 532 ) {
122     permlist |= perm_mask[(int)(p-perm_chars)];
123     }
124     if (!*++s) {
125     break;
126     }
127     goto PERM_LIST;
128     }
129     } while (*++p);
130 niro 816 GOT_ACTION:
131 niro 532 if (permlist) { /* The permlist was nonempty. */
132 niro 816 mode_t tmp = wholist;
133     if (!wholist) {
134     mode_t u_mask = umask(0);
135     umask(u_mask);
136     tmp = ~u_mask;
137 niro 532 }
138     permlist &= tmp;
139     if (op == '-') {
140     new_mode &= ~permlist;
141     } else {
142     new_mode |= permlist;
143     }
144     }
145     } while (*s && (*s != ','));
146     }
147    
148     *current_mode = new_mode;
149     return 1;
150     }