passwd: rework:
[oweals/busybox.git] / libbb / make_directory.c
index 710537dd1a47934c15910919870407dc9a30d5f6..fbec4e20e3081816ac2708705ec0a5c5b62201e6 100644 (file)
@@ -4,20 +4,7 @@
  *
  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
 /* Mar 5, 2003    Manuel Novoa III
@@ -37,6 +24,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include "libbb.h"
 
 int bb_make_directory (char *path, long mode, int flags)
@@ -45,9 +33,17 @@ int bb_make_directory (char *path, long mode, int flags)
        const char *fail_msg;
        char *s = path;
        char c;
+       struct stat st;
 
        mask = umask(0);
-       umask(mask & ~0300);
+       if (mode == -1) {
+               umask(mask);
+               mode = (S_IXUSR | S_IXGRP | S_IXOTH |
+                               S_IWUSR | S_IWGRP | S_IWOTH |
+                               S_IRUSR | S_IRGRP | S_IROTH) & ~mask;
+       } else {
+               umask(mask & ~0300);
+       }
 
        do {
                c = 0;
@@ -70,7 +66,9 @@ int bb_make_directory (char *path, long mode, int flags)
                if (mkdir(path, 0777) < 0) {
                        /* If we failed for any other reason than the directory
                         * already exists, output a diagnostic and return -1.*/
-                       if (errno != EEXIST) {
+                       if (errno != EEXIST
+                               || !(flags & FILEUTILS_RECUR)
+                               || (stat(path, &st) < 0 || !S_ISDIR(st.st_mode))) {
                                fail_msg = "create";
                                umask(mask);
                                break;
@@ -101,6 +99,6 @@ int bb_make_directory (char *path, long mode, int flags)
 
        } while (1);
 
-       bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);
+       bb_perror_msg ("cannot %s directory '%s'", fail_msg, path);
        return -1;
 }