diff options
Diffstat (limited to 'src/chown.c')
-rw-r--r-- | src/chown.c | 246 |
1 files changed, 119 insertions, 127 deletions
diff --git a/src/chown.c b/src/chown.c index 63a32f5..108e629 100644 --- a/src/chown.c +++ b/src/chown.c @@ -1,10 +1,10 @@ /* chown -- change user and group ownership of files - Copyright (C) 89, 90, 91, 1995-2006 Free Software Foundation, Inc. + Copyright (C) 1989-2016 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,21 +12,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* - | user - | unchanged explicit - -------------|-------------------------+-------------------------| - g unchanged | --- | chown u | - r |-------------------------+-------------------------| - o explicit | chgrp g or chown .g | chown u.g | - u |-------------------------+-------------------------| - p from passwd| --- | chown u. | - |-------------------------+-------------------------| - - Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ #include <config.h> #include <stdio.h> @@ -41,13 +29,12 @@ #include "root-dev-ino.h" #include "userspec.h" -/* The official name of this program (e.g., no `g' prefix). */ +/* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "chown" -#define AUTHORS "David MacKenzie", "Jim Meyering" - -/* The name the program was run with. */ -char *program_name; +#define AUTHORS \ + proper_name ("David MacKenzie"), \ + proper_name ("Jim Meyering") /* The argument to the --reference option. Use the owner and group IDs of this file. This file must exist. */ @@ -86,26 +73,31 @@ void usage (int status) { if (status != EXIT_SUCCESS) - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); + emit_try_help (); else { printf (_("\ Usage: %s [OPTION]... [OWNER][:[GROUP]] FILE...\n\ or: %s [OPTION]... --reference=RFILE FILE...\n\ "), - program_name, program_name); + program_name, program_name); fputs (_("\ Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\ With --reference, change the owner and group of each FILE to those of RFILE.\n\ \n\ +"), stdout); + fputs (_("\ -c, --changes like verbose but report only when a change is made\n\ + -f, --silent, --quiet suppress most error messages\n\ + -v, --verbose output a diagnostic for every file processed\n\ +"), stdout); + fputs (_("\ --dereference affect the referent of each symbolic link (this is\n\ the default), rather than the symbolic link itself\n\ + -h, --no-dereference affect symbolic links instead of any referenced file\n\ "), stdout); fputs (_("\ - -h, --no-dereference affect each symbolic link instead of any referenced\n\ - file (useful only on systems that can change the\n\ + (useful only on systems that can change the\n\ ownership of a symlink)\n\ "), stdout); fputs (_("\ @@ -113,21 +105,21 @@ With --reference, change the owner and group of each FILE to those of RFILE.\n\ change the owner and/or group of each file only if\n\ its current owner and/or group match those specified\n\ here. Either may be omitted, in which case a match\n\ - is not required for the omitted attribute.\n\ + is not required for the omitted attribute\n\ "), stdout); fputs (_("\ - --no-preserve-root do not treat `/' specially (the default)\n\ - --preserve-root fail to operate recursively on `/'\n\ + --no-preserve-root do not treat '/' specially (the default)\n\ + --preserve-root fail to operate recursively on '/'\n\ "), stdout); fputs (_("\ - -f, --silent, --quiet suppress most error messages\n\ --reference=RFILE use RFILE's owner and group rather than\n\ specifying OWNER:GROUP values\n\ +"), stdout); + fputs (_("\ -R, --recursive operate on files and directories recursively\n\ - -v, --verbose output a diagnostic for every file processed\n\ -\n\ "), stdout); fputs (_("\ +\n\ The following options modify how a hierarchy is traversed when the -R\n\ option is also specified. If more than one is specified, only the final\n\ one takes effect.\n\ @@ -144,7 +136,7 @@ one takes effect.\n\ fputs (_("\ \n\ Owner is unchanged if missing. Group is unchanged if missing, but changed\n\ -to login group if implied by a `:' following a symbolic OWNER.\n\ +to login group if implied by a ':' following a symbolic OWNER.\n\ OWNER and GROUP may be numeric as well as symbolic.\n\ "), stdout); printf (_("\ @@ -154,8 +146,8 @@ Examples:\n\ %s root:staff /u Likewise, but also change its group to \"staff\".\n\ %s -hR root /u Change the owner of /u and subfiles to \"root\".\n\ "), - program_name, program_name, program_name); - printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); + program_name, program_name, program_name); + emit_ancillary_info (PROGRAM_NAME); } exit (status); } @@ -185,7 +177,7 @@ main (int argc, char **argv) int optc; initialize_main (&argc, &argv); - program_name = argv[0]; + set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); @@ -195,86 +187,85 @@ main (int argc, char **argv) chopt_init (&chopt); while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL)) - != -1) + != -1) { switch (optc) - { - case 'H': /* Traverse command-line symlinks-to-directories. */ - bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; - break; - - case 'L': /* Traverse all symlinks-to-directories. */ - bit_flags = FTS_LOGICAL; - break; - - case 'P': /* Traverse no symlinks-to-directories. */ - bit_flags = FTS_PHYSICAL; - break; - - case 'h': /* --no-dereference: affect symlinks */ - dereference = 0; - break; - - case DEREFERENCE_OPTION: /* --dereference: affect the referent - of each symlink */ - dereference = 1; - break; - - case NO_PRESERVE_ROOT: - preserve_root = false; - break; - - case PRESERVE_ROOT: - preserve_root = true; - break; - - case REFERENCE_FILE_OPTION: - reference_file = optarg; - break; - - case FROM_OPTION: - { - char *u_dummy, *g_dummy; - const char *e = parse_user_spec (optarg, - &required_uid, &required_gid, - &u_dummy, &g_dummy); - if (e) - error (EXIT_FAILURE, 0, "%s: %s", quote (optarg), e); - break; - } - - case 'R': - chopt.recurse = true; - break; - - case 'c': - chopt.verbosity = V_changes_only; - break; - - case 'f': - chopt.force_silent = true; - break; - - case 'v': - chopt.verbosity = V_high; - break; - - case_GETOPT_HELP_CHAR; - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); - default: - usage (EXIT_FAILURE); - } + { + case 'H': /* Traverse command-line symlinks-to-directories. */ + bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; + break; + + case 'L': /* Traverse all symlinks-to-directories. */ + bit_flags = FTS_LOGICAL; + break; + + case 'P': /* Traverse no symlinks-to-directories. */ + bit_flags = FTS_PHYSICAL; + break; + + case 'h': /* --no-dereference: affect symlinks */ + dereference = 0; + break; + + case DEREFERENCE_OPTION: /* --dereference: affect the referent + of each symlink */ + dereference = 1; + break; + + case NO_PRESERVE_ROOT: + preserve_root = false; + break; + + case PRESERVE_ROOT: + preserve_root = true; + break; + + case REFERENCE_FILE_OPTION: + reference_file = optarg; + break; + + case FROM_OPTION: + { + const char *e = parse_user_spec (optarg, + &required_uid, &required_gid, + NULL, NULL); + if (e) + error (EXIT_FAILURE, 0, "%s: %s", e, quote (optarg)); + break; + } + + case 'R': + chopt.recurse = true; + break; + + case 'c': + chopt.verbosity = V_changes_only; + break; + + case 'f': + chopt.force_silent = true; + break; + + case 'v': + chopt.verbosity = V_high; + break; + + case_GETOPT_HELP_CHAR; + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + default: + usage (EXIT_FAILURE); + } } if (chopt.recurse) { if (bit_flags == FTS_PHYSICAL) - { - if (dereference == 1) - error (EXIT_FAILURE, 0, - _("-R --dereference requires either -H or -L")); - dereference = 0; - } + { + if (dereference == 1) + error (EXIT_FAILURE, 0, + _("-R --dereference requires either -H or -L")); + dereference = 0; + } } else { @@ -285,9 +276,9 @@ main (int argc, char **argv) if (argc - optind < (reference_file ? 1 : 2)) { if (argc <= optind) - error (0, 0, _("missing operand")); + error (0, 0, _("missing operand")); else - error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); + error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); usage (EXIT_FAILURE); } @@ -295,8 +286,8 @@ main (int argc, char **argv) { struct stat ref_stats; if (stat (reference_file, &ref_stats)) - error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), - quote (reference_file)); + error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), + quoteaf (reference_file)); uid = ref_stats.st_uid; gid = ref_stats.st_gid; @@ -306,33 +297,34 @@ main (int argc, char **argv) else { const char *e = parse_user_spec (argv[optind], &uid, &gid, - &chopt.user_name, &chopt.group_name); + &chopt.user_name, &chopt.group_name); if (e) - error (EXIT_FAILURE, 0, "%s: %s", quote (argv[optind]), e); + error (EXIT_FAILURE, 0, "%s: %s", e, quote (argv[optind])); /* If a group is specified but no user, set the user name to the - empty string so that diagnostics say "ownership :GROUP" - rather than "group GROUP". */ + empty string so that diagnostics say "ownership :GROUP" + rather than "group GROUP". */ if (!chopt.user_name && chopt.group_name) - chopt.user_name = ""; + chopt.user_name = bad_cast (""); optind++; } - if (chopt.recurse & preserve_root) + if (chopt.recurse && preserve_root) { static struct dev_ino dev_ino_buf; chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf); if (chopt.root_dev_ino == NULL) - error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), - quote ("/")); + error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), + quoteaf ("/")); } + bit_flags |= FTS_DEFER_STAT; ok = chown_files (argv + optind, bit_flags, - uid, gid, - required_uid, required_gid, &chopt); + uid, gid, + required_uid, required_gid, &chopt); chopt_free (&chopt); - exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); + return ok ? EXIT_SUCCESS : EXIT_FAILURE; } |