]> Dogcows Code - chaz/tar/blobdiff - src/create.c
Fix hard links recognition with -c --remove-files
[chaz/tar] / src / create.c
index f54e346f777c4828002ac6e24a103d50415312b1..1031cc2be928c7f44019db1243dce16208d93616 100644 (file)
@@ -1041,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
   while (size_left > 0)
     {
       size_t bufsize, count;
-
+      
       mv_size_left (size_left);
 
       blk = find_next_block ();
@@ -1066,8 +1066,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
          return dump_status_short;
        }
       size_left -= count;
-      if (count)
-       set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
+      set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
 
       if (count != bufsize)
        {
@@ -1081,7 +1080,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
                 STRINGIFY_BIGINT (size_left, buf)));
          if (! ignore_failed_read_option) 
            exit_status = TAREXIT_DIFFERS;
-         pad_archive (size_left - (bufsize-count));
+         pad_archive (size_left - (bufsize - count));
          return dump_status_short;
        }
     }
@@ -1378,7 +1377,7 @@ static Hash_table *link_table;
 static bool
 dump_hard_link (struct tar_stat_info *st)
 {
-  if (link_table && st->stat.st_nlink > 1)
+  if (link_table && (st->stat.st_nlink > 1 || remove_files_option))
     {
       struct link lp;
       struct link *duplicate;
@@ -1423,22 +1422,31 @@ dump_hard_link (struct tar_stat_info *st)
 static void
 file_count_links (struct tar_stat_info *st)
 {
+  if (hard_dereference_option)
+    return;
   if (st->stat.st_nlink > 1)
     {
       struct link *duplicate;
-      struct link *lp = xmalloc (offsetof (struct link, name)
-                                + strlen (st->orig_file_name) + 1);
+      char *linkname = NULL;
+      struct link *lp;
+
+      assign_string (&linkname, st->orig_file_name);
+      transform_name (&linkname, XFORM_LINK);
+      
+      lp = xmalloc (offsetof (struct link, name)
+                                + strlen (linkname) + 1);
       lp->ino = st->stat.st_ino;
       lp->dev = st->stat.st_dev;
       lp->nlink = st->stat.st_nlink;
-      strcpy (lp->name, st->orig_file_name);
-
+      strcpy (lp->name, linkname);
+      free (linkname);
+      
       if (! ((link_table
              || (link_table = hash_initialize (0, 0, hash_link,
                                                compare_links, 0)))
             && (duplicate = hash_insert (link_table, lp))))
        xalloc_die ();
-
+      
       if (duplicate != lp)
        abort ();
       lp->nlink--;
@@ -1460,7 +1468,7 @@ check_links (void)
     {
       if (lp->nlink)
        {
-         WARN ((0, 0, _("Missing links to %s.\n"), quote (lp->name)));
+         WARN ((0, 0, _("Missing links to %s."), quote (lp->name)));
        }
     }
 }
@@ -1494,7 +1502,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
   assign_string (&st->file_name,
                  safer_name_suffix (p, false, absolute_names_option));
 
-  transform_name (&st->file_name);
+  transform_name (&st->file_name, XFORM_REGFILE);
 
   if (deref_stat (dereference_option, p, &st->stat) != 0)
     {
@@ -1615,6 +1623,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
            case dump_status_ok:
            case dump_status_short:
              mv_end ();
+             file_count_links (st);
              break;
 
            case dump_status_fail:
@@ -1624,8 +1633,6 @@ dump_file0 (struct tar_stat_info *st, const char *p,
              abort ();
            }
 
-         file_count_links (st);
-
          ok = status == dump_status_ok;
        }
 
@@ -1705,6 +1712,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
        }
       buffer[size] = '\0';
       assign_string (&st->link_name, buffer);
+      transform_name (&st->link_name, XFORM_SYMLINK);
       if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
        write_long_link (st);
 
@@ -1713,7 +1721,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
       header = start_header (st);
       if (!header)
        return;
-      tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
+      tar_copy_str (header->header.linkname, st->link_name, NAME_FIELD_SIZE);
       header->header.typeflag = SYMTYPE;
       finish_header (st, header, block_ordinal);
       /* nothing more to do to it */
This page took 0.026339 seconds and 4 git commands to generate.