+ if (utime (file_name, &utimbuf) < 0)
+ utime_error (file_name);
+ else
+ {
+ check_time (file_name, utimbuf.actime);
+ check_time (file_name, utimbuf.modtime);
+ }
+ }
+
+ /* Some systems allow non-root users to give files away. Once this
+ done, it is not possible anymore to change file permissions, so we
+ have to set permissions prior to possibly giving files away. */
+
+ set_mode (file_name, stat_info, current_stat_info,
+ invert_permissions, permstatus, typeflag);
+ }
+
+ if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS)
+ {
+ /* When lchown exists, it should be used to change the attributes of
+ the symbolic link itself. In this case, a mere chown would change
+ the attributes of the file the symbolic link is pointing to, and
+ should be avoided. */
+
+ if (typeflag == SYMTYPE)
+ {
+#if HAVE_LCHOWN
+ if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
+ chown_error_details (file_name,
+ stat_info->st_uid, stat_info->st_gid);
+#endif
+ }
+ else
+ {
+ if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
+ chown_error_details (file_name,
+ stat_info->st_uid, stat_info->st_gid);
+
+ /* On a few systems, and in particular, those allowing to give files
+ away, changing the owner or group destroys the suid or sgid bits.
+ So let's attempt setting these bits once more. */
+ if (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX))
+ set_mode (file_name, stat_info, 0,
+ invert_permissions, permstatus, typeflag);
+ }
+ }
+}
+
+/* Remember to restore stat attributes (owner, group, mode and times)
+ for the directory FILE_NAME, using information given in *STAT_INFO,
+ once we stop extracting files into that directory.
+ If not restoring permissions, remember to invert the
+ INVERT_PERMISSIONS bits from the file's current permissions.
+ PERMSTATUS specifies the status of the file's permissions. */
+static void
+delay_set_stat (char const *file_name, struct stat const *stat_info,
+ mode_t invert_permissions, enum permstatus permstatus)