X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fmakepath.c;h=661f58b0fdba73b9fd6b5b7f8ab24d219627824f;hb=ad77a609ccd84b0650cbdc0cda015456c28ce5d7;hp=4d647b5ef3160a5bcdd1cf8c80bdd7b51a1b3f34;hpb=84c6de080c36ad607cb2b4759ae36ce04b10831c;p=gnulib.git diff --git a/lib/makepath.c b/lib/makepath.c index 4d647b5ef..661f58b0f 100644 --- a/lib/makepath.c +++ b/lib/makepath.c @@ -19,14 +19,7 @@ Jim Meyering . */ #ifdef HAVE_CONFIG_H -#if defined (CONFIG_BROKETS) -/* We use instead of "config.h" so that a compilation - using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h - (which it would do because it found this file in $srcdir). */ #include -#else -#include "config.h" -#endif #endif #ifdef __GNUC__ @@ -50,11 +43,9 @@ char *alloca (); #include #endif -#ifdef STAT_MACROS_BROKEN -#ifdef S_ISDIR +#ifdef STAT_MACROS_BROKEN #undef S_ISDIR -#endif -#endif /* STAT_MACROS_BROKEN. */ +#endif /* STAT_MACROS_BROKEN. */ #if !defined(S_ISDIR) && defined(S_IFDIR) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) @@ -68,17 +59,17 @@ char *alloca (); #include #endif -#ifndef STDC_HEADERS +#ifndef errno extern int errno; #endif -#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) -#include -#ifndef index -#define index strchr -#endif +#ifdef HAVE_STRING_H +# include #else -#include +# include +# ifndef strchr +# define strchr index +# endif #endif #ifdef __MSDOS__ @@ -86,38 +77,57 @@ typedef int uid_t; typedef int gid_t; #endif +#include "makepath.h" + void error (); /* Ensure that the directory ARGPATH exists. Remove any trailing slashes from ARGPATH before calling this function. - Make any leading directories that don't already exist, with + Create any leading directories that don't already exist, with permissions PARENT_MODE. If the last element of ARGPATH does not exist, create it as a new directory with permissions MODE. - If OWNER and GROUP are non-negative, make them the UID and GID of - created directories. + If OWNER and GROUP are non-negative, use them to set the UID and GID of + any created directories. If VERBOSE_FMT_STRING is nonzero, use it as a printf format string for printing a message after successfully making a directory, with the name of the directory that was just made as an argument. + If PRESERVE_EXISTING is non-zero and ARGPATH is an existing directory, + then do not attempt to set its permissions and ownership. Return 0 if ARGPATH exists as a directory with the proper ownership and permissions when done, otherwise 1. */ +#if __STDC__ +int +make_path (const char *argpath, + int mode, + int parent_mode, + uid_t owner, + gid_t group, + int preserve_existing, + const char *verbose_fmt_string) +#else int -make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string) - char *argpath; +make_path (argpath, mode, parent_mode, owner, group, preserve_existing, + verbose_fmt_string) + const char *argpath; int mode; int parent_mode; uid_t owner; gid_t group; - char *verbose_fmt_string; + int preserve_existing; + const char *verbose_fmt_string; +#endif { char *dirpath; /* A copy we can scribble NULs on. */ struct stat stats; int retval = 0; int oldmask = umask (0); + /* FIXME: move this alloca and strcpy into the if-block. + Set dirpath to argpath in the else-block. */ dirpath = (char *) alloca (strlen (argpath) + 1); strcpy (dirpath, argpath); @@ -152,14 +162,14 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string) slash = dirpath; while (*slash == '/') slash++; - while ((slash = index (slash, '/'))) + while ((slash = strchr (slash, '/'))) { *slash = '\0'; if (stat (dirpath, &stats)) { if (mkdir (dirpath, tmp_mode)) { - error (0, errno, "cannot make directory `%s'", dirpath); + error (0, errno, "cannot create directory `%s'", dirpath); umask (oldmask); return 1; } @@ -204,14 +214,14 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string) } /* We're done making leading directories. - Make the final component of the path. */ + Create the final component of the path. */ /* The path could end in "/." or contain "/..", so test if we really have to create the directory. */ if (stat (dirpath, &stats) && mkdir (dirpath, mode)) { - error (0, errno, "cannot make directory `%s'", dirpath); + error (0, errno, "cannot create directory `%s'", dirpath); umask (oldmask); return 1; } @@ -261,26 +271,29 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string) return 1; } - /* chown must precede chmod because on some systems, - chown clears the set[ug]id bits for non-superusers, - resulting in incorrect permissions. - On System V, users can give away files with chown and then not - be able to chmod them. So don't give files away. */ - - if (owner != (uid_t) -1 && group != (gid_t) -1 - && chown (dirpath, owner, group) + if (!preserve_existing) + { + /* chown must precede chmod because on some systems, + chown clears the set[ug]id bits for non-superusers, + resulting in incorrect permissions. + On System V, users can give away files with chown and then not + be able to chmod them. So don't give files away. */ + + if (owner != (uid_t) -1 && group != (gid_t) -1 + && chown (dirpath, owner, group) #ifdef AFS - && errno != EPERM + && errno != EPERM #endif - ) - { - error (0, errno, "%s", dirpath); - retval = 1; - } - if (chmod (dirpath, mode)) - { - error (0, errno, "%s", dirpath); - retval = 1; + ) + { + error (0, errno, "%s", dirpath); + retval = 1; + } + if (chmod (dirpath, mode)) + { + error (0, errno, "%s", dirpath); + retval = 1; + } } }