]> Dogcows Code - chaz/tar/blobdiff - src/delete.c
(delete_archive_members): Honor --occurence option.
[chaz/tar] / src / delete.c
index a854adce3b1299d67dfa7a4ac1a8382031297275..b79321ff319b08c3a2d306e4cda2ca3d8eb45189 100644 (file)
@@ -132,6 +132,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)
 {
@@ -158,12 +173,18 @@ delete_archive_members (void)
          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 = 1;
+         name->found_count++;
+         if (!ISFOUND(name))
+           {
+             skip_member ();
+             break;
+           }
+         
          /* Fall through.  */
        case HEADER_SUCCESS_EXTENDED:
          logical_status = status;
@@ -240,7 +261,10 @@ delete_archive_members (void)
          if (current_block == record_end)
            flush_archive ();
          status = read_header (false);
-
+         
+         if (extended_header.size)
+           xheader_decode (&current_stat_info);
+         
          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.  */
 
-         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.  */
 
-         write_recent_blocks (recent_long_name, recent_long_name_blocks);
-         write_recent_blocks (recent_long_link, recent_long_link_blocks);
+         if (extended_header.size)
+           {
+             write_recent_bytes (extended_header.buffer,
+                                 extended_header.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
This page took 0.023155 seconds and 4 git commands to generate.