+
+ /* Print the block from current_header and current_stat. */
+
+ if (verbose_option)
+ print_header (¤t_stat_info, -1);
+
+ file_name = safer_name_suffix (current_stat_info.file_name,
+ false, absolute_names_option);
+ if (strip_name_components)
+ {
+ size_t prefix_len = stripped_prefix_len (file_name,
+ strip_name_components);
+ if (prefix_len == (size_t) -1)
+ {
+ skip_member ();
+ return;
+ }
+ file_name += prefix_len;
+ }
+
+ /* Restore stats for all non-ancestor directories, unless
+ it is an incremental archive.
+ (see NOTICE in the comment to delay_set_stat above) */
+ if (!directories_first)
+ apply_nonancestor_delayed_set_stat (file_name, 0);
+
+ /* Take a safety backup of a previously existing file. */
+
+ if (backup_option)
+ if (!maybe_backup_file (file_name, 0))
+ {
+ int e = errno;
+ ERROR ((0, e, _("%s: Was unable to backup this file"),
+ quotearg_colon (file_name)));
+ skip_member ();
+ return;
+ }
+
+ /* Extract the archive entry according to its type. */
+ /* KLUDGE */
+ typeflag = sparse_member_p (¤t_stat_info) ?
+ GNUTYPE_SPARSE : current_header->header.typeflag;
+
+ if (prepare_to_extract (file_name, typeflag, &fun))
+ {
+ if (fun && (*fun) (file_name, typeflag) && backup_option)
+ undo_last_backup ();
+ }
+ else
+ skip_member ();
+
+}
+
+/* Extract the symbolic links whose final extraction were delayed. */
+static void
+apply_delayed_links (void)
+{
+ struct delayed_link *ds;
+
+ for (ds = delayed_link_head; ds; )
+ {
+ struct string_list *sources = ds->sources;
+ char const *valid_source = 0;
+
+ for (sources = ds->sources; sources; sources = sources->next)
+ {
+ char const *source = sources->string;
+ struct stat st;
+
+ /* Make sure the placeholder file is still there. If not,
+ don't create a link, as the placeholder was probably
+ removed by a later extraction. */
+ if (lstat (source, &st) == 0
+ && st.st_dev == ds->dev
+ && st.st_ino == ds->ino
+ && timespec_cmp (get_stat_mtime (&st), ds->mtime) == 0)
+ {
+ /* Unlink the placeholder, then create a hard link if possible,
+ a symbolic link otherwise. */
+ if (unlink (source) != 0)
+ unlink_error (source);
+ else if (valid_source && link (valid_source, source) == 0)
+ ;
+ else if (!ds->is_symlink)
+ {
+ if (link (ds->target, source) != 0)
+ link_error (ds->target, source);
+ }
+ else if (symlink (ds->target, source) != 0)
+ symlink_error (ds->target, source);
+ else
+ {
+ struct tar_stat_info st1;
+ st1.stat.st_uid = ds->uid;
+ st1.stat.st_gid = ds->gid;
+ set_stat (source, &st1, NULL, 0, 0, SYMTYPE);
+ valid_source = source;
+ }
+ }
+ }
+
+ for (sources = ds->sources; sources; )
+ {
+ struct string_list *next = sources->next;
+ free (sources);
+ sources = next;
+ }
+
+ {
+ struct delayed_link *next = ds->next;
+ free (ds);
+ ds = next;
+ }
+ }
+
+ delayed_link_head = 0;
+}
+
+/* Finish the extraction of an archive. */
+void
+extract_finish (void)
+{
+ /* First, fix the status of ordinary directories that need fixing. */
+ apply_nonancestor_delayed_set_stat ("", 0);
+
+ /* Then, apply delayed links, so that they don't affect delayed
+ directory status-setting for ordinary directories. */
+ apply_delayed_links ();
+
+ /* Finally, fix the status of directories that are ancestors
+ of delayed links. */
+ apply_nonancestor_delayed_set_stat ("", 1);