source: trunk/minix/commands/simple/mkfifo.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.9 KB
Line 
1/* mkfifo - Make FIFO special files Author: V. Archer */
2
3/* Copyright 1991 by Vincent Archer
4 * You may freely redistribute this software, in source or binary
5 * form, provided that you do not alter this copyright mention in any
6 * way.
7 */
8
9#include <sys/types.h>
10#include <stdlib.h>
11#include <sys/stat.h>
12#include <string.h>
13#include <unistd.h>
14#include <minix/minlib.h>
15#include <stdio.h>
16
17#define USR_MODES (S_ISUID|S_IRWXU)
18#define GRP_MODES (S_ISGID|S_IRWXG)
19#define EXE_MODES (S_IXUSR|S_IXGRP|S_IXOTH)
20#ifdef S_ISVTX
21#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO|S_ISVTX)
22#else
23#define ALL_MODES (USR_MODES|GRP_MODES|S_IRWXO)
24#endif
25#define DEFAULT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
26
27
28/* Global u_mask needed in changemode.h */
29mode_t u_mask;
30
31_PROTOTYPE(int main, (int argc, char **argv));
32_PROTOTYPE(mode_t parsemode, (char *symbolic, mode_t oldmode));
33_PROTOTYPE(void usage, (void));
34
35/* Parse a P1003.2 4.7.7-conformant symbolic mode. */
36mode_t parsemode(char *symbolic, mode_t oldmode)
37{
38 mode_t who, mask, newmode, tmpmask;
39 char action;
40
41 newmode = oldmode & ALL_MODES;
42 while (*symbolic) {
43 who = 0;
44 for (; *symbolic; symbolic++) {
45 if (*symbolic == 'a') {
46 who |= ALL_MODES;
47 continue;
48 }
49 if (*symbolic == 'u') {
50 who |= USR_MODES;
51 continue;
52 }
53 if (*symbolic == 'g') {
54 who |= GRP_MODES;
55 continue;
56 }
57 if (*symbolic == 'o') {
58 who |= S_IRWXO;
59 continue;
60 }
61 break;
62 }
63 if (!*symbolic || *symbolic == ',') usage();
64 while (*symbolic) {
65 if (*symbolic == ',') break;
66 switch (*symbolic) {
67 default:
68 usage();
69 case '+':
70 case '-':
71 case '=': action = *symbolic++;
72 }
73 mask = 0;
74 for (; *symbolic; symbolic++) {
75 if (*symbolic == 'u') {
76 tmpmask = newmode & S_IRWXU;
77 mask |= tmpmask | (tmpmask << 3) | (tmpmask << 6);
78 symbolic++;
79 break;
80 }
81 if (*symbolic == 'g') {
82 tmpmask = newmode & S_IRWXG;
83 mask |= tmpmask | (tmpmask >> 3) | (tmpmask << 3);
84 symbolic++;
85 break;
86 }
87 if (*symbolic == 'o') {
88 tmpmask = newmode & S_IRWXO;
89 mask |= tmpmask | (tmpmask >> 3) | (tmpmask >> 6);
90 symbolic++;
91 break;
92 }
93 if (*symbolic == 'r') {
94 mask |= S_IRUSR | S_IRGRP | S_IROTH;
95 continue;
96 }
97 if (*symbolic == 'w') {
98 mask |= S_IWUSR | S_IWGRP | S_IWOTH;
99 continue;
100 }
101 if (*symbolic == 'x') {
102 mask |= EXE_MODES;
103 continue;
104 }
105 if (*symbolic == 's') {
106 mask |= S_ISUID | S_ISGID;
107 continue;
108 }
109 if (*symbolic == 'X') {
110 if (S_ISDIR(oldmode) || (oldmode & EXE_MODES))
111 mask |= EXE_MODES;
112 continue;
113 }
114#ifdef S_ISVTX
115 if (*symbolic == 't') {
116 mask |= S_ISVTX;
117 who |= S_ISVTX;
118 continue;
119 }
120#endif
121 break;
122 }
123 switch (action) {
124 case '=':
125 if (who)
126 newmode &= ~who;
127 else
128 newmode = 0;
129 case '+':
130 if (who)
131 newmode |= who & mask;
132 else
133 newmode |= mask & (~u_mask);
134 break;
135 case '-':
136 if (who)
137 newmode &= ~(who & mask);
138 else
139 newmode &= ~mask | u_mask;
140 }
141 }
142 if (*symbolic) symbolic++;
143 }
144 return(newmode);
145}
146
147
148/* Main module. Since only one option (-m mode) is allowed, there's no need
149 * to include the whole getopt() stuff.
150 */
151int main(argc, argv)
152int argc;
153char *argv[];
154{
155 int errors = 0;
156 char *symbolic;
157
158 if (argc > 2 && *argv[1] == '-' && strcmp(argv[1], "-m") != 0) usage();
159 argc--;
160 argv++;
161 if (argc && strncmp(*argv, "-m", (size_t) 2) == 0) {
162 argc--;
163 if ((argv[0])[2])
164 symbolic = (*argv++) + 2;
165 else {
166 if (!argc--) usage();
167 argv++;
168 symbolic = *argv++;
169 }
170 u_mask = umask(0);
171 umask(u_mask);
172 } else
173 symbolic = (char *) 0;
174
175 if (!argc) usage();
176 for (; argc--; argv++)
177 if (mkfifo(*argv, DEFAULT_MODE)) {
178 perror(*argv);
179 errors = 1;
180 } else if (symbolic && chmod(*argv, parsemode(symbolic, DEFAULT_MODE))) {
181 unlink(*argv);
182 perror(*argv);
183 errors = 1;
184 }
185 return(errors);
186}
187
188
189/* Posix command prototype. */
190void usage()
191{
192 std_err("Usage: mkfifo [-m mode] file...\n");
193 exit(1);
194}
Note: See TracBrowser for help on using the repository browser.