diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chown.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/src/chown.c b/src/chown.c index 7975904b9..8a943604e 100644 --- a/src/chown.c +++ b/src/chown.c @@ -170,6 +170,10 @@ main (int argc, char **argv) /* Bit flags that control how fts works. */ int bit_flags = FTS_PHYSICAL; + /* 1 if --dereference, 0 if --no-dereference, -1 if neither has been + specified. */ + int dereference = -1; + struct Chown_option chopt; int fail; int optc; @@ -193,7 +197,7 @@ main (int argc, char **argv) break; case 'H': /* Traverse command-line symlinks-to-directories. */ - bit_flags = FTS_COMFOLLOW; + bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; break; case 'L': /* Traverse all symlinks-to-directories. */ @@ -205,12 +209,12 @@ main (int argc, char **argv) break; case 'h': /* --no-dereference: affect symlinks */ - chopt.affect_symlink_referent = false; + dereference = 0; break; case DEREFERENCE_OPTION: /* --dereference: affect the referent of each symlink */ - chopt.affect_symlink_referent = true; + dereference = 1; break; case NO_PRESERVE_ROOT: @@ -259,6 +263,28 @@ main (int argc, char **argv) } } + if (chopt.recurse) + { + if (bit_flags == FTS_PHYSICAL) + { + if (dereference == 1) + error (EXIT_FAILURE, 0, + _("-R --dereference requires either -H or -L")); + chopt.affect_symlink_referent = false; + } + else + { + if (dereference == 0) + error (EXIT_FAILURE, 0, _("-R -h requires -P")); + chopt.affect_symlink_referent = true; + } + } + else + { + bit_flags = FTS_PHYSICAL; + chopt.affect_symlink_referent = (dereference != 0); + } + if (argc - optind + (reference_file ? 1 : 0) <= 1) { error (0, 0, _("too few arguments")); |