| 124 | The old mode was OLD_MODE, but it was changed to NEW_MODE. */ |
| 125 | |
| 126 | static bool |
| 127 | mode_changed (int dir_fd, char const *file, char const *file_full_name, |
| 128 | mode_t old_mode, mode_t new_mode) |
| 129 | { |
| 130 | if (new_mode & (S_ISUID | S_ISGID | S_ISVTX)) |
| 131 | { |
| 132 | /* The new mode contains unusual bits that the call to chmod may |
| 133 | have silently cleared. Check whether they actually changed. */ |
| 134 | |
| 135 | struct stat new_stats; |
| 136 | |
| 137 | if (fstatat (dir_fd, file, &new_stats, 0) != 0) |
| 138 | { |
| 139 | if (! force_silent) |
| 140 | error (0, errno, _("getting new attributes of %s"), |
| 141 | quoteaf (file_full_name)); |
| 142 | return false; |
| 143 | } |
| 144 | |
| 145 | new_mode = new_stats.st_mode; |
| 146 | } |
| 147 | |
| 148 | return ((old_mode ^ new_mode) & CHMOD_MODE_BITS) != 0; |
| 149 | } |
| 150 | |
| 151 | /* Tell the user how/if the MODE of FILE has been changed. |
| 152 | CH describes what (if anything) has happened. */ |