.
[gnulib.git] / lib / makepath.c
index 98b78a1..f0303fa 100644 (file)
 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
    Jim Meyering <meyering@cs.utexas.edu>.  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #ifdef __GNUC__
 #define alloca __builtin_alloca
 #else
@@ -38,20 +42,32 @@ char *alloca ();
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+
+#ifdef STAT_MACROS_BROKEN
+#undef S_ISDIR
+#endif /* STAT_MACROS_BROKEN.  */
+
 #if !defined(S_ISDIR) && defined(S_IFDIR)
-#define        S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
 #endif
 
 #ifdef STDC_HEADERS
-#include <errno.h>
 #include <stdlib.h>
-#else
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifndef STDC_HEADERS
 extern int errno;
 #endif
 
-#if defined(USG) || defined(STDC_HEADERS)
+#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
 #include <string.h>
+#ifndef index
 #define index strchr
+#endif
 #else
 #include <strings.h>
 #endif
@@ -61,6 +77,7 @@ typedef int uid_t;
 typedef int gid_t;
 #endif
 
+#include "safe-stat.h"
 void error ();
 
 /* Ensure that the directory ARGPATH exists.
@@ -93,10 +110,10 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
   int retval = 0;
   int oldmask = umask (0);
 
-  dirpath = alloca (strlen (argpath) + 1);
+  dirpath = (char *) alloca (strlen (argpath) + 1);
   strcpy (dirpath, argpath);
 
-  if (stat (dirpath, &stats))
+  if (SAFE_STAT (dirpath, &stats))
     {
       char *slash;
       int tmp_mode;            /* Initial perms for leading dirs.  */
@@ -130,7 +147,7 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
       while ((slash = index (slash, '/')))
        {
          *slash = '\0';
-         if (stat (dirpath, &stats))
+         if (SAFE_STAT (dirpath, &stats))
            {
              if (mkdir (dirpath, tmp_mode))
                {
@@ -145,7 +162,7 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
 
                  if (owner != (uid_t) -1 && group != (gid_t) -1
                      && chown (dirpath, owner, group)
-#ifdef AFS
+#if defined(AFS) && defined (EPERM)
                      && errno != EPERM
 #endif
                      )
@@ -181,7 +198,10 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
       /* We're done making leading directories.
         Make the final component of the path.  */
 
-      if (mkdir (dirpath, mode))
+      /* The path could end in "/." or contain "/..", so test
+        if we really have to create the directory.  */
+
+      if (SAFE_STAT (dirpath, &stats) && mkdir (dirpath, mode))
        {
          error (0, errno, "cannot make directory `%s'", dirpath);
          umask (oldmask);