summaryrefslogtreecommitdiff
path: root/src/chgrp.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1996-05-19 17:13:36 +0000
committerJim Meyering <jim@meyering.net>1996-05-19 17:13:36 +0000
commitfaf0038376ddcb40f17570cc75f420ccb440cf18 (patch)
tree969be544633d06a135ecc026b861dbe268d4a3bc /src/chgrp.c
parentdd7aea80f7f7b49f1aa379821e9f2dacbc93abe1 (diff)
downloadcoreutils-faf0038376ddcb40f17570cc75f420ccb440cf18.tar.xz
New option: --no-dereference (-h).
[!MAXUID]: Define to INT_MAX. (change_file_group): Use lchown if --no-dereference (-h) was given. (usage): Update. (main): Fail if user requests --no-dereference on a system that doesn't have support for it.
Diffstat (limited to 'src/chgrp.c')
-rw-r--r--src/chgrp.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/chgrp.c b/src/chgrp.c
index 1806c6f39..8900091ba 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -27,10 +27,6 @@
# include <limits.h>
#endif
-#ifdef HAVE_LCHOWN
-# define chown(PATH, OWNER, GROUP) lchown(PATH, OWNER, GROUP)
-#endif
-
#ifndef UINT_MAX
# define UINT_MAX ((unsigned int) ~(unsigned int) 0)
#endif
@@ -39,6 +35,10 @@
# define INT_MAX ((int) (UINT_MAX >> 1))
#endif
+#ifndef MAXUID
+# define MAXUID INT_MAX
+#endif
+
#include "system.h"
#include "xstrtoul.h"
#include "error.h"
@@ -51,6 +51,12 @@ struct group *getgrnam ();
# define endgrent() ((void) 0)
#endif
+#ifdef HAVE_LCHOWN
+# define LCHOWN(FILE, OWNER, GROUP) lchown (FILE, OWNER, GROUP)
+#else
+# define LCHOWN(FILE, OWNER, GROUP) 1
+#endif
+
char *group_member ();
char *savedir ();
char *xmalloc ();
@@ -61,6 +67,10 @@ static int change_dir_group __P ((char *dir, int group, struct stat *statp));
/* The name the program was run with. */
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;
+
/* If nonzero, change the ownership of directories recursively. */
static int recurse;
@@ -86,6 +96,7 @@ static struct option const long_options[] =
{
{"recursive", no_argument, 0, 'R'},
{"changes", no_argument, 0, 'c'},
+ {"no-dereference", no_argument, 0, 'h'},
{"silent", no_argument, 0, 'f'},
{"quiet", no_argument, 0, 'f'},
{"verbose", no_argument, 0, 'v'},
@@ -154,9 +165,17 @@ change_file_group (char *file, int group)
if (group != file_stats.st_gid)
{
+ int fail;
+
if (verbose)
describe_change (file, 1);
- if (chown (file, file_stats.st_uid, group))
+
+ if (change_symlinks)
+ fail = LCHOWN (file, file_stats.st_uid, group);
+ else
+ fail = chown (file, file_stats.st_uid, group);
+
+ if (fail)
{
errors = 1;
if (force_silent == 0)
@@ -169,12 +188,10 @@ change_file_group (char *file, int group)
error (0, errno, _("you are not a member of group `%s'"),
groupname);
}
-#ifdef MAXUID
else if (errno == EINVAL && group > MAXUID)
{
error (0, 0, _("%s: invalid group number"), groupname);
}
-#endif
else
{
error (0, errno, "%s", file);
@@ -255,6 +272,8 @@ usage (int status)
Change the group membership of each FILE to GROUP.\n\
\n\
-c, --changes like verbose but report only when a change is made\n\
+ -h, --no-dereference affect symbolic links instead of any referenced file\n\
+ (available only on systems with lchown system call)\n\
-f, --silent, --quiet suppress most error messages\n\
-v, --verbose output a diagnostic for every file processed\n\
-R, --recursive change files and directories recursively\n\
@@ -274,7 +293,7 @@ main (int argc, char **argv)
program_name = argv[0];
recurse = force_silent = verbose = changes_only = 0;
- while ((optc = getopt_long (argc, argv, "Rcfv", long_options, (int *) 0))
+ while ((optc = getopt_long (argc, argv, "Rcfnv", long_options, (int *) 0))
!= EOF)
{
switch (optc)
@@ -291,6 +310,9 @@ main (int argc, char **argv)
case 'f':
force_silent = 1;
break;
+ case 'h':
+ change_symlinks = 1;
+ break;
case 'v':
verbose = 1;
break;
@@ -314,6 +336,13 @@ main (int argc, char **argv)
usage (1);
}
+#ifndef HAVE_LCHOWN
+ if (change_symlinks)
+ {
+ error (1, 0, _("--no-dereference (-h) is not supported on this system"));
+ }
+#endif
+
parse_group (argv[optind++], &group);
for (; optind < argc; ++optind)