Преглед изворни кода

Fix the logic of prepare_to_extract.

* src/extract.c (prepare_to_extract): Return true to proceed with
the extraction, and false to skip the current member.  If extracting
over a pipe, skip unlinking logic.
(extract_archive): Update accordingly.
Sergey Poznyakoff пре 4 година
родитељ
комит
34d15af170
1 измењених фајлова са 50 додато и 78 уклоњено
  1. 50 78
      src/extract.c

+ 50 - 78
src/extract.c

@@ -1621,47 +1621,23 @@ extract_fifo (char *file_name, int typeflag)
 }
 #endif
 
-static int
-extract_volhdr (char *file_name, int typeflag)
-{
-  skip_member ();
-  return 0;
-}
-
-static int
-extract_failure (char *file_name, int typeflag)
-{
-  return 1;
-}
-
-static int
-extract_skip (char *file_name, int typeflag)
-{
-  skip_member ();
-  return 0;
-}
-
 typedef int (*tar_extractor_t) (char *file_name, int typeflag);
 
 
-
 /* Prepare to extract a file. Find extractor function.
-   Return zero if extraction should not proceed.  */
+   Return true to proceed with the extraction, false to skip the current
+   member.  */
 
-static int
+static bool
 prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
 {
-  int rc = 1;
-
-  if (EXTRACT_OVER_PIPE)
-    rc = 0;
+  tar_extractor_t extractor = NULL;
 
   /* Select the extractor */
   switch (typeflag)
     {
     case GNUTYPE_SPARSE:
-      *fun = extract_file;
-      rc = 1;
+      extractor = extract_file;
       break;
 
     case AREGTYPE:
@@ -1670,106 +1646,101 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
       /* Appears to be a file.  But BSD tar uses the convention that a slash
 	 suffix means a directory.  */
       if (current_stat_info.had_trailing_slash)
-	*fun = extract_dir;
+	extractor = extract_dir;
       else
-	{
-	  *fun = extract_file;
-	  rc = 1;
-	}
+	extractor = extract_file;
       break;
 
     case SYMTYPE:
-      *fun = extract_symlink;
+      extractor = extract_symlink;
       break;
 
     case LNKTYPE:
-      *fun = extract_link;
+      extractor = extract_link;
       break;
 
 #if S_IFCHR
     case CHRTYPE:
       current_stat_info.stat.st_mode |= S_IFCHR;
-      *fun = extract_node;
+      extractor = extract_node;
       break;
 #endif
 
 #if S_IFBLK
     case BLKTYPE:
       current_stat_info.stat.st_mode |= S_IFBLK;
-      *fun = extract_node;
+      extractor = extract_node;
       break;
 #endif
 
 #if HAVE_MKFIFO || defined mkfifo
     case FIFOTYPE:
-      *fun = extract_fifo;
+      extractor = extract_fifo;
       break;
 #endif
 
     case DIRTYPE:
     case GNUTYPE_DUMPDIR:
-      *fun = extract_dir;
+      extractor = extract_dir;
       if (current_stat_info.is_dumpdir)
 	delay_directory_restore_option = true;
       break;
 
     case GNUTYPE_VOLHDR:
-      *fun = extract_volhdr;
-      break;
-
+      return false;
+      
     case GNUTYPE_MULTIVOL:
       ERROR ((0, 0,
 	      _("%s: Cannot extract -- file is continued from another volume"),
 	      quotearg_colon (current_stat_info.file_name)));
-      *fun = extract_skip;
-      break;
+      return false;
 
     case GNUTYPE_LONGNAME:
     case GNUTYPE_LONGLINK:
       ERROR ((0, 0, _("Unexpected long name header")));
-      *fun = extract_failure;
-      break;
+      return false;
 
     default:
       WARNOPT (WARN_UNKNOWN_CAST,
 	       (0, 0,
 		_("%s: Unknown file type '%c', extracted as normal file"),
 		quotearg_colon (file_name), typeflag));
-      *fun = extract_file;
+      extractor = extract_file;
     }
 
-  /* Determine whether the extraction should proceed */
-  if (rc == 0)
-    return 0;
-
-  switch (old_files_option)
+  if (!EXTRACT_OVER_PIPE)
     {
-    case UNLINK_FIRST_OLD_FILES:
-      if (!remove_any_file (file_name,
-                            recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
-                                                      : ORDINARY_REMOVE_OPTION)
-	  && errno && errno != ENOENT)
+      switch (old_files_option)
 	{
-	  unlink_error (file_name);
-	  return 0;
-	}
-      break;
+	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 false;
+	    }
+	  break;
 
-    case KEEP_NEWER_FILES:
-      if (file_newer_p (file_name, 0, &current_stat_info))
-	{
-	  WARNOPT (WARN_IGNORE_NEWER,
-		   (0, 0, _("Current %s is newer or same age"),
-		    quote (file_name)));
-	  return 0;
-	}
-      break;
+	case KEEP_NEWER_FILES:
+	  if (file_newer_p (file_name, 0, &current_stat_info))
+	    {
+	      WARNOPT (WARN_IGNORE_NEWER,
+		       (0, 0, _("Current %s is newer or same age"),
+			quote (file_name)));
+	      return false;
+	    }
+	  break;
 
-    default:
-      break;
+	default:
+	  break;
+	}
     }
-
-  return 1;
+  *fun = extractor;
+  
+  return true;
 }
 
 /* Extract a file from the archive.  */
@@ -1832,13 +1803,14 @@ extract_archive (void)
 
   if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
     {
-      if (fun && (*fun) (current_stat_info.file_name, typeflag)
-	  && backup_option)
-	undo_last_backup ();
+      if (fun (current_stat_info.file_name, typeflag) == 0)
+	return;
     }
   else
     skip_member ();
 
+  if (backup_option)
+    undo_last_backup ();
 }
 
 /* Extract the links whose final extraction were delayed.  */