]> Dogcows Code - chaz/tar/blobdiff - src/buffer.c
(open_compressed_archive): Do not attemt to determine compression type if handling...
[chaz/tar] / src / buffer.c
index 0d142f7907e29909c7b61718bff8dc4995ee00fa..6390d7db401c0194b2443481cfa57e9df75f78e6 100644 (file)
@@ -177,32 +177,34 @@ static struct zip_magic magic[] = {
 #define compress_option(t) magic[t].option
 #define compress_program(t) magic[t].program
 
-/* Check if the file FD is a compressed archive. FD is guaranteed to
-   represent a local file */
+/* Check if the file ARCHIVE is a compressed archive. */
 enum compress_type 
-check_compressed_archive (int fd)
+check_compressed_archive ()
 {
   struct zip_magic *p;
   size_t status;
-  union block buf;
-  
-  status = read (fd, &buf, sizeof buf);
-  if (status != sizeof buf)
-    {
-      archive_read_error ();
-      FATAL_ERROR ((0, 0, _("Quitting now.")));
-    }
-
-  lseek (fd, 0, SEEK_SET); /* This will fail if fd==0, but that does not
-                             matter, since we do not handle compressed
-                             stdin anyway */
-  
-  if (tar_checksum (&buf) == HEADER_SUCCESS)
+  bool sfr, srp;
+
+  /* Prepare global data needed for find_next_block: */
+  record_end = record_start; /* set up for 1st record = # 0 */
+  sfr = read_full_records;
+  read_full_records = true; /* Suppress fatal error on reading a partial
+                              record */
+  srp = reading_from_pipe;
+  reading_from_pipe = true; /* Suppress warning message on reading a partial
+                              record */
+  find_next_block ();
+
+  /* Restore global values */
+  read_full_records = sfr;
+  reading_from_pipe = srp;
+
+  if (tar_checksum (record_start, true) == HEADER_SUCCESS)
     /* Probably a valid header */
     return ct_none;
 
   for (p = magic + 1; p < magic + NMAGIC; p++)
-    if (memcmp (buf.buffer, p->magic, p->length) == 0)
+    if (memcmp (record_start->buffer, p->magic, p->length) == 0)
       return p->type;
   
   return ct_none;
@@ -214,34 +216,33 @@ check_compressed_archive (int fd)
 int
 open_compressed_archive ()
 {
-  enum compress_type type;
-  int fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
-                   MODE_RW, rsh_command_option);
-  if (fd == -1 || _isrmt (fd))
-    return fd;
-  
-  type = check_compressed_archive (fd);
-  
-  if (type == ct_none)
+  archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
+                    MODE_RW, rsh_command_option);
+  if (archive == -1)
+    return archive;
+
+  if (!multi_volume_option) 
     {
-      if (rmtlseek (fd, (off_t) 0, SEEK_CUR) != 0)
-       {
-         /* Archive may be not seekable. Reopen it. */
-         rmtclose (fd);
-         fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
-                       MODE_RW, rsh_command_option);
-       }
-      return fd;
-    }
+      enum compress_type type = check_compressed_archive ();
+  
+      if (type == ct_none)
+       return archive;
 
-  /* FD is not needed any more */
-  rmtclose (fd);
+      /* FD is not needed any more */
+      rmtclose (archive);
 
-  /* Open compressed archive */
-  use_compress_program_option = compress_program (type);
-  child_pid = sys_child_open_for_uncompress ();
-  read_full_records = reading_from_pipe = true;
+      hit_eof = false; /* It might have been set by find_next_block in
+                         check_compressed_archive */
 
+      /* Open compressed archive */
+      use_compress_program_option = compress_program (type);
+      child_pid = sys_child_open_for_uncompress ();
+      read_full_records = reading_from_pipe = true;
+    }
+  
+  records_read = 0;
+  record_end = record_start; /* set up for 1st record = # 0 */
+  
   return archive;
 }
 \f
@@ -408,6 +409,8 @@ open_archive (enum access_mode wanted_access)
   read_full_records = read_full_records_option;
   reading_from_pipe = false;
   
+  records_read = 0;
+  
   if (use_compress_program_option)
     {
       switch (wanted_access)
@@ -415,6 +418,7 @@ open_archive (enum access_mode wanted_access)
        case ACCESS_READ:
          child_pid = sys_child_open_for_uncompress ();
          read_full_records = reading_from_pipe = true;
+         record_end = record_start; /* set up for 1st record = # 0 */
          break;
 
        case ACCESS_WRITE:
@@ -509,9 +513,9 @@ open_archive (enum access_mode wanted_access)
     {
     case ACCESS_UPDATE:
       records_written = 0;
-    case ACCESS_READ:
-      records_read = 0;
       record_end = record_start; /* set up for 1st record = # 0 */
+
+    case ACCESS_READ:
       find_next_block ();      /* read it in, check for EOF */
 
       if (volume_label_option)
This page took 0.022747 seconds and 4 git commands to generate.