/* makepath.c -- Ensure that a directory path exists.
- Copyright (C) 1990, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Copyright (C) 1990, 1997, 1998, 1999, 2000, 2002, 2003 Free
+ Software Foundation, Inc.
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
# include <config.h>
#endif
-#if __GNUC__
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- # pragma alloca
-# else
-char *alloca ();
-# endif
-# endif
-#endif
+#include <alloca.h>
#include <stdio.h>
#include <sys/types.h>
# undef S_ISDIR
#endif
-#if !defined(S_ISDIR) && defined(S_IFDIR)
+#if !defined S_ISDIR && defined S_IFDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
# include <stdlib.h>
#endif
-#if HAVE_ERRNO_H
-# include <errno.h>
-#endif
+#include <errno.h>
#ifndef errno
extern int errno;
#define WX_USR (S_IWUSR | S_IXUSR)
-/* Include this before libintl.h so we get our definition of PARAMS. */
#include "makepath.h"
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#if ENABLE_NLS
-# include <libintl.h>
-# define _(Text) gettext (Text)
-#else
-# define _(Text) Text
-#endif
-
-#ifdef __MSDOS__
-typedef int uid_t;
-typedef int gid_t;
-#endif
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
#include "save-cwd.h"
+#include "dirname.h"
#include "error.h"
-
-void strip_trailing_slashes ();
+#include "quote.h"
#define CLEANUP_CWD \
do \
Restore working directory. */ \
if (do_chdir) \
{ \
- int _fail = restore_cwd (&cwd, NULL, NULL); \
+ if (restore_cwd (&cwd) != 0) \
+ { \
+ int _saved_errno = errno; \
+ error (0, errno, \
+ _("failed to return to initial working directory")); \
+ free_cwd (&cwd); \
+ errno = _saved_errno; \
+ return 1; \
+ } \
free_cwd (&cwd); \
- if (_fail) \
- return 1; \
} \
} \
while (0)
function creates DIR and to zero otherwise. Give a diagnostic and
return non-zero if DIR cannot be created or cannot be determined to
exist already. Use DIRPATH in any diagnostic, not DIR.
- Note that if DIR already exists, this function will return zero
- (indicating success) and will set *CREATED_DIR_P to zero. */
+ Note that if DIR already exists, this function returns zero
+ (indicating success) and sets *CREATED_DIR_P to zero. */
-static int
+int
make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
{
int fail = 0;
if (stat (dir, &stats))
{
- error (0, saved_errno, _("cannot create directory `%s'"), dirpath);
+ error (0, saved_errno, _("cannot create directory %s"),
+ quote (dirpath));
fail = 1;
}
else if (!S_ISDIR (stats.st_mode))
{
- error (0, 0, _("`%s' exists but is not a directory"), dirpath);
+ error (0, 0, _("%s exists but is not a directory"), quote (dirpath));
fail = 1;
}
else
}
/* Ensure that the directory ARGPATH exists.
- Remove any trailing slashes from ARGPATH before calling this function.
Create any leading directories that don't already exist, with
permissions PARENT_MODE.
if (newly_created_dir)
{
if (verbose_fmt_string)
- error (0, 0, verbose_fmt_string, dirpath);
+ error (0, 0, verbose_fmt_string, quote (dirpath));
if ((owner != (uid_t) -1 || group != (gid_t) -1)
&& chown (basename_dir, owner, group)
-#if defined(AFS) && defined (EPERM)
+#if defined AFS && defined EPERM
&& errno != EPERM
#endif
)
{
- error (0, errno, "%s", dirpath);
+ error (0, errno, _("cannot change owner and/or group of %s"),
+ quote (dirpath));
CLEANUP;
return 1;
}
stat and mkdir process O(n^2) file name components. */
if (do_chdir && chdir (basename_dir) < 0)
{
- error (0, errno, _("cannot chdir to directory, %s"), dirpath);
+ error (0, errno, _("cannot chdir to directory %s"),
+ quote (dirpath));
CLEANUP;
return 1;
}
if (!do_chdir)
basename_dir = dirpath;
+ /* Done creating leading directories. Restore original umask. */
+ umask (oldmask);
+
/* We're done making leading directories.
Create the final component of the path. */
return 1;
}
- /* Done creating directories. Restore original umask. */
- umask (oldmask);
-
if (verbose_fmt_string != NULL)
- error (0, 0, verbose_fmt_string, dirpath);
+ error (0, 0, verbose_fmt_string, quote (dirpath));
if (owner != (uid_t) -1 || group != (gid_t) -1)
{
#endif
)
{
- error (0, errno, _("cannot chown %s"), dirpath);
+ error (0, errno, _("cannot change owner and/or group of %s"),
+ quote (dirpath));
retval = 1;
}
}
/* The above chown may have turned off some permission bits in MODE.
Another reason we may have to use chmod here is that mkdir(2) is
required to honor only the file permission bits. In particular,
- it may not have honored the `special' bits. */
+ it need not honor the `special' bits, so if MODE includes any
+ special bits, set them here. */
if ((mode & ~S_IRWXUGO)
&& chmod (basename_dir, mode))
{
- error (0, errno, _("cannot chmod %s"), dirpath);
+ error (0, errno, _("cannot change permissions of %s"),
+ quote (dirpath));
retval = 1;
}
*(p->dirname_end) = '\0';
if (chmod (dirpath, parent_mode))
{
- error (0, errno, "%s", dirpath);
+ error (0, errno, _("cannot change permissions of %s"),
+ quote (dirpath));
retval = 1;
}
}
if (!S_ISDIR (stats.st_mode))
{
- error (0, 0, _("`%s' exists but is not a directory"), dirpath);
+ error (0, 0, _("%s exists but is not a directory"), quote (dirpath));
return 1;
}
#endif
)
{
- error (0, errno, "%s", dirpath);
+ error (0, errno, _("cannot change owner and/or group of %s"),
+ quote (dirpath));
retval = 1;
}
if (chmod (dirpath, mode))
{
- error (0, errno, "%s", dirpath);
+ error (0, errno, _("cannot change permissions of %s"),
+ quote (dirpath));
retval = 1;
}
}