summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/chgrp.c44
-rw-r--r--src/chown.c44
2 files changed, 68 insertions, 20 deletions
diff --git a/src/chgrp.c b/src/chgrp.c
index 58cbe4f5a..3e4209983 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -88,6 +88,10 @@ static int changes_only;
/* The name of the group to which ownership of the files is being given. */
static const char *groupname;
+/* The argument to the --reference option. Use the group ID of this file.
+ This file must exist. */
+static char *reference_file;
+
/* If nonzero, display usage information and exit. */
static int show_help;
@@ -101,6 +105,7 @@ static struct option const long_options[] =
{"no-dereference", no_argument, 0, 'h'},
{"silent", no_argument, 0, 'f'},
{"quiet", no_argument, 0, 'f'},
+ {"reference", required_argument, 0, 12},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
@@ -277,18 +282,23 @@ usage (int status)
program_name);
else
{
- printf (_("Usage: %s [OPTION]... GROUP FILE...\n"), program_name);
+ printf (_("\
+Usage: %s [OPTION]... GROUP FILE...\n\
+ or: %s [OPTION]... --reference=RFILE FILE...\n\
+"),
+ program_name, program_name);
printf (_("\
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\
- -R, --recursive change files and directories recursively\n\
- -v, --verbose output a diagnostic for every file processed\n\
- --help display this help and exit\n\
- --version output version information and exit\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\
+ --reference=RFILE use RFILE's group instead of using a GROUP value\n\
+ -R, --recursive change files and directories recursively\n\
+ -v, --verbose output a diagnostic for every file processed\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
"));
puts (_("\nReport bugs to <fileutils-bugs@gnu.ai.mit.edu>."));
}
@@ -315,6 +325,9 @@ main (int argc, char **argv)
{
case 0:
break;
+ case 12:
+ reference_file = optarg;
+ break;
case 'R':
recurse = 1;
break;
@@ -345,7 +358,7 @@ main (int argc, char **argv)
if (show_help)
usage (0);
- if (argc - optind <= 1)
+ if (argc - optind + (reference_file ? 1 : 0) <= 1)
{
error (0, 0, _("too few arguments"));
usage (1);
@@ -358,7 +371,16 @@ main (int argc, char **argv)
}
#endif
- parse_group (argv[optind++], &group);
+ if (reference_file)
+ {
+ struct stat ref_stats;
+ if (stat (reference_file, &ref_stats))
+ error (1, errno, "%s", reference_file);
+
+ group = ref_stats.st_gid;
+ }
+ else
+ parse_group (argv[optind++], &group);
for (; optind < argc; ++optind)
errors |= change_file_group (argv[optind], group);
diff --git a/src/chown.c b/src/chown.c
index 48e07577c..54679a553 100644
--- a/src/chown.c
+++ b/src/chown.c
@@ -88,6 +88,10 @@ static char *username;
/* The name of the group to which ownership of the files is being given. */
static char *groupname;
+/* The argument to the --reference option. Use the owner and group IDs
+ of this file. This file must exist. */
+static char *reference_file;
+
/* If nonzero, display usage information and exit. */
static int show_help;
@@ -101,6 +105,7 @@ static struct option const long_options[] =
{"no-dereference", no_argument, 0, 'h'},
{"quiet", no_argument, 0, 'f'},
{"silent", no_argument, 0, 'f'},
+ {"reference", required_argument, 0, 12},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
@@ -233,9 +238,10 @@ usage (int status)
{
printf (_("\
Usage: %s [OPTION]... OWNER[.[GROUP]] FILE...\n\
- or: %s [OPTION]... .[GROUP] FILE...\n\
+ or: %s [OPTION]... .GROUP FILE...\n\
+ or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
- program_name, program_name);
+ program_name, program_name, program_name);
printf (_("\
Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\
\n\
@@ -244,6 +250,8 @@ Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\
(available only on systems that can change the\n\
ownership of a symlink)\n\
-f, --silent, --quiet suppress most error messages\n\
+ --reference=RFILE use the owner and group of RFILE instead of using\n\
+ explicit OWNER.GROUP values\n\
-R, --recursive operate on files and directories recursively\n\
-v, --verbose explain what is being done\n\
--help display this help and exit\n\
@@ -279,6 +287,9 @@ main (int argc, char **argv)
{
case 0:
break;
+ case 12:
+ reference_file = optarg;
+ break;
case 'R':
recurse = 1;
break;
@@ -309,7 +320,7 @@ main (int argc, char **argv)
if (show_help)
usage (0);
- if (optind >= argc - 1)
+ if (argc - optind + (reference_file ? 1 : 0) <= 1)
{
error (0, 0, _("too few arguments"));
usage (1);
@@ -322,13 +333,28 @@ main (int argc, char **argv)
}
#endif
- e = parse_user_spec (argv[optind], &user, &group, &username, &groupname);
- if (e)
- error (1, 0, "%s: %s", argv[optind], e);
- if (username == NULL)
- username = "";
+ if (reference_file)
+ {
+ struct stat ref_stats;
+
+ if (stat (reference_file, &ref_stats))
+ error (1, errno, "%s", reference_file);
+
+ user = ref_stats.st_uid;
+ group = ref_stats.st_gid;
+ }
+ else
+ {
+ e = parse_user_spec (argv[optind], &user, &group, &username, &groupname);
+ if (e)
+ error (1, 0, "%s: %s", argv[optind], e);
+ if (username == NULL)
+ username = "";
+
+ optind++;
+ }
- for (++optind; optind < argc; ++optind)
+ for (; optind < argc; ++optind)
{
strip_trailing_slashes (argv[optind]);
errors |= change_file_owner (argv[optind], user, group);