Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/file_mode.c
Parent Directory | Revision Log
Revision 532 -
(show 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)
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 | #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 | } |