From a086f904e1366ec32d8b756d0da5e4ea29c17212 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 4 Nov 1994 16:42:25 +0000 Subject: [PATCH] GNU file utilities --- lib/Makefile.in | 3 ++- lib/euidaccess.c | 12 +++++++++++ lib/filemode.c | 32 +++++++++++++++++++++------- lib/makepath.c | 64 ++++++++++++++++++++++++++++++++------------------------ lib/makepath.h | 16 ++++++++++++++ 5 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 lib/makepath.h diff --git a/lib/Makefile.in b/lib/Makefile.in index 3ba1f8927..cdbad3f2b 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -48,7 +48,7 @@ stripslash.o xgetcwd.o xmalloc.o xstrdup.o userspec.o yesno.o \ @LIBOBJS@ @ALLOCA@ DISTFILES = Makefile.in backupfile.h getopt.h long-options.h modechange.h \ -fnmatch.h fsusage.h mountlist.h obstack.h pathmax.h \ +fnmatch.h fsusage.h makepath.h mountlist.h obstack.h pathmax.h \ safe-xstat.cin safe-xstat.hin getdate.c posixtm.c $(SOURCES) all: libfu.a @@ -152,6 +152,7 @@ modechange.o: modechange.h mountlist.o: mountlist.h xgetcwd.o: pathmax.h euidaccess.o fsusage.o isdir.o makepath.o mkdir.o rename.o: safe-stat.h +makepath.o: makepath.h # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/lib/euidaccess.c b/lib/euidaccess.c index 1073c9741..00d6a9569 100644 --- a/lib/euidaccess.c +++ b/lib/euidaccess.c @@ -24,6 +24,18 @@ #include #include +#ifdef S_IEXEC +#ifndef S_IXUSR +#define S_IXUSR S_IEXEC +#endif +#ifndef S_IXGRP +#define S_IXGRP (S_IEXEC >> 3) +#endif +#ifndef S_IXOTH +#define S_IXOTH (S_IEXEC >> 6) +#endif +#endif /* S_IEXEC */ + #ifdef HAVE_UNISTD_H #include #endif diff --git a/lib/filemode.c b/lib/filemode.c index c86ee2ff5..478120bdf 100644 --- a/lib/filemode.c +++ b/lib/filemode.c @@ -22,10 +22,28 @@ #include #include -#ifndef S_IREAD -#define S_IREAD S_IRUSR -#define S_IWRITE S_IWUSR -#define S_IEXEC S_IXUSR +#if !S_IRUSR +# if S_IREAD +# define S_IRUSR S_IREAD +# else +# define S_IRUSR 00400 +#endif +#endif + +#if !S_IWUSR +# if S_IWRITE +# define S_IWUSR S_IWRITE +# else +# define S_IWUSR 00200 +# endif +#endif + +#if !S_IXUSR +# if S_IEXEC +# define S_IXUSR S_IEXEC +# else +# define S_IXUSR 00100 +# endif #endif #ifdef STAT_MACROS_BROKEN @@ -191,9 +209,9 @@ rwx (bits, chars) unsigned short bits; char *chars; { - chars[0] = (bits & S_IREAD) ? 'r' : '-'; - chars[1] = (bits & S_IWRITE) ? 'w' : '-'; - chars[2] = (bits & S_IEXEC) ? 'x' : '-'; + chars[0] = (bits & S_IRUSR) ? 'r' : '-'; + chars[1] = (bits & S_IWUSR) ? 'w' : '-'; + chars[2] = (bits & S_IXUSR) ? 'x' : '-'; } /* Set the 's' and 't' flags in file attributes string CHARS, diff --git a/lib/makepath.c b/lib/makepath.c index f0303fa8f..9066874cd 100644 --- a/lib/makepath.c +++ b/lib/makepath.c @@ -77,39 +77,46 @@ typedef int uid_t; typedef int gid_t; #endif +#include "makepath.h" #include "safe-stat.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. */ 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; { 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); @@ -151,7 +158,7 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string) { 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; } @@ -196,14 +203,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 (SAFE_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; } @@ -253,26 +260,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; + } } } diff --git a/lib/makepath.h b/lib/makepath.h new file mode 100644 index 000000000..f555d7b4b --- /dev/null +++ b/lib/makepath.h @@ -0,0 +1,16 @@ +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +int + make_path __P ((const char *_argpath, + int _mode, + int _parent_mode, + uid_t _owner, + gid_t _group, + int _preserve_existing, + const char *_verbose_fmt_string)); -- 2.11.0