]> Dogcows Code - chaz/tar/blobdiff - src/buffer.c
(magic): Add an entry for new lzma format. Proposed by Lasse Collin
[chaz/tar] / src / buffer.c
index 2b53ec38d6d90d4c0ef1fed3e7373fe1b372a306..75b4487a8ef2ef5c3064749b71b042ce8e23ca60 100644 (file)
@@ -1,13 +1,13 @@
 /* Buffer management for tar.
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
 /* Buffer management for tar.
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
-   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1985-08-25.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
 
    Written by John Gilmore, on 1985-08-25.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any later
+   Free Software Foundation; either version 3, or (at your option) any later
    version.
 
    This program is distributed in the hope that it will be useful, but
    version.
 
    This program is distributed in the hope that it will be useful, but
@@ -26,7 +26,6 @@
 
 #include <closeout.h>
 #include <fnmatch.h>
 
 #include <closeout.h>
 #include <fnmatch.h>
-#include <getline.h>
 #include <human.h>
 #include <quotearg.h>
 
 #include <human.h>
 #include <quotearg.h>
 
@@ -121,6 +120,15 @@ static off_t save_totsize; /* total size of file we are writing, only
 static off_t save_sizeleft;    /* where we are in the file we are writing,
                                   only valid if save_name is nonzero */
 
 static off_t save_sizeleft;    /* where we are in the file we are writing,
                                   only valid if save_name is nonzero */
 
+\f
+static struct tar_stat_info dummy;
+
+void
+buffer_write_global_xheader ()
+{
+  xheader_write_global (&dummy.xhdr);
+}
+
 void
 mv_begin (struct tar_stat_info *st)
 {
 void
 mv_begin (struct tar_stat_info *st)
 {
@@ -196,7 +204,8 @@ enum compress_type {
   ct_none,
   ct_compress,
   ct_gzip,
   ct_none,
   ct_compress,
   ct_gzip,
-  ct_bzip2
+  ct_bzip2,
+  ct_lzma
 };
 
 struct zip_magic
 };
 
 struct zip_magic
@@ -213,6 +222,7 @@ static struct zip_magic const magic[] = {
   { ct_compress, 2, "\037\235", "compress", "-Z" },
   { ct_gzip,     2, "\037\213", "gzip", "-z"  },
   { ct_bzip2,    3, "BZh",      "bzip2", "-j" },
   { ct_compress, 2, "\037\235", "compress", "-Z" },
   { ct_gzip,     2, "\037\213", "gzip", "-z"  },
   { ct_bzip2,    3, "BZh",      "bzip2", "-j" },
+  { ct_lzma,     6, "\xFFLZMA", "lzma", "-a" }, /* FIXME: ???? */
 };
 
 #define NMAGIC (sizeof(magic)/sizeof(magic[0]))
 };
 
 #define NMAGIC (sizeof(magic)/sizeof(magic[0]))
@@ -226,14 +236,16 @@ check_compressed_archive ()
 {
   struct zip_magic const *p;
   bool sfr;
 {
   struct zip_magic const *p;
   bool sfr;
-
+  bool short_file = false;
+  
   /* 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 */
   /* 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 */
-  find_next_block ();
-
+  if (find_next_block () == 0)
+    short_file = true;
+  
   /* Restore global values */
   read_full_records = sfr;
 
   /* Restore global values */
   read_full_records = sfr;
 
@@ -245,6 +257,9 @@ check_compressed_archive ()
     if (memcmp (record_start->buffer, p->magic, p->length) == 0)
       return p->type;
 
     if (memcmp (record_start->buffer, p->magic, p->length) == 0)
       return p->type;
 
+  if (short_file)
+    ERROR ((0, 0, _("This does not look like a tar archive")));
+
   return ct_none;
 }
 
   return ct_none;
 }
 
@@ -338,6 +353,9 @@ print_total_stats ()
       print_stats (stderr, _("Total bytes read"),
                   records_read * record_size);
       break;
       print_stats (stderr, _("Total bytes read"),
                   records_read * record_size);
       break;
+
+    default:
+      abort ();
     }
 }
 
     }
 }
 
@@ -433,16 +451,6 @@ _open_archive (enum access_mode wanted_access)
 {
   int backed_up_flag = 0;
 
 {
   int backed_up_flag = 0;
 
-  if (index_file_name)
-    {
-      stdlis = freopen (index_file_name, "w", stdout);
-      if (! stdlis)
-       open_error (index_file_name);
-      close_stdout_set_file_name (index_file_name);
-    }
-  else
-    stdlis = to_stdout_option ? stderr : stdout;
-
   if (record_size == 0)
     FATAL_ERROR ((0, 0, _("Invalid value for record_size")));
 
   if (record_size == 0)
     FATAL_ERROR ((0, 0, _("Invalid value for record_size")));
 
@@ -482,7 +490,8 @@ _open_archive (enum access_mode wanted_access)
          break;
        }
 
          break;
        }
 
-      if (wanted_access == ACCESS_WRITE
+      if (!index_file_name
+         && wanted_access == ACCESS_WRITE
          && strcmp (archive_name_array[0], "-") == 0)
        stdlis = stderr;
     }
          && strcmp (archive_name_array[0], "-") == 0)
        stdlis = stderr;
     }
@@ -510,14 +519,16 @@ _open_archive (enum access_mode wanted_access)
 
        case ACCESS_WRITE:
          archive = STDOUT_FILENO;
 
        case ACCESS_WRITE:
          archive = STDOUT_FILENO;
-         stdlis = stderr;
+         if (!index_file_name)
+           stdlis = stderr;
          break;
 
        case ACCESS_UPDATE:
          archive = STDIN_FILENO;
          break;
 
        case ACCESS_UPDATE:
          archive = STDIN_FILENO;
-         stdlis = stderr;
          write_archive_to_stdout = true;
          record_end = record_start; /* set up for 1st record = # 0 */
          write_archive_to_stdout = true;
          record_end = record_start; /* set up for 1st record = # 0 */
+         if (!index_file_name)
+           stdlis = stderr;
          break;
        }
     }
          break;
        }
     }
@@ -581,7 +592,7 @@ _open_archive (enum access_mode wanted_access)
 }
 
 static void
 }
 
 static void
-do_checkpoint (bool write)
+do_checkpoint (bool do_write)
 {
   if (checkpoint_option && !(++checkpoint % checkpoint_option))
     {
 {
   if (checkpoint_option && !(++checkpoint % checkpoint_option))
     {
@@ -593,7 +604,7 @@ do_checkpoint (bool write)
          break;
 
        case checkpoint_text:
          break;
 
        case checkpoint_text:
-         if (write)
+         if (do_write)
            /* TRANSLATORS: This is a ``checkpoint of write operation'',
             *not* ``Writing a checkpoint''.
             E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
            /* TRANSLATORS: This is a ``checkpoint of write operation'',
             *not* ``Writing a checkpoint''.
             E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
@@ -1033,7 +1044,8 @@ new_volume (enum access_mode mode)
   assign_string (&volume_label, NULL);
   assign_string (&continued_file_name, NULL);
   continued_file_size = continued_file_offset = 0;
   assign_string (&volume_label, NULL);
   assign_string (&continued_file_name, NULL);
   continued_file_size = continued_file_offset = 0;
-
+  current_block = record_start;
+  
   if (rmtclose (archive) != 0)
     close_warn (*archive_name_cursor);
 
   if (rmtclose (archive) != 0)
     close_warn (*archive_name_cursor);
 
@@ -1126,23 +1138,24 @@ try_new_volume ()
 {
   size_t status;
   union block *header;
 {
   size_t status;
   union block *header;
-  struct tar_stat_info dummy;
-       
+  enum access_mode acc;
+  
   switch (subcommand_option)
     {
     case APPEND_SUBCOMMAND:
     case CAT_SUBCOMMAND:
     case UPDATE_SUBCOMMAND:
   switch (subcommand_option)
     {
     case APPEND_SUBCOMMAND:
     case CAT_SUBCOMMAND:
     case UPDATE_SUBCOMMAND:
-      if (!new_volume (ACCESS_UPDATE))
-       return true;
+      acc = ACCESS_UPDATE;
       break;
 
     default:
       break;
 
     default:
-      if (!new_volume (ACCESS_READ))
-       return true;
+      acc = ACCESS_READ;
       break;
     }
 
       break;
     }
 
+  if (!new_volume (acc))
+    return true;
+  
   while ((status = rmtread (archive, record_start->buffer, record_size))
         == SAFE_READ_ERROR)
     archive_read_error ();
   while ((status = rmtread (archive, record_start->buffer, record_size))
         == SAFE_READ_ERROR)
     archive_read_error ();
@@ -1296,7 +1309,7 @@ static void
 _write_volume_label (const char *str)
 {
   if (archive_format == POSIX_FORMAT)
 _write_volume_label (const char *str)
 {
   if (archive_format == POSIX_FORMAT)
-    xheader_store ("GNU.volume.label", NULL, str);
+    xheader_store ("GNU.volume.label", &dummy, str);
   else
     {
       union block *label = find_next_block ();
   else
     {
       union block *label = find_next_block ();
@@ -1413,9 +1426,9 @@ add_multi_volume_header (void)
   if (archive_format == POSIX_FORMAT)
     {
       off_t d = real_s_totsize - real_s_sizeleft;
   if (archive_format == POSIX_FORMAT)
     {
       off_t d = real_s_totsize - real_s_sizeleft;
-      xheader_store ("GNU.volume.filename", NULL, real_s_name);
-      xheader_store ("GNU.volume.size", NULL, &real_s_sizeleft);
-      xheader_store ("GNU.volume.offset", NULL, &d);
+      xheader_store ("GNU.volume.filename", &dummy, real_s_name);
+      xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
+      xheader_store ("GNU.volume.offset", &dummy, &d);
     }
   else
     gnu_add_multi_volume_header ();
     }
   else
     gnu_add_multi_volume_header ();
@@ -1602,7 +1615,7 @@ _gnu_flush_write (size_t buffer_level)
   if (!new_volume (ACCESS_WRITE))
     return;
 
   if (!new_volume (ACCESS_WRITE))
     return;
 
-  xheader_destroy (&extended_header);
+  tar_stat_destroy (&dummy);
 
   increase_volume_number ();
   prev_written += bytes_written;
 
   increase_volume_number ();
   prev_written += bytes_written;
@@ -1620,7 +1633,9 @@ _gnu_flush_write (size_t buffer_level)
   if (real_s_name)
     add_multi_volume_header ();
 
   if (real_s_name)
     add_multi_volume_header ();
 
-  write_extended (true, NULL, find_next_block ());
+  write_extended (true, &dummy, find_next_block ());
+  tar_stat_destroy (&dummy);
+  
   if (real_s_name)
     add_chunk_header ();
   header = find_next_block ();
   if (real_s_name)
     add_chunk_header ();
   header = find_next_block ();
This page took 0.025944 seconds and 4 git commands to generate.