From 4d22e13282b17a4acb902dcef99b9c39cc2d3ec9 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 16 Aug 1999 21:21:39 +0000 Subject: This change is nearly identical to the chown.c change of 1998-05-24 Accept new option, --dereference. --no-dereference is now the default. Include lchown.h. (enum Change_status) [CH_NOT_APPLIED]: New member. (change_symlinks): Enable this by default, now. (describe_change): Handle new case. (change_file_group): Add new parameter: cmdline_arg. Update callers. Reorganize to reflect changed semantics. (LCHOWN): Remove definitions. From Bruno Haible. --- src/chgrp.c | 62 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/chgrp.c b/src/chgrp.c index f74ab381e..7c31af158 100644 --- a/src/chgrp.c +++ b/src/chgrp.c @@ -25,6 +25,7 @@ #include "system.h" #include "error.h" +#include "lchown.h" #include "group-member.h" #include "savedir.h" #include "xstrtol.h" @@ -50,14 +51,9 @@ struct group *getgrnam (); # define endgrent() ((void) 0) #endif -#if HAVE_LCHOWN -# define LCHOWN(FILE, OWNER, GROUP) lchown (FILE, OWNER, GROUP) -#else -# define LCHOWN(FILE, OWNER, GROUP) 1 -#endif - enum Change_status { + CH_NOT_APPLIED, CH_SUCCEEDED, CH_FAILED, CH_NO_CHANGE_REQUESTED @@ -83,7 +79,7 @@ char *program_name; /* If nonzero, and the systems has support for it, change the ownership of symbolic links rather than any files they point to. */ -static int change_symlinks; +static int change_symlinks = 1; /* If nonzero, change the ownership of directories recursively. */ static int recurse; @@ -105,9 +101,10 @@ static struct option const long_options[] = { {"recursive", no_argument, 0, 'R'}, {"changes", no_argument, 0, 'c'}, + {"dereference", no_argument, 0, CHAR_MAX + 2}, {"no-dereference", no_argument, 0, 'h'}, - {"silent", no_argument, 0, 'f'}, {"quiet", no_argument, 0, 'f'}, + {"silent", no_argument, 0, 'f'}, {"reference", required_argument, 0, CHAR_MAX + 1}, {"verbose", no_argument, 0, 'v'}, {GETOPT_HELP_OPTION_DECL}, @@ -122,6 +119,14 @@ static void describe_change (const char *file, enum Change_status changed) { const char *fmt; + + if (changed == CH_NOT_APPLIED) + { + printf (_("neither symbolic link %s nor referent has been changed\n"), + file); + return; + } + switch (changed) { case CH_SUCCEEDED: @@ -178,7 +183,7 @@ parse_group (const char *name, gid_t *g) Return 0 if successful, 1 if errors occurred. */ static int -change_file_group (const char *file, gid_t group) +change_file_group (int cmdline_arg, const char *file, gid_t group) { struct stat file_stats; int errors = 0; @@ -193,14 +198,31 @@ change_file_group (const char *file, gid_t group) if (group != file_stats.st_gid) { int fail; + int symlink_changed = 1; - if (change_symlinks) - fail = LCHOWN (file, (uid_t) -1, group); + if (S_ISLNK (file_stats.st_mode) && change_symlinks) + { + fail = lchown (file, (uid_t) -1, group); + + /* Ignore the failure if it's due to lack of support (ENOSYS) + and this is not a command line argument. */ + if (!cmdline_arg && fail && errno == ENOSYS) + { + fail = 0; + symlink_changed = 0; + } + } else - fail = chown (file, (uid_t) -1, group); + { + fail = chown (file, (uid_t) -1, group); + } if (verbosity == V_high || (verbosity == V_changes_only && !fail)) - describe_change (file, (fail ? CH_FAILED : CH_SUCCEEDED)); + { + enum Change_status ch_status = (! symlink_changed ? CH_NOT_APPLIED + : (fail ? CH_FAILED : CH_SUCCEEDED)); + describe_change (file, ch_status); + } if (fail) { @@ -282,7 +304,7 @@ change_dir_group (const char *dir, gid_t group, const struct stat *statp) path = xrealloc (path, pathlength); } strcpy (path + dirlength, namep); - errors |= change_file_group (path, group); + errors |= change_file_group (0, path, group); } free (path); free (name_space); @@ -344,6 +366,9 @@ main (int argc, char **argv) case CHAR_MAX + 1: reference_file = optarg; break; + case CHAR_MAX + 2: + change_symlinks = 0; + break; case 'R': recurse = 1; break; @@ -372,13 +397,6 @@ main (int argc, char **argv) usage (1); } -#if ! HAVE_LCHOWN - if (change_symlinks) - { - error (1, 0, _("--no-dereference (-h) is not supported on this system")); - } -#endif - if (reference_file) { struct stat ref_stats; @@ -391,7 +409,7 @@ main (int argc, char **argv) parse_group (argv[optind++], &group); for (; optind < argc; ++optind) - errors |= change_file_group (argv[optind], group); + errors |= change_file_group (1, argv[optind], group); if (verbosity != V_off) close_stdout (); -- cgit v1.2.3-70-g09d2