]> Dogcows Code - chaz/tar/blobdiff - src/delete.c
Fix descriptions of some options (tiny change)
[chaz/tar] / src / delete.c
index a854adce3b1299d67dfa7a4ac1a8382031297275..d59a857f5f9b663adfbdab89f39eba048e7edf80 100644 (file)
@@ -1,11 +1,11 @@
 /* Delete entries from a tar archive.
 
 /* Delete entries from a tar archive.
 
-   Copyright (C) 1988, 1992, 1994, 1996, 1997, 2000, 2001, 2003 Free
-   Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1994, 1996, 1997, 2000, 2001, 2003, 2004,
+   2005, 2006 Free Software Foundation, Inc.
 
    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
 
    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
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 
-#include "system.h"
+#include <system.h>
+#include <system-ioctl.h>
 
 #include "common.h"
 
 #include "common.h"
-#include "rmt.h"
+#include <rmt.h>
 
 static union block *new_record;
 static int new_blocks;
 
 static union block *new_record;
 static int new_blocks;
@@ -33,12 +34,12 @@ extern union block *record_end;
 extern union block *current_block;
 extern union block *recent_long_name;
 extern union block *recent_long_link;
 extern union block *current_block;
 extern union block *recent_long_name;
 extern union block *recent_long_link;
-extern off_t records_read; 
+extern off_t records_read;
 extern off_t records_written;
 
 /* The number of records skipped at the start of the archive, when
    passing over members that are not deleted.  */
 extern off_t records_written;
 
 /* The number of records skipped at the start of the archive, when
    passing over members that are not deleted.  */
-static off_t records_skipped;
+off_t records_skipped;
 
 /* Move archive descriptor by COUNT records worth.  If COUNT is
    positive we move forward, else we move negative.  If it's a tape,
 
 /* Move archive descriptor by COUNT records worth.  If COUNT is
    positive we move forward, else we move negative.  If it's a tape,
@@ -132,6 +133,21 @@ write_recent_blocks (union block *h, size_t blocks)
     }
 }
 
     }
 }
 
+static void
+write_recent_bytes (char *data, size_t bytes)
+{
+  size_t blocks = bytes / BLOCKSIZE;
+  size_t rest = bytes - blocks * BLOCKSIZE;
+
+  write_recent_blocks ((union block *)data, blocks);
+  memcpy (new_record[new_blocks].buffer, data + blocks * BLOCKSIZE, rest);
+  if (rest < BLOCKSIZE)
+    memset (new_record[new_blocks].buffer + rest, 0, BLOCKSIZE - rest);
+  new_blocks++;
+  if (new_blocks == blocking_factor)
+    write_record (1);
+}
+
 void
 delete_archive_members (void)
 {
 void
 delete_archive_members (void)
 {
@@ -158,12 +174,18 @@ delete_archive_members (void)
          abort ();
 
        case HEADER_SUCCESS:
          abort ();
 
        case HEADER_SUCCESS:
-         if (name = name_scan (current_stat_info.file_name), !name)
+         if ((name = name_scan (current_stat_info.file_name)) == NULL)
+           {
+             skip_member ();
+             break;
+           }
+         name->found_count++;
+         if (!ISFOUND(name))
            {
              skip_member ();
              break;
            }
            {
              skip_member ();
              break;
            }
-         name->found = 1;
+
          /* Fall through.  */
        case HEADER_SUCCESS_EXTENDED:
          logical_status = status;
          /* Fall through.  */
        case HEADER_SUCCESS_EXTENDED:
          logical_status = status;
@@ -213,7 +235,7 @@ delete_archive_members (void)
   if (logical_status == HEADER_SUCCESS
       || logical_status == HEADER_SUCCESS_EXTENDED)
     {
   if (logical_status == HEADER_SUCCESS
       || logical_status == HEADER_SUCCESS_EXTENDED)
     {
-      write_archive_to_stdout = 0;
+      write_archive_to_stdout = false;
 
       /* Save away blocks before this one in this record.  */
 
 
       /* Save away blocks before this one in this record.  */
 
@@ -241,6 +263,8 @@ delete_archive_members (void)
            flush_archive ();
          status = read_header (false);
 
            flush_archive ();
          status = read_header (false);
 
+         xheader_decode (&current_stat_info);
+
          if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
            {
              set_next_block_after (current_header);
          if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
            {
              set_next_block_after (current_header);
@@ -261,27 +285,38 @@ delete_archive_members (void)
 
          /* Found another header.  */
 
 
          /* Found another header.  */
 
-         if (name = name_scan (current_stat_info.file_name), name)
+         if ((name = name_scan (current_stat_info.file_name)) != NULL)
            {
            {
-             name->found = 1;
-           flush_file:
-             set_next_block_after (current_header);
-             blocks_to_skip = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
-
-             while (record_end - current_block <= blocks_to_skip)
+             name->found_count++;
+             if (ISFOUND(name))
                {
                {
-                 blocks_to_skip -= (record_end - current_block);
-                 flush_archive ();
+               flush_file:
+                 set_next_block_after (current_header);
+                 blocks_to_skip = (current_stat_info.stat.st_size
+                                   + BLOCKSIZE - 1) / BLOCKSIZE;
+                 
+                 while (record_end - current_block <= blocks_to_skip)
+                   {
+                     blocks_to_skip -= (record_end - current_block);
+                     flush_archive ();
+                   }
+                 current_block += blocks_to_skip;
+                 blocks_to_skip = 0;
+                 continue;
                }
                }
-             current_block += blocks_to_skip;
-             blocks_to_skip = 0;
-             continue;
            }
            }
-
          /* Copy header.  */
 
          /* Copy header.  */
 
-         write_recent_blocks (recent_long_name, recent_long_name_blocks);
-         write_recent_blocks (recent_long_link, recent_long_link_blocks);
+         if (current_stat_info.xhdr.size)
+           {
+             write_recent_bytes (current_stat_info.xhdr.buffer,
+                                 current_stat_info.xhdr.size);
+           }
+         else
+           {
+             write_recent_blocks (recent_long_name, recent_long_name_blocks);
+             write_recent_blocks (recent_long_link, recent_long_link_blocks);
+           }
          new_record[new_blocks] = *current_header;
          new_blocks++;
          blocks_to_keep
          new_record[new_blocks] = *current_header;
          new_blocks++;
          blocks_to_keep
@@ -325,39 +360,32 @@ delete_archive_members (void)
                write_record (1);
            }
        }
                write_record (1);
            }
        }
-    }
 
 
-  if (logical_status == HEADER_END_OF_FILE)
-    {
-      /* Write the end of tape.  FIXME: we can't use write_eot here,
-        as it gets confused when the input is at end of file.  */
+      if (logical_status == HEADER_END_OF_FILE)
+       {
+         /* Write the end of tape.  FIXME: we can't use write_eot here,
+            as it gets confused when the input is at end of file.  */
+
+         int total_zero_blocks = 0;
 
 
-      int total_zero_blocks = 0;
+         do
+           {
+             int zero_blocks = blocking_factor - new_blocks;
+             memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
+             total_zero_blocks += zero_blocks;
+             write_record (total_zero_blocks < 2);
+           }
+         while (total_zero_blocks < 2);
+       }
 
 
-      do
+      if (! acting_as_filter && ! _isrmt (archive))
        {
        {
-         int zero_blocks = blocking_factor - new_blocks;
-         memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
-         total_zero_blocks += zero_blocks;
-         write_record (total_zero_blocks < 2);
+         if (sys_truncate (archive))
+           truncate_warn (archive_name_array[0]);
        }
        }
-      while (total_zero_blocks < 2);
     }
     }
-
   free (new_record);
 
   free (new_record);
 
-  if (! acting_as_filter && ! _isrmt (archive))
-    {
-#if MSDOS
-      int status = write (archive, "", 0);
-#else
-      off_t pos = lseek (archive, (off_t) 0, SEEK_CUR);
-      int status = pos < 0 ? -1 : ftruncate (archive, pos);
-#endif
-      if (status != 0)
-       truncate_warn (archive_name_array[0]);
-    }
-
   close_archive ();
   names_notfound ();
 }
   close_archive ();
   names_notfound ();
 }
This page took 0.031508 seconds and 4 git commands to generate.