Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/utils/file_mode.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 2492 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 #include <sys/stat.h>
2     #include <ctype.h>
3     #include <errno.h>
4     #include <limits.h>
5     #include <string.h>
6     #include <stdio.h>
7     #include <stdlib.h>
8    
9     #include "file_mode.h"
10    
11     extern char *progname;
12    
13     mode_t parse_file_mode(char *arg, mode_t mode, mode_t sumask)
14     {
15     char *clause;
16    
17     if (isdigit(*arg) && *arg < '8') {
18     unsigned long num;
19    
20     num = strtoul(arg, NULL, 8);
21     if ((num == ULONG_MAX && errno == ERANGE) || num > 07777) {
22     fprintf(stderr, "%s: invalid mode `%s'\n", progname,
23     arg);
24     exit(255);
25     }
26     return (mode_t) num;
27     }
28    
29     while ((clause = strsep(&arg, ",")) != NULL) {
30     mode_t who = 0;
31     int action;
32     char *p = clause;
33    
34     /*
35     * Parse the who list. Optional.
36     */
37     while (1) {
38     switch (*p++) {
39     case 'u':
40     who |= S_IRWXU | S_ISUID;
41     continue;
42     case 'g':
43     who |= S_IRWXG | S_ISGID;
44     continue;
45     case 'o':
46     who |= S_IRWXO | S_ISVTX;
47     continue;
48     case 'a':
49     who =
50     S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID |
51     S_ISGID | S_ISVTX;
52     continue;
53     }
54     /* undo the increment above */
55     p--;
56     break;
57     }
58    
59     if (who == 0)
60     who = (~sumask) | S_ISVTX;
61    
62     /*
63     * Parse an action list. Must be at least one action.
64     */
65     while (*p) {
66     mode_t perm = 0;
67    
68     /*
69     * Parse the action
70     */
71     action = *p;
72     if (action == '+' || action == '-' || action == '=')
73     p++;
74    
75     /*
76     * Parse perm
77     */
78     while (*p) {
79     switch (*p++) {
80     case 'r':
81     perm |= S_IRUSR | S_IRGRP | S_IROTH;
82     continue;
83     case 'w':
84     perm |= S_IWUSR | S_IWGRP | S_IWOTH;
85     continue;
86     case 'x':
87     perm |= S_IXUSR | S_IXGRP | S_IXOTH;
88     continue;
89     case 'X':
90     perm |= S_ISVTX;
91     continue;
92     case 's':
93     perm |= S_ISUID | S_ISGID;
94     continue;
95     case 'u':
96     perm = mode & S_IRWXU;
97     perm |= perm >> 3 | perm >> 6;
98     if (mode & S_ISUID)
99     perm |= S_ISGID;
100     continue;
101     case 'g':
102     perm = mode & S_IRWXG;
103     perm |= perm << 3 | perm >> 3;
104     if (mode & S_ISGID)
105     perm |= S_ISUID;
106     continue;
107     case 'o':
108     perm = mode & S_IRWXO;
109     perm |= perm << 6 | perm << 3;
110     continue;
111     }
112     /* undo the increment above */
113     p--;
114     break;
115     }
116    
117     perm &= who;
118    
119     switch (action) {
120     case '+':
121     mode |= perm;
122     continue;
123    
124     case '-':
125     mode &= ~perm;
126     continue;
127    
128     case '=':
129     mode &= ~who;
130     mode |= perm;
131     continue;
132     }
133    
134     if (!action)
135     break;
136     fprintf(stderr, "%s: invalid mode `%s'\n", progname,
137     clause);
138     exit(255);
139     }
140     }
141    
142     return mode;
143     }