+ WARNOPT (WARN_UNKNOWN_CAST,
+ (0, 0,
+ _("%s: Unknown file type '%c', extracted as normal file"),
+ quotearg_colon (file_name), typeflag));
+ *fun = extract_file;
+ }
+
+ /* Determine whether the extraction should proceed */
+ if (rc == 0)
+ return 0;
+
+ switch (old_files_option)
+ {
+ case UNLINK_FIRST_OLD_FILES:
+ if (!remove_any_file (file_name,
+ recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
+ : ORDINARY_REMOVE_OPTION)
+ && errno && errno != ENOENT)
+ {
+ unlink_error (file_name);
+ return 0;
+ }
+ break;
+
+ case KEEP_NEWER_FILES:
+ if (file_newer_p (file_name, 0, ¤t_stat_info))
+ {
+ WARNOPT (WARN_IGNORE_NEWER,
+ (0, 0, _("Current %s is newer or same age"),
+ quote (file_name)));
+ return 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+/* Extract a file from the archive. */
+void
+extract_archive (void)
+{
+ char typeflag;
+ tar_extractor_t fun;
+
+ fatal_exit_hook = extract_finish;
+
+ set_next_block_after (current_header);
+
+ if (!current_stat_info.file_name[0]
+ || (interactive_option
+ && !confirm ("extract", current_stat_info.file_name)))
+ {
+ skip_member ();
+ return;
+ }
+
+ /* Print the block from current_header and current_stat. */
+ if (verbose_option)
+ print_header (¤t_stat_info, current_header, -1);
+
+ /* Restore stats for all non-ancestor directories, unless
+ it is an incremental archive.
+ (see NOTICE in the comment to delay_set_stat above) */
+ if (!delay_directory_restore_option)
+ {
+ int dir = chdir_current;
+ apply_nonancestor_delayed_set_stat (current_stat_info.file_name, 0);
+ chdir_do (dir);