Ver código fonte

dpkg: Fix hard link extraction for normal files due to deferred rename

When creating hard links on extraction use the .dpkg-new filename
for source as the normal file is not yet in place due to the rename
deferral.

We avoid doing this for hard links to special files (which do not
have the fnnf_deferred_rename flag) because they are already in
place. Although this should not always pose a problem because not
all tar creation implementations support hard links for non-normal
files, but at least FreeBSD libarchive based ones support them for
fifos, so better be safe than sorry.

Based-on-patch-by: Colin Watson <cjwatson@ubuntu.com>
Guillem Jover 16 anos atrás
pai
commit
8ccebf62ea
2 arquivos alterados com 9 adições e 1 exclusões
  1. 3 0
      debian/changelog
  2. 6 1
      src/archives.c

+ 3 - 0
debian/changelog

@@ -36,6 +36,9 @@ dpkg (1.15.6.2) UNRELEASED; urgency=low
   [ Guillem Jover ]
   [ Guillem Jover ]
   * Report deferred trigger errors on status-fd. Closes: #574599
   * Report deferred trigger errors on status-fd. Closes: #574599
     Thanks to Michael Vogt <michael.vogt@ubuntu.com>.
     Thanks to Michael Vogt <michael.vogt@ubuntu.com>.
+  * When creating hard links to normal files on extraction use the .dpkg-new
+    filename for source as the file is not yet in place due to the rename
+    deferral. Thanks to Colin Watson for the initial patch.
 
 
   [ Updated dpkg translations ]
   [ Updated dpkg translations ]
   * German (Sven Joachim).
   * German (Sven Joachim).

+ 6 - 1
src/archives.c

@@ -393,6 +393,7 @@ int tarobject(struct TarInfo *ti) {
   static int fd;
   static int fd;
   const char *usename;
   const char *usename;
   struct filenamenode *usenode;
   struct filenamenode *usenode;
+  struct filenamenode *linknode;
 
 
   struct conffile *conff;
   struct conffile *conff;
   struct tarcontext *tc= (struct tarcontext*)ti->UserData;
   struct tarcontext *tc= (struct tarcontext*)ti->UserData;
@@ -691,7 +692,11 @@ int tarobject(struct TarInfo *ti) {
   case HardLink:
   case HardLink:
     varbufreset(&hardlinkfn);
     varbufreset(&hardlinkfn);
     varbufaddstr(&hardlinkfn,instdir); varbufaddc(&hardlinkfn,'/');
     varbufaddstr(&hardlinkfn,instdir); varbufaddc(&hardlinkfn,'/');
-    varbufaddstr(&hardlinkfn,ti->LinkName); varbufaddc(&hardlinkfn,0);
+    varbufaddstr(&hardlinkfn, ti->LinkName);
+    linknode = findnamenode(ti->LinkName, 0);
+    if (linknode->flags & fnnf_deferred_rename)
+      varbufaddstr(&hardlinkfn, DPKGNEWEXT);
+    varbufaddc(&hardlinkfn, '\0');
     if (link(hardlinkfn.buf,fnamenewvb.buf))
     if (link(hardlinkfn.buf,fnamenewvb.buf))
       ohshite(_("error creating hard link `%.255s'"),ti->Name);
       ohshite(_("error creating hard link `%.255s'"),ti->Name);
     debug(dbg_eachfiledetail,"tarobject HardLink");
     debug(dbg_eachfiledetail,"tarobject HardLink");