blob: 3afe76c28bf6953fc6fb086ef97a01e05ee85a4d
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Mini mkdir implementation for busybox |
4 | * |
5 | * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | */ |
9 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
10 | * |
11 | * Fixed broken permission setting when -p was used; especially in |
12 | * conjunction with -m. |
13 | */ |
14 | /* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support. |
15 | */ |
16 | //config:config MKDIR |
17 | //config: bool "mkdir" |
18 | //config: default y |
19 | //config: help |
20 | //config: mkdir is used to create directories with the specified names. |
21 | //config: |
22 | //config:config FEATURE_MKDIR_LONG_OPTIONS |
23 | //config: bool "Enable long options" |
24 | //config: default y |
25 | //config: depends on MKDIR && LONG_OPTS |
26 | //config: help |
27 | //config: Support long options for the mkdir applet. |
28 | |
29 | //applet:IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) |
30 | |
31 | //kbuild:lib-$(CONFIG_MKDIR) += mkdir.o |
32 | |
33 | /* BB_AUDIT SUSv3 compliant */ |
34 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */ |
35 | |
36 | //usage:#define mkdir_trivial_usage |
37 | //usage: "[OPTIONS] DIRECTORY..." |
38 | //usage:#define mkdir_full_usage "\n\n" |
39 | //usage: "Create DIRECTORY\n" |
40 | //usage: "\n -m MODE Mode" |
41 | //usage: "\n -p No error if exists; make parent directories as needed" |
42 | //usage: IF_SELINUX( |
43 | //usage: "\n -Z Set security context" |
44 | //usage: ) |
45 | //usage: |
46 | //usage:#define mkdir_example_usage |
47 | //usage: "$ mkdir /tmp/foo\n" |
48 | //usage: "$ mkdir /tmp/foo\n" |
49 | //usage: "/tmp/foo: File exists\n" |
50 | //usage: "$ mkdir /tmp/foo/bar/baz\n" |
51 | //usage: "/tmp/foo/bar/baz: No such file or directory\n" |
52 | //usage: "$ mkdir -p /tmp/foo/bar/baz\n" |
53 | |
54 | #include "libbb.h" |
55 | |
56 | /* This is a NOFORK applet. Be very careful! */ |
57 | |
58 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS |
59 | static const char mkdir_longopts[] ALIGN1 = |
60 | "mode\0" Required_argument "m" |
61 | "parents\0" No_argument "p" |
62 | #if ENABLE_SELINUX |
63 | "context\0" Required_argument "Z" |
64 | #endif |
65 | #if ENABLE_FEATURE_VERBOSE |
66 | "verbose\0" No_argument "v" |
67 | #endif |
68 | ; |
69 | #endif |
70 | |
71 | int mkdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
72 | int mkdir_main(int argc UNUSED_PARAM, char **argv) |
73 | { |
74 | long mode = -1; |
75 | int status = EXIT_SUCCESS; |
76 | int flags = 0; |
77 | unsigned opt; |
78 | char *smode; |
79 | #if ENABLE_SELINUX |
80 | security_context_t scontext; |
81 | #endif |
82 | |
83 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS |
84 | applet_long_options = mkdir_longopts; |
85 | #endif |
86 | opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); |
87 | if (opt & 1) { |
88 | mode_t mmode = bb_parse_mode(smode, 0777); |
89 | if (mmode == (mode_t)-1) { |
90 | bb_error_msg_and_die("invalid mode '%s'", smode); |
91 | } |
92 | mode = mmode; |
93 | } |
94 | if (opt & 2) |
95 | flags |= FILEUTILS_RECUR; |
96 | if ((opt & 4) && FILEUTILS_VERBOSE) |
97 | flags |= FILEUTILS_VERBOSE; |
98 | #if ENABLE_SELINUX |
99 | if (opt & 8) { |
100 | selinux_or_die(); |
101 | setfscreatecon_or_die(scontext); |
102 | } |
103 | #endif |
104 | |
105 | argv += optind; |
106 | if (!argv[0]) |
107 | bb_show_usage(); |
108 | |
109 | do { |
110 | if (bb_make_directory(*argv, mode, flags)) { |
111 | status = EXIT_FAILURE; |
112 | } |
113 | } while (*++argv); |
114 | |
115 | return status; |
116 | } |
117 |