Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 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 #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 }