+ /* FIXME: incremental_option should set ctime too, but how? */
+
+ if (incremental_option)
+ utimbuf.actime = stat_info->st_atime;
+ else
+ utimbuf.actime = now;
+
+ utimbuf.modtime = stat_info->st_mtime;
+
+ if (utime (file_name, &utimbuf) < 0)
+ ERROR ((0, errno,
+ _("%s: Could not change access and modification times"),
+ file_name));
+ }
+
+ /* 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);
+ }
+
+ /* If we are root, set the owner and group of the extracted file, so we
+ extract as the original owner. Or else, if we are running as a user,
+ leave the owner and group as they are, so we extract as that user. */
+
+ if (we_are_root || same_owner_option)
+ {
+#if HAVE_LCHOWN
+
+ /* 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 (symlink_flag)
+ {
+ if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
+ ERROR ((0, errno, _("%s: Cannot lchown to uid %d gid %d"),
+ file_name, stat_info->st_uid, stat_info->st_gid));
+ }
+ else
+ {
+ if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
+ ERROR ((0, errno, _("%s: Cannot chown to uid %d gid %d"),
+ file_name, stat_info->st_uid, stat_info->st_gid));
+ }
+
+#else /* not HAVE_LCHOWN */
+
+ if (!symlink_flag)
+
+ if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
+ ERROR ((0, errno, _("%s: Cannot chown to uid %d gid %d"),
+ file_name, stat_info->st_uid, stat_info->st_gid));
+
+#endif/* not HAVE_LCHOWN */
+
+ if (!symlink_flag)
+
+ /* 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, when root, let's attempt setting these bits once more. */
+
+ if (we_are_root && (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
+ set_mode (file_name, stat_info);
+ }
+}
+
+/*-----------------------------------------------------------------------.
+| After a file/link/symlink/directory creation has failed, see if it's |
+| because some required directory was not present, and if so, create all |
+| required directories. Return non-zero if a directory was created. |
+`-----------------------------------------------------------------------*/
+
+static int
+make_directories (char *file_name)