misc/mkdirp.c

Go to the documentation of this file.
00001 // Copyright (C) 2006-2007 Benedikt Böhm <hollow@gentoo.org>
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00016 
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <sys/stat.h>
00020 
00021 #include "misc.h"
00022 #include "open.h"
00023 #include "str.h"
00024 #include "strtok.h"
00025 
00026 int mkdirp(const char *path, mode_t mode)
00027 {
00028         int ok = 1;
00029         struct stat sb;
00030 
00031         if (str_isempty(path) || str_path_isdot(path))
00032                 return errno = EINVAL, -1;
00033 
00034         strtok_t _st, *st = &_st, *p;
00035 
00036         int curdir = open_read(".");
00037 
00038         if (curdir == -1)
00039                 return -1;
00040 
00041         if (!strtok_init_str(st, path, "/", 0))
00042                 return -1;
00043 
00044         strtok_for_each(st, p) {
00045                 if (mkdir(p->token, 0755) == -1) {
00046                         if (errno != EEXIST || stat(p->token, &sb) == -1) {
00047                                 ok = 0;
00048                                 break;
00049                         }
00050 
00051                         if (!S_ISDIR(sb.st_mode)) {
00052                                 errno = ENOTDIR;
00053                                 ok = 0;
00054                                 break;
00055                         }
00056                 }
00057 
00058                 if (chdir(p->token) == -1) {
00059                         ok = 0;
00060                         break;
00061                 }
00062         }
00063 
00064         if (ok && chmod(".", mode) == -1)
00065                 ok = 0;
00066 
00067         fchdir(curdir);
00068         close(curdir);
00069 
00070         strtok_free(st);
00071         return ok ? 0 : -1;
00072 }

Generated on Tue Jun 19 20:38:26 2007 for lucid by  doxygen 1.5.2