+#include "save-cwd.h"
+#include "error.h"
+
+void strip_trailing_slashes ();
+
+#define CLEANUP_CWD \
+ do \
+ { \
+ /* We're done operating on basename_dir. \
+ Restore working directory. */ \
+ if (do_chdir) \
+ { \
+ int _fail = restore_cwd (&cwd, NULL, NULL); \
+ free_cwd (&cwd); \
+ if (_fail) \
+ return 1; \
+ } \
+ } \
+ while (0)
+
+#define CLEANUP \
+ do \
+ { \
+ umask (oldmask); \
+ CLEANUP_CWD; \
+ } \
+ while (0)
+
+/* Attempt to create directory DIR (aka DIRPATH) with the specified MODE.
+ If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P to non-zero if this
+ 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. */
+
+static int
+make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
+{
+ int fail = 0;
+ int created_dir;
+
+ created_dir = (mkdir (dir, mode) == 0);
+
+ if (!created_dir)
+ {
+ struct stat stats;
+ int saved_errno = errno;
+
+ /* The mkdir and stat calls below may appear to be reversed.
+ They are not. It is important to call mkdir first and then to
+ call stat (to distinguish the three cases) only if mkdir fails.
+ The alternative to this approach is to `stat' each directory,
+ then to call mkdir if it doesn't exist. But if some other process
+ were to create the directory between the stat & mkdir, the mkdir
+ would fail with EEXIST. */
+
+ if (stat (dir, &stats))
+ {
+ error (0, saved_errno, _("cannot create directory `%s'"), dirpath);
+ fail = 1;
+ }
+ else if (!S_ISDIR (stats.st_mode))
+ {
+ error (0, 0, _("`%s' exists but is not a directory"), dirpath);
+ fail = 1;
+ }
+ else
+ {
+ /* DIR (aka DIRPATH) already exists and is a directory. */
+ }
+ }
+
+ if (created_dir_p)
+ *created_dir_p = created_dir;
+
+ return fail;
+}