aboutsummaryrefslogtreecommitdiff
path: root/libbb/make_directory.c
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2003-03-19 09:13:01 +0000
committerManuel Novoa III <mjn3@codepoet.org>2003-03-19 09:13:01 +0000
commitcad5364599eb5062d59e0c397ed638ddd61a8d5d (patch)
treea318d0f03aa076c74b576ea45dc543a5669e8e91 /libbb/make_directory.c
parente01f9662a5bd5d91be4f6b3941b57fff73cd5af1 (diff)
downloadbusybox-w32-cad5364599eb5062d59e0c397ed638ddd61a8d5d.tar.gz
busybox-w32-cad5364599eb5062d59e0c397ed638ddd61a8d5d.tar.bz2
busybox-w32-cad5364599eb5062d59e0c397ed638ddd61a8d5d.zip
Major coreutils update.
Diffstat (limited to 'libbb/make_directory.c')
-rw-r--r--libbb/make_directory.c118
1 files changed, 72 insertions, 46 deletions
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 65be397bf..e3d2c52b1 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -1,12 +1,8 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * Mini make_directory implementation for busybox 3 * parse_mode implementation for busybox
4 * 4 *
5 * Copyright (C) 2001 Matt Kraai. 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6 *
7 * Rewriten in 2002
8 * Copyright (C) 2002 Glenn McGrath
9 * Copyright (C) 2002 Vladimir N. Oleynik
10 * 6 *
11 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -24,57 +20,87 @@
24 * 20 *
25 */ 21 */
26 22
23/* Mar 5, 2003 Manuel Novoa III
24 *
25 * This is the main work function for the 'mkdir' applet. As such, it
26 * strives to be SUSv3 compliant in it's behaviour when recursively
27 * making missing parent dirs, and in it's mode setting of the final
28 * directory 'path'.
29 *
30 * To recursively build all missing intermediate directories, make
31 * sure that (flags & FILEUTILS_RECUR) is non-zero. Newly created
32 * intermediate directories will have at least u+wx perms.
33 *
34 * To set specific permisions on 'path', pass the appropriate 'mode'
35 * val. Otherwise, pass -1 to get default permisions.
36 */
37
27#include <errno.h> 38#include <errno.h>
28#include <fcntl.h>
29#include <string.h>
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <unistd.h> 39#include <unistd.h>
33#include <stdlib.h>
34
35#include "libbb.h" 40#include "libbb.h"
36 41
37/* Create the directory PATH with mode MODE, or the default if MODE is -1. 42int bb_make_directory (char *path, long mode, int flags)
38 * Also create parent directories as necessary if flags contains
39 * FILEUTILS_RECUR. */
40
41int make_directory (char *path, long mode, int flags)
42{ 43{
43 int ret; 44 mode_t mask;
44 45 const char *fail_msg;
45 if (flags == FILEUTILS_RECUR) { 46 char *s = path;
46 char *pp = strrchr(path, '/'); 47 char c;
47 if ((pp) && (pp != path)) {
48 *pp = '\0';
49 make_directory(path, -1, flags);
50 *pp = '/';
51 }
52 }
53 48
54 if (mode == -1) { 49 mask = umask(0);
55 struct stat statbuf; 50 umask(mask & ~0300);
56 char *pp = strrchr(path, '/');
57 51
58 statbuf.st_mode = 0777; 52 do {
53 c = 0;
59 54
60 /* stat the directory */ 55 if (flags & FILEUTILS_RECUR) { /* Get the parent. */
61 if ((pp) && (pp != path)) { 56 /* Bypass leading non-'/'s and then subsequent '/'s. */
62 *pp = '\0'; 57 while (*s) {
63 stat(path, &statbuf); 58 if (*s == '/') {
64 *pp = '/'; 59 do {
60 ++s;
61 } while (*s == '/');
62 c = *s; /* Save the current char */
63 *s = 0; /* and replace it with nul. */
64 break;
65 }
66 ++s;
67 }
65 } 68 }
66 69
67 mode = statbuf.st_mode; 70 if (mkdir(path, 0777) < 0) {
68 } 71 /* If we failed for any other reason than the directory
72 * already exists, output a diagnostic and return -1.*/
73 if (errno != EEXIST) {
74 fail_msg = "create";
75 umask(mask);
76 break;
77 }
78 /* Since the directory exists, don't attempt to change
79 * permissions if it was the full target. Note that
80 * this is not an error conditon. */
81 if (!c) {
82 umask(mask);
83 return 0;
84 }
85 }
69 86
70 ret = mkdir(path, mode); 87 if (!c) {
71 if (ret == -1) { 88 /* Done. If necessary, updated perms on the newly
72 if ((flags == FILEUTILS_RECUR) && (errno == EEXIST)) { 89 * created directory. Failure to update here _is_
73 ret = 0; 90 * an error.*/
74 } else { 91 umask(mask);
75 perror_msg_and_die("Cannot create directory '%s'", path); 92 if ((mode != -1) && (chmod(path, mode) < 0)){
93 fail_msg = "set permissions of";
94 break;
95 }
96 return 0;
76 } 97 }
77 }
78 98
79 return(ret); 99 /* Remove any inserted nul from the path (recursive mode). */
100 *s = c;
101
102 } while (1);
103
104 bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);
105 return -1;
80} 106}