.
[gnulib.git] / lib / makepath.c
index ea1b407..d4eaade 100644 (file)
@@ -1,5 +1,5 @@
 /* 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 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
@@ -46,7 +46,7 @@ char *alloca ();
 # 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
 
@@ -103,26 +103,13 @@ extern int errno;
 /* 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                                                   \
@@ -152,10 +139,10 @@ void strip_trailing_slashes ();
    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;
@@ -178,12 +165,13 @@ make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
 
       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
@@ -199,7 +187,6 @@ make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p)
 }
 
 /* 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.
@@ -312,16 +299,17 @@ make_path (const char *argpath,
          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;
                }
@@ -342,7 +330,8 @@ make_path (const char *argpath,
             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;
            }
@@ -358,6 +347,9 @@ make_path (const char *argpath,
       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.  */
 
@@ -367,11 +359,8 @@ make_path (const char *argpath,
          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)
        {
@@ -381,7 +370,8 @@ make_path (const char *argpath,
 #endif
              )
            {
-             error (0, errno, _("cannot chown %s"), dirpath);
+             error (0, errno, _("cannot change owner and/or group of %s"),
+                    quote (dirpath));
              retval = 1;
            }
        }
@@ -389,11 +379,13 @@ make_path (const char *argpath,
       /* 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;
        }
 
@@ -407,7 +399,8 @@ make_path (const char *argpath,
          *(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;
            }
        }
@@ -420,7 +413,7 @@ make_path (const char *argpath,
 
       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;
        }
 
@@ -439,12 +432,14 @@ make_path (const char *argpath,
 #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;
            }
        }