Просмотр исходного кода

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
Родитель
Сommit
8ccebf62ea
2 измененных файлов с 9 добавлено и 1 удалено
  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 ]
   * Report deferred trigger errors on status-fd. Closes: #574599
     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 ]
   * German (Sven Joachim).

+ 6 - 1
src/archives.c

@@ -393,6 +393,7 @@ int tarobject(struct TarInfo *ti) {
   static int fd;
   const char *usename;
   struct filenamenode *usenode;
+  struct filenamenode *linknode;
 
   struct conffile *conff;
   struct tarcontext *tc= (struct tarcontext*)ti->UserData;
@@ -691,7 +692,11 @@ int tarobject(struct TarInfo *ti) {
   case HardLink:
     varbufreset(&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))
       ohshite(_("error creating hard link `%.255s'"),ti->Name);
     debug(dbg_eachfiledetail,"tarobject HardLink");