- if (i->mode_set)
- if (chmod(path, i->mode) < 0) {
- if (errno != ENOENT || !ignore_enoent) {
- log_error("chmod(%s) failed: %m", path);
- return -errno;
+ if (i->mode_set) {
+ mode_t m = i->mode;
+
+ if (i->mask_perms) {
+ struct stat st;
+
+ if (stat(path, &st) >= 0) {
+ if (!(st.st_mode & 0111))
+ m &= ~0111;
+ if (!(st.st_mode & 0222))
+ m &= ~0222;
+ if (!(st.st_mode & 0444))
+ m &= ~0444;
+ if (!S_ISDIR(st.st_mode))
+ m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */