diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2018-07-11 23:59:10 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2018-07-12 00:36:52 -0400 |
commit | 3529cc45cb25630a109cb650d5813a1f2ba405cb (patch) | |
tree | f143ca063614f86e90b7856a186c64678aff300d /eval.c | |
parent | f25efd83a941d143dff939d353113415b3a7fa90 (diff) | |
download | bfs-3529cc45cb25630a109cb650d5813a1f2ba405cb.tar.xz |
eval: Fix -delete when following symlinks.
Same bug as https://savannah.gnu.org/bugs/?46305. Please don't ever do
this though.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -277,8 +277,21 @@ bool eval_delete(const struct expr *expr, struct eval_state *state) { } int flag = 0; - if (ftwbuf->typeflag == BFTW_DIR) { - flag |= AT_REMOVEDIR; + if (ftwbuf->at_flags & AT_SYMLINK_NOFOLLOW) { + if (ftwbuf->typeflag == BFTW_DIR) { + flag |= AT_REMOVEDIR; + } + } else { + // We need to know the actual type of the path, not what it points to + struct bfs_stat sb; + if (bfs_stat(ftwbuf->at_fd, ftwbuf->at_path, ftwbuf->at_flags | AT_SYMLINK_NOFOLLOW, 0, &sb) == 0) { + if (S_ISDIR(sb.mode)) { + flag |= AT_REMOVEDIR; + } + } else { + eval_error(state); + return false; + } } if (unlinkat(ftwbuf->at_fd, ftwbuf->at_path, flag) != 0) { |