Contents of /trunk/mkinitrd-magellan/busybox/libbb/make_directory.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 2549 byte(s)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 2549 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 | /* 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 <errno.h> |
26 | #include <unistd.h> |
27 | #include <sys/stat.h> |
28 | #include "libbb.h" |
29 | |
30 | int bb_make_directory (char *path, long mode, int flags) |
31 | { |
32 | mode_t mask; |
33 | const char *fail_msg; |
34 | char *s = path; |
35 | char c; |
36 | struct stat st; |
37 | |
38 | mask = umask(0); |
39 | if (mode == -1) { |
40 | umask(mask); |
41 | mode = (S_IXUSR | S_IXGRP | S_IXOTH | |
42 | S_IWUSR | S_IWGRP | S_IWOTH | |
43 | S_IRUSR | S_IRGRP | S_IROTH) & ~mask; |
44 | } else { |
45 | umask(mask & ~0300); |
46 | } |
47 | |
48 | do { |
49 | c = 0; |
50 | |
51 | if (flags & FILEUTILS_RECUR) { /* Get the parent. */ |
52 | /* Bypass leading non-'/'s and then subsequent '/'s. */ |
53 | while (*s) { |
54 | if (*s == '/') { |
55 | do { |
56 | ++s; |
57 | } while (*s == '/'); |
58 | c = *s; /* Save the current char */ |
59 | *s = 0; /* and replace it with nul. */ |
60 | break; |
61 | } |
62 | ++s; |
63 | } |
64 | } |
65 | |
66 | if (mkdir(path, 0777) < 0) { |
67 | /* If we failed for any other reason than the directory |
68 | * already exists, output a diagnostic and return -1.*/ |
69 | if (errno != EEXIST |
70 | || !(flags & FILEUTILS_RECUR) |
71 | || (stat(path, &st) < 0 || !S_ISDIR(st.st_mode))) { |
72 | fail_msg = "create"; |
73 | umask(mask); |
74 | break; |
75 | } |
76 | /* Since the directory exists, don't attempt to change |
77 | * permissions if it was the full target. Note that |
78 | * this is not an error conditon. */ |
79 | if (!c) { |
80 | umask(mask); |
81 | return 0; |
82 | } |
83 | } |
84 | |
85 | if (!c) { |
86 | /* Done. If necessary, updated perms on the newly |
87 | * created directory. Failure to update here _is_ |
88 | * an error.*/ |
89 | umask(mask); |
90 | if ((mode != -1) && (chmod(path, mode) < 0)){ |
91 | fail_msg = "set permissions of"; |
92 | break; |
93 | } |
94 | return 0; |
95 | } |
96 | |
97 | /* Remove any inserted nul from the path (recursive mode). */ |
98 | *s = c; |
99 | |
100 | } while (1); |
101 | |
102 | bb_perror_msg ("cannot %s directory '%s'", fail_msg, path); |
103 | return -1; |
104 | } |