Magellan Linux

Annotation of /tags/mkinitrd-6_2_0/libbb/make_directory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (hide annotations) (download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/libbb/make_directory.c
File MIME type: text/plain
File size: 3311 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * parse_mode implementation for busybox
4     *
5     * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6     *
7     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8     */
9    
10     /* Mar 5, 2003 Manuel Novoa III
11     *
12     * This is the main work function for the 'mkdir' applet. As such, it
13     * strives to be SUSv3 compliant in it's behaviour when recursively
14     * making missing parent dirs, and in it's mode setting of the final
15     * directory 'path'.
16     *
17     * To recursively build all missing intermediate directories, make
18     * sure that (flags & FILEUTILS_RECUR) is non-zero. Newly created
19     * intermediate directories will have at least u+wx perms.
20     *
21     * To set specific permissions on 'path', pass the appropriate 'mode'
22     * val. Otherwise, pass -1 to get default permissions.
23     */
24    
25     #include "libbb.h"
26    
27 niro 816 /* This function is used from NOFORK applets. It must not allocate anything */
28    
29     int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
30 niro 532 {
31 niro 984 mode_t cur_mask;
32     mode_t org_mask;
33 niro 532 const char *fail_msg;
34 niro 984 char *s;
35 niro 532 char c;
36     struct stat st;
37    
38 niro 984 /* Happens on bb_make_directory(dirname("no_slashes"),...) */
39     if (LONE_CHAR(path, '.'))
40     return 0;
41 niro 532
42 niro 984 org_mask = cur_mask = (mode_t)-1L;
43     s = path;
44 niro 816 while (1) {
45     c = '\0';
46 niro 532
47 niro 984 if (flags & FILEUTILS_RECUR) { /* Get the parent */
48     /* Bypass leading non-'/'s and then subsequent '/'s */
49 niro 532 while (*s) {
50     if (*s == '/') {
51     do {
52     ++s;
53     } while (*s == '/');
54 niro 816 c = *s; /* Save the current char */
55 niro 984 *s = '\0'; /* and replace it with nul */
56 niro 532 break;
57     }
58     ++s;
59     }
60     }
61    
62 niro 984 if (c != '\0') {
63     /* Intermediate dirs: must have wx for user */
64     if (cur_mask == (mode_t)-1L) { /* wasn't done yet? */
65     mode_t new_mask;
66     org_mask = umask(0);
67     cur_mask = 0;
68     /* Clear u=wx in umask - this ensures
69     * they won't be cleared on mkdir */
70     new_mask = (org_mask & ~(mode_t)0300);
71     //bb_error_msg("org_mask:%o cur_mask:%o", org_mask, new_mask);
72     if (new_mask != cur_mask) {
73     cur_mask = new_mask;
74     umask(new_mask);
75     }
76     }
77     } else {
78     /* Last component: uses original umask */
79     //bb_error_msg("1 org_mask:%o", org_mask);
80     if (org_mask != cur_mask) {
81     cur_mask = org_mask;
82     umask(org_mask);
83     }
84     }
85 niro 816
86 niro 532 if (mkdir(path, 0777) < 0) {
87     /* If we failed for any other reason than the directory
88 niro 984 * already exists, output a diagnostic and return -1 */
89 niro 532 if (errno != EEXIST
90 niro 816 || !(flags & FILEUTILS_RECUR)
91     || ((stat(path, &st) < 0) || !S_ISDIR(st.st_mode))
92     ) {
93 niro 532 fail_msg = "create";
94     break;
95     }
96     /* Since the directory exists, don't attempt to change
97     * permissions if it was the full target. Note that
98 niro 816 * this is not an error condition. */
99 niro 532 if (!c) {
100 niro 984 goto ret0;
101 niro 532 }
102     }
103    
104     if (!c) {
105 niro 816 /* Done. If necessary, update perms on the newly
106 niro 532 * created directory. Failure to update here _is_
107 niro 816 * an error. */
108     if ((mode != -1) && (chmod(path, mode) < 0)) {
109 niro 532 fail_msg = "set permissions of";
110     break;
111     }
112 niro 984 goto ret0;
113 niro 532 }
114    
115 niro 984 /* Remove any inserted nul from the path (recursive mode) */
116 niro 532 *s = c;
117 niro 816 } /* while (1) */
118 niro 532
119 niro 984 bb_perror_msg("can't %s directory '%s'", fail_msg, path);
120     flags = -1;
121     goto ret;
122     ret0:
123     flags = 0;
124     ret:
125     //bb_error_msg("2 org_mask:%o", org_mask);
126     if (org_mask != cur_mask)
127     umask(org_mask);
128     return flags;
129 niro 532 }