Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/mkdir.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: 2845 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 <sys/types.h>
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10
11 #include "file_mode.h"
12
13 static mode_t leaf_mode, subdir_mode;
14 static int p_flag;
15
16 char *progname;
17
18 static __noreturn usage(void)
19 {
20 fprintf(stderr, "Usage: %s [-p] [-m mode] dir...\n", progname);
21 exit(1);
22 }
23
24 static int make_one_dir(char *dir, mode_t mode)
25 {
26 struct stat stbuf;
27
28 if (mkdir(dir, mode) == -1) {
29 int err = errno;
30
31 /*
32 * Ignore the error if it all of the following
33 * are satisfied:
34 * - error was EEXIST
35 * - -p was specified
36 * - stat indicates that its a directory
37 */
38 if (p_flag && errno == EEXIST &&
39 stat(dir, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
40 return 1;
41 errno = err;
42 fprintf(stderr, "%s: ", progname);
43 perror(dir);
44 return -1;
45 }
46 return 0;
47 }
48
49 static int make_dir(char *dir)
50 {
51 int ret;
52
53 if (p_flag) {
54 char *s, *p;
55
56 /*
57 * Recurse each directory, trying to make it
58 * as we go. Should we check to see if it
59 * exists, and if so if it's a directory
60 * before calling mkdir?
61 */
62 s = dir;
63 while ((p = strchr(s, '/')) != NULL) {
64 /*
65 * Ignore the leading /
66 */
67 if (p != dir) {
68 *p = '\0';
69
70 /*
71 * Make the intermediary directory. POSIX
72 * says that these directories are created
73 * with umask,u+wx
74 */
75 if (make_one_dir(dir, subdir_mode) == -1)
76 return -1;
77
78 *p = '/';
79 }
80 s = p + 1;
81 }
82 }
83
84 /*
85 * Make the final target. Only complain if the
86 * target already exists if -p was not specified.
87 * This is created with the asked for mode & ~umask
88 */
89 ret = make_one_dir(dir, leaf_mode);
90 if (ret == -1)
91 return -1;
92
93 /*
94 * We might not set all the permission bits. Do that
95 * here (but only if we did create it.)
96 */
97 if (ret == 0 && chmod(dir, leaf_mode) == -1) {
98 int err_save = errno;
99
100 /*
101 * We failed, remove the directory we created
102 */
103 rmdir(dir);
104 errno = err_save;
105 fprintf(stderr, "%s: ", progname);
106 perror(dir);
107 return -1;
108 }
109 return 0;
110 }
111
112 int main(int argc, char *argv[])
113 {
114 int c, ret = 0;
115 mode_t saved_umask;
116
117 progname = argv[0];
118
119 saved_umask = umask(0);
120 leaf_mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~saved_umask;
121 subdir_mode = (saved_umask ^ (S_IRWXU | S_IRWXG | S_IRWXO))
122 | S_IWUSR | S_IXUSR;
123
124 do {
125 c = getopt(argc, argv, "pm:");
126 if (c == EOF)
127 break;
128 switch (c) {
129 case 'm':
130 leaf_mode =
131 parse_file_mode(optarg, leaf_mode, saved_umask);
132 break;
133 case 'p':
134 p_flag = 1;
135 break;
136
137 case '?':
138 fprintf(stderr, "%s: invalid option -%c\n",
139 progname, optopt);
140 usage();
141 }
142 } while (1);
143
144 if (optind == argc)
145 usage();
146
147 while (optind < argc) {
148 if (make_dir(argv[optind]))
149 ret = 255; /* seems to be what gnu mkdir does */
150 optind++;
151 }
152
153 return ret;
154 }