+ 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;
+}
+
+void
+maybe_prepend_name (char **file_name)
+{
+ int i;
+
+ for (i = 0; i < strlen (*file_name); i++)
+ if (!ISSLASH ((*file_name)[i]) && (*file_name)[i] != '.') break;
+
+ if (i == strlen (*file_name))
+ return;
+
+ if (!strncmp (*file_name + i, one_top_level, strlen (one_top_level)))
+ {
+ int pos = i + strlen (one_top_level);
+ if (ISSLASH ((*file_name)[pos]) || (*file_name)[pos] == '\0') return;
+ }
+
+ char *new_name = xmalloc (strlen (one_top_level) + strlen (*file_name) + 2);
+
+ strcpy (new_name, one_top_level);
+ strcat (new_name, "/");
+ strcat (new_name, *file_name);
+
+ free (*file_name);
+ *file_name = new_name;
+}
+
+/* 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;