blob: 65be397bffeb2be4ed41811c1cac2e95b59024cf [file] [log] [blame]
Matt Kraaiceeff732001-06-21 19:41:37 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini make_directory implementation for busybox
4 *
5 * Copyright (C) 2001 Matt Kraai.
Glenn L McGrathfbef2252002-08-23 17:19:26 +00006 *
7 * Rewriten in 2002
8 * Copyright (C) 2002 Glenn McGrath
9 * Copyright (C) 2002 Vladimir N. Oleynik
Matt Kraaiceeff732001-06-21 19:41:37 +000010 *
11 * 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
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <errno.h>
28#include <fcntl.h>
Glenn L McGrath210aa142002-08-24 20:00:52 +000029#include <string.h>
Matt Kraaiceeff732001-06-21 19:41:37 +000030#include <sys/stat.h>
31#include <sys/types.h>
32#include <unistd.h>
Eric Andersen764303f2001-06-22 03:07:19 +000033#include <stdlib.h>
Matt Kraaiceeff732001-06-21 19:41:37 +000034
35#include "libbb.h"
36
37/* Create the directory PATH with mode MODE, or the default if MODE is -1.
38 * Also create parent directories as necessary if flags contains
39 * FILEUTILS_RECUR. */
40
Eric Andersen879d6c82001-08-02 09:58:19 +000041int make_directory (char *path, long mode, int flags)
Matt Kraaiceeff732001-06-21 19:41:37 +000042{
Glenn L McGrathfbef2252002-08-23 17:19:26 +000043 int ret;
Glenn L McGrath822e7fd2002-11-24 22:48:20 +000044
Glenn L McGrathfbef2252002-08-23 17:19:26 +000045 if (flags == FILEUTILS_RECUR) {
46 char *pp = strrchr(path, '/');
Glenn L McGrath4298e872002-10-19 23:56:41 +000047 if ((pp) && (pp != path)) {
Glenn L McGrathfbef2252002-08-23 17:19:26 +000048 *pp = '\0';
Glenn L McGrath822e7fd2002-11-24 22:48:20 +000049 make_directory(path, -1, flags);
Glenn L McGrathfbef2252002-08-23 17:19:26 +000050 *pp = '/';
Matt Kraaiceeff732001-06-21 19:41:37 +000051 }
52 }
Glenn L McGrath822e7fd2002-11-24 22:48:20 +000053
54 if (mode == -1) {
Glenn L McGrath5b110872002-11-24 23:22:29 +000055 struct stat statbuf;
56 char *pp = strrchr(path, '/');
57
58 statbuf.st_mode = 0777;
59
60 /* stat the directory */
61 if ((pp) && (pp != path)) {
62 *pp = '\0';
63 stat(path, &statbuf);
64 *pp = '/';
65 }
66
67 mode = statbuf.st_mode;
Glenn L McGrath822e7fd2002-11-24 22:48:20 +000068 }
69
Glenn L McGrathfbef2252002-08-23 17:19:26 +000070 ret = mkdir(path, mode);
Glenn L McGrath193697d2002-08-24 20:11:38 +000071 if (ret == -1) {
Glenn L McGrathb3f72612002-09-22 02:12:30 +000072 if ((flags == FILEUTILS_RECUR) && (errno == EEXIST)) {
Glenn L McGrath193697d2002-08-24 20:11:38 +000073 ret = 0;
74 } else {
Glenn L McGrath891ee642002-09-28 08:30:47 +000075 perror_msg_and_die("Cannot create directory '%s'", path);
Glenn L McGrath193697d2002-08-24 20:11:38 +000076 }
Glenn L McGrathfbef2252002-08-23 17:19:26 +000077 }
Glenn L McGrath822e7fd2002-11-24 22:48:20 +000078
Glenn L McGrath193697d2002-08-24 20:11:38 +000079 return(ret);
Matt Kraaiceeff732001-06-21 19:41:37 +000080}