/* $Id$ */ /*- * Copyright (c) 2003-2006 Benedikt Meurer * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include /** * xfce_mkdirhier: * @whole_path : path to the directory to create. * @omode : file permissions to use for the newly created directories. * @error : location where to store GError object to, error are returned * in the %G_FILE_ERROR domain. * * Creates the specified directory @whole_path, but unlike the mkdir() * function from the standard C library, if any of the parent directories * of the @whole_path do not exists, they are created as well. * * If the directory specified by @whole_path already exists, this function * performs no operation and simply returns %TRUE. * * Return value: %TRUE on success, else %FALSE. * * Since: 4.2 **/ gboolean xfce_mkdirhier (const gchar *whole_path, gulong omode, GError **error) { /* Stolen from FreeBSD's mkdir(1) with modifications to make it * work properly with NFS on Solaris */ char path[1024]; struct stat sb; mode_t numask, oumask; int first, last, sverrno; gboolean retval; char *p; g_return_val_if_fail (whole_path != NULL, FALSE); g_strlcpy (path, whole_path, sizeof (path)); p = path; oumask = 0; retval = TRUE; if (p[0] == '/') /* Skip leading '/'. */ ++p; for (first = 1, last = 0; !last ; ++p) { if (p[0] == '\0') last = 1; else if (p[0] != '/') continue; else if (p[1] == '\0') last = 1; *p = '\0'; if (first) { /* * POSIX 1003.2: * For each dir operand that does not name an existing * directory, effects equivalent to those cased by the * following command shall occcur: * * mkdir -p -m $(umask -S),u+wx $(dirname dir) && * mkdir [-m mode] dir * * We change the user's umask and then restore it, * instead of doing chmod's. */ oumask = umask(0); numask = oumask & ~(S_IWUSR | S_IXUSR); umask(numask); first = 0; } if (last) umask(oumask); if (mkdir (path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) { sverrno = errno; if (stat (path, &sb) < 0) { errno = sverrno; retval = FALSE; break; } else if (!S_ISDIR (sb.st_mode)) { errno = ENOTDIR; retval = FALSE; break; } } if (!last) *p = '/'; } if (!first && !last) umask (oumask); if (!retval && error != NULL) { /* be sure to initialize the i18n support */ _xfce_i18n_init (); g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("Error creating directory '%s': %s"), whole_path, g_strerror (errno)); } return retval; } #define __XFCE_FILEUTILS_C__ #include