Erik Andersen | e49d5ec | 2000-02-08 19:58:47 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
Eric Andersen | f6be944 | 1999-10-13 21:12:06 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Mini mkdir implementation for busybox |
| 4 | * |
Matt Kraai | ceeff73 | 2001-06-21 19:41:37 +0000 | [diff] [blame] | 5 | * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> |
Eric Andersen | f6be944 | 1999-10-13 21:12:06 +0000 | [diff] [blame] | 6 | * |
Denys Vlasenko | 0ef64bd | 2010-08-16 20:14:46 +0200 | [diff] [blame] | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
Eric Andersen | f6be944 | 1999-10-13 21:12:06 +0000 | [diff] [blame] | 8 | */ |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 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 | */ |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 14 | /* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support. |
| 15 | */ |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 16 | //config:config MKDIR |
Denys Vlasenko | 4eed2c6 | 2017-07-18 22:01:24 +0200 | [diff] [blame] | 17 | //config: bool "mkdir (4.4 kb)" |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 18 | //config: default y |
| 19 | //config: help |
Denys Vlasenko | 72089cf | 2017-07-21 09:50:55 +0200 | [diff] [blame] | 20 | //config: mkdir is used to create directories with the specified names. |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 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 |
Denys Vlasenko | af3f420 | 2016-11-23 14:46:56 +0100 | [diff] [blame] | 26 | |
| 27 | //applet:IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) |
| 28 | |
| 29 | //kbuild:lib-$(CONFIG_MKDIR) += mkdir.o |
| 30 | |
| 31 | /* BB_AUDIT SUSv3 compliant */ |
| 32 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */ |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 33 | |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 34 | //usage:#define mkdir_trivial_usage |
| 35 | //usage: "[OPTIONS] DIRECTORY..." |
| 36 | //usage:#define mkdir_full_usage "\n\n" |
| 37 | //usage: "Create DIRECTORY\n" |
Pere Orga | 3442538 | 2011-03-31 14:43:25 +0200 | [diff] [blame] | 38 | //usage: "\n -m MODE Mode" |
| 39 | //usage: "\n -p No error if exists; make parent directories as needed" |
| 40 | //usage: IF_SELINUX( |
| 41 | //usage: "\n -Z Set security context" |
| 42 | //usage: ) |
| 43 | //usage: |
| 44 | //usage:#define mkdir_example_usage |
| 45 | //usage: "$ mkdir /tmp/foo\n" |
| 46 | //usage: "$ mkdir /tmp/foo\n" |
| 47 | //usage: "/tmp/foo: File exists\n" |
| 48 | //usage: "$ mkdir /tmp/foo/bar/baz\n" |
| 49 | //usage: "/tmp/foo/bar/baz: No such file or directory\n" |
| 50 | //usage: "$ mkdir -p /tmp/foo/bar/baz\n" |
| 51 | |
Denis Vlasenko | b6adbf1 | 2007-05-26 19:00:18 +0000 | [diff] [blame] | 52 | #include "libbb.h" |
Erik Andersen | fac10d7 | 2000-02-07 05:29:42 +0000 | [diff] [blame] | 53 | |
Denis Vlasenko | 99912ca | 2007-04-10 15:43:37 +0000 | [diff] [blame] | 54 | /* This is a NOFORK applet. Be very careful! */ |
| 55 | |
Bernhard Reutner-Fischer | 01d23ad | 2006-05-26 20:19:22 +0000 | [diff] [blame] | 56 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 57 | static const char mkdir_longopts[] ALIGN1 = |
Denis Vlasenko | bdc88fd | 2007-07-23 17:14:14 +0000 | [diff] [blame] | 58 | "mode\0" Required_argument "m" |
| 59 | "parents\0" No_argument "p" |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 60 | #if ENABLE_SELINUX |
Denis Vlasenko | bdc88fd | 2007-07-23 17:14:14 +0000 | [diff] [blame] | 61 | "context\0" Required_argument "Z" |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 62 | #endif |
Denys Vlasenko | 17f8418 | 2014-05-19 16:23:50 +0200 | [diff] [blame] | 63 | #if ENABLE_FEATURE_VERBOSE |
Simon B | 3698ed1 | 2012-05-06 15:03:32 +0200 | [diff] [blame] | 64 | "verbose\0" No_argument "v" |
Denys Vlasenko | 17f8418 | 2014-05-19 16:23:50 +0200 | [diff] [blame] | 65 | #endif |
Denis Vlasenko | 990d0f6 | 2007-07-24 15:54:42 +0000 | [diff] [blame] | 66 | ; |
Bernhard Reutner-Fischer | 01d23ad | 2006-05-26 20:19:22 +0000 | [diff] [blame] | 67 | #endif |
Eric Andersen | 8876fb2 | 2003-06-20 09:01:58 +0000 | [diff] [blame] | 68 | |
Denis Vlasenko | 9b49a5e | 2007-10-11 10:05:36 +0000 | [diff] [blame] | 69 | int mkdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
Denys Vlasenko | e992bae | 2009-11-28 15:18:53 +0100 | [diff] [blame] | 70 | int mkdir_main(int argc UNUSED_PARAM, char **argv) |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 71 | { |
Timo Teras | af36ba2 | 2012-02-10 09:55:24 +0200 | [diff] [blame] | 72 | long mode = -1; |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 73 | int status = EXIT_SUCCESS; |
Matt Kraai | ceeff73 | 2001-06-21 19:41:37 +0000 | [diff] [blame] | 74 | int flags = 0; |
Denis Vlasenko | 67b23e6 | 2006-10-03 21:00:06 +0000 | [diff] [blame] | 75 | unsigned opt; |
Eric Andersen | 8876fb2 | 2003-06-20 09:01:58 +0000 | [diff] [blame] | 76 | char *smode; |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 77 | #if ENABLE_SELINUX |
| 78 | security_context_t scontext; |
| 79 | #endif |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 80 | |
Bernhard Reutner-Fischer | 01d23ad | 2006-05-26 20:19:22 +0000 | [diff] [blame] | 81 | #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS |
Denis Vlasenko | bdc88fd | 2007-07-23 17:14:14 +0000 | [diff] [blame] | 82 | applet_long_options = mkdir_longopts; |
Bernhard Reutner-Fischer | 01d23ad | 2006-05-26 20:19:22 +0000 | [diff] [blame] | 83 | #endif |
Denys Vlasenko | 17f8418 | 2014-05-19 16:23:50 +0200 | [diff] [blame] | 84 | opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); |
Denis Vlasenko | 22dcd04 | 2006-11-19 13:53:50 +0000 | [diff] [blame] | 85 | if (opt & 1) { |
Denys Vlasenko | 5711a2a | 2015-10-07 17:55:33 +0200 | [diff] [blame] | 86 | mode_t mmode = bb_parse_mode(smode, 0777); |
| 87 | if (mmode == (mode_t)-1) { |
Denis Vlasenko | 22dcd04 | 2006-11-19 13:53:50 +0000 | [diff] [blame] | 88 | bb_error_msg_and_die("invalid mode '%s'", smode); |
Eric Andersen | fa0540f | 1999-10-22 18:18:31 +0000 | [diff] [blame] | 89 | } |
Timo Teras | af36ba2 | 2012-02-10 09:55:24 +0200 | [diff] [blame] | 90 | mode = mmode; |
Eric Andersen | fa0540f | 1999-10-22 18:18:31 +0000 | [diff] [blame] | 91 | } |
Denis Vlasenko | 22dcd04 | 2006-11-19 13:53:50 +0000 | [diff] [blame] | 92 | if (opt & 2) |
Eric Andersen | 8876fb2 | 2003-06-20 09:01:58 +0000 | [diff] [blame] | 93 | flags |= FILEUTILS_RECUR; |
Denys Vlasenko | 17f8418 | 2014-05-19 16:23:50 +0200 | [diff] [blame] | 94 | if ((opt & 4) && FILEUTILS_VERBOSE) |
| 95 | flags |= FILEUTILS_VERBOSE; |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 96 | #if ENABLE_SELINUX |
Denys Vlasenko | 17f8418 | 2014-05-19 16:23:50 +0200 | [diff] [blame] | 97 | if (opt & 8) { |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 98 | selinux_or_die(); |
Denis Vlasenko | 39c651e | 2007-03-12 18:22:55 +0000 | [diff] [blame] | 99 | setfscreatecon_or_die(scontext); |
Denis Vlasenko | 49622d7 | 2007-03-10 16:58:49 +0000 | [diff] [blame] | 100 | } |
| 101 | #endif |
Eric Andersen | f6be944 | 1999-10-13 21:12:06 +0000 | [diff] [blame] | 102 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 103 | argv += optind; |
Denys Vlasenko | e992bae | 2009-11-28 15:18:53 +0100 | [diff] [blame] | 104 | if (!argv[0]) |
| 105 | bb_show_usage(); |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 106 | |
| 107 | do { |
| 108 | if (bb_make_directory(*argv, mode, flags)) { |
| 109 | status = EXIT_FAILURE; |
| 110 | } |
| 111 | } while (*++argv); |
| 112 | |
| 113 | return status; |
Eric Andersen | cc8ed39 | 1999-10-05 16:24:54 +0000 | [diff] [blame] | 114 | } |