Major coreutils update.
This commit is contained in:
@@ -1,12 +1,8 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Mini make_directory implementation for busybox
|
||||
* parse_mode implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2001 Matt Kraai.
|
||||
*
|
||||
* Rewriten in 2002
|
||||
* Copyright (C) 2002 Glenn McGrath
|
||||
* Copyright (C) 2002 Vladimir N. Oleynik
|
||||
* 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
|
||||
@@ -24,57 +20,87 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
/* Mar 5, 2003 Manuel Novoa III
|
||||
*
|
||||
* This is the main work function for the 'mkdir' applet. As such, it
|
||||
* strives to be SUSv3 compliant in it's behaviour when recursively
|
||||
* making missing parent dirs, and in it's mode setting of the final
|
||||
* directory 'path'.
|
||||
*
|
||||
* To recursively build all missing intermediate directories, make
|
||||
* sure that (flags & FILEUTILS_RECUR) is non-zero. Newly created
|
||||
* intermediate directories will have at least u+wx perms.
|
||||
*
|
||||
* To set specific permisions on 'path', pass the appropriate 'mode'
|
||||
* val. Otherwise, pass -1 to get default permisions.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "libbb.h"
|
||||
|
||||
/* Create the directory PATH with mode MODE, or the default if MODE is -1.
|
||||
* Also create parent directories as necessary if flags contains
|
||||
* FILEUTILS_RECUR. */
|
||||
|
||||
int make_directory (char *path, long mode, int flags)
|
||||
int bb_make_directory (char *path, long mode, int flags)
|
||||
{
|
||||
int ret;
|
||||
mode_t mask;
|
||||
const char *fail_msg;
|
||||
char *s = path;
|
||||
char c;
|
||||
|
||||
if (flags == FILEUTILS_RECUR) {
|
||||
char *pp = strrchr(path, '/');
|
||||
if ((pp) && (pp != path)) {
|
||||
*pp = '\0';
|
||||
make_directory(path, -1, flags);
|
||||
*pp = '/';
|
||||
}
|
||||
}
|
||||
mask = umask(0);
|
||||
umask(mask & ~0300);
|
||||
|
||||
if (mode == -1) {
|
||||
struct stat statbuf;
|
||||
char *pp = strrchr(path, '/');
|
||||
do {
|
||||
c = 0;
|
||||
|
||||
statbuf.st_mode = 0777;
|
||||
|
||||
/* stat the directory */
|
||||
if ((pp) && (pp != path)) {
|
||||
*pp = '\0';
|
||||
stat(path, &statbuf);
|
||||
*pp = '/';
|
||||
if (flags & FILEUTILS_RECUR) { /* Get the parent. */
|
||||
/* Bypass leading non-'/'s and then subsequent '/'s. */
|
||||
while (*s) {
|
||||
if (*s == '/') {
|
||||
do {
|
||||
++s;
|
||||
} while (*s == '/');
|
||||
c = *s; /* Save the current char */
|
||||
*s = 0; /* and replace it with nul. */
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
mode = statbuf.st_mode;
|
||||
}
|
||||
|
||||
ret = mkdir(path, mode);
|
||||
if (ret == -1) {
|
||||
if ((flags == FILEUTILS_RECUR) && (errno == EEXIST)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
perror_msg_and_die("Cannot create directory '%s'", path);
|
||||
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) {
|
||||
fail_msg = "create";
|
||||
umask(mask);
|
||||
break;
|
||||
}
|
||||
/* Since the directory exists, don't attempt to change
|
||||
* permissions if it was the full target. Note that
|
||||
* this is not an error conditon. */
|
||||
if (!c) {
|
||||
umask(mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
if (!c) {
|
||||
/* Done. If necessary, updated perms on the newly
|
||||
* created directory. Failure to update here _is_
|
||||
* an error.*/
|
||||
umask(mask);
|
||||
if ((mode != -1) && (chmod(path, mode) < 0)){
|
||||
fail_msg = "set permissions of";
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any inserted nul from the path (recursive mode). */
|
||||
*s = c;
|
||||
|
||||
} while (1);
|
||||
|
||||
bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user