]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
Support new options: --preserve-root and --no-preserve-root.
authorJim Meyering <jim@meyering.net>
Sun, 9 Nov 2003 21:10:11 +0000 (21:10 +0000)
committerJim Meyering <jim@meyering.net>
Sun, 9 Nov 2003 21:10:11 +0000 (21:10 +0000)
src/chown.c

index fae399db04e7f4c2124808da7790c5154105df6d..956cd894390a87f95d5aa2764ee336801bc43556 100644 (file)
@@ -39,6 +39,7 @@
 #include "fts_.h"
 #include "lchown.h"
 #include "quote.h"
+#include "root-dev-ino.h"
 #include "userspec.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
@@ -57,8 +58,10 @@ static char *reference_file;
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
 {
-  FROM_OPTION = CHAR_MAX + 1,
-  DEREFERENCE_OPTION,
+  DEREFERENCE_OPTION = CHAR_MAX + 1,
+  FROM_OPTION,
+  NO_PRESERVE_ROOT,
+  PRESERVE_ROOT,
   REFERENCE_FILE_OPTION
 };
 
@@ -69,6 +72,8 @@ static struct option const long_options[] =
   {"dereference", no_argument, 0, DEREFERENCE_OPTION},
   {"from", required_argument, 0, FROM_OPTION},
   {"no-dereference", no_argument, 0, 'h'},
+  {"no-preserve-root", no_argument, 0, NO_PRESERVE_ROOT},
+  {"preserve-root", no_argument, 0, PRESERVE_ROOT},
   {"quiet", no_argument, 0, 'f'},
   {"silent", no_argument, 0, 'f'},
   {"reference", required_argument, 0, REFERENCE_FILE_OPTION},
@@ -111,6 +116,10 @@ With --reference, change the owner and group of each FILE to those of RFILE.\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\
+"), stdout);
+      fputs (_("\
+      --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\
@@ -148,6 +157,8 @@ as symbolic.\n\
 int
 main (int argc, char **argv)
 {
+  bool preserve_root = false;
+
   uid_t uid = -1;      /* Specified uid; -1 if not to be changed. */
   gid_t gid = -1;      /* Specified gid; -1 if not to be changed. */
 
@@ -202,6 +213,14 @@ main (int argc, char **argv)
          chopt.affect_symlink_referent = true;
          break;
 
+       case NO_PRESERVE_ROOT:
+         preserve_root = false;
+         break;
+
+       case PRESERVE_ROOT:
+         preserve_root = true;
+         break;
+
        case REFERENCE_FILE_OPTION:
          reference_file = optarg;
          break;
@@ -272,6 +291,15 @@ main (int argc, char **argv)
       optind++;
     }
 
+  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 ("/"));
+    }
+
   fail = chown_files (argv + optind, bit_flags,
                      uid, gid,
                      required_uid, required_gid, &chopt);