浏览代码

dpkg: Unpack missing shared directories when the package is replaced

When unpacking a directory missing in the file system with that path
shared by at least one other package, from a package that is Replaced
by other packages, assume the missing path is a shared directory and
avoid setting ‘keepexisting’ and as such returning prematurely from
tarobject(), because in that case we need to recreate the lost
directory. As a side effect this also prevents printing the message
“Replaced by files in installed package” which is bogus in this case,
as directories are always shared.

Regression introduced in commit 00e5640a99be03aba40c9e08a663b90d8f8aa797.

Closes: #631808
Guillem Jover 15 年之前
父节点
当前提交
b6ca9bcdb5
共有 2 个文件被更改,包括 18 次插入10 次删除
  1. 2 0
      debian/changelog
  2. 16 10
      src/archives.c

+ 2 - 0
debian/changelog

@@ -113,6 +113,8 @@ dpkg (1.16.1) UNRELEASED; urgency=low
   * Run du with --apparent-size when generating the Installed-Size field in
   * Run du with --apparent-size when generating the Installed-Size field in
     dpkg-gencontrol to get consistent results independent of build system.
     dpkg-gencontrol to get consistent results independent of build system.
     Thanks to Ludovic Brenta <ludovic@ludovic-brenta.org>. Closes: #630533
     Thanks to Ludovic Brenta <ludovic@ludovic-brenta.org>. Closes: #630533
+  * Do not fail to unpack shared directories missing on the file system
+    from packages being replaced by other packages. Closes: #631808
 
 
   [ Bill Allombert]
   [ Bill Allombert]
   * Add support for Build-Features: build-arch. Closes: #229357
   * Add support for Build-Features: build-arch. Closes: #229357

+ 16 - 10
src/archives.c

@@ -583,6 +583,15 @@ tarobject(void *ctx, struct tar_entry *ti)
           continue;
           continue;
       }
       }
 
 
+      /* If the new object is a directory and the previous object does
+       * not exist assume it's also a directory and skip further checks.
+       * XXX: Ideally with more information about the installed files we
+       * could perform more clever checks. */
+      if (statr != 0 && ti->type == tar_filetype_dir) {
+        debug(dbg_eachfile, "tarobject ... assuming shared directory");
+        continue;
+      }
+
       /* Nope? Hmm, file conflict, perhaps. Check Replaces. */
       /* Nope? Hmm, file conflict, perhaps. Check Replaces. */
       switch (otherpkg->clientdata->replacingfilesandsaid) {
       switch (otherpkg->clientdata->replacingfilesandsaid) {
       case 2:
       case 2:
@@ -636,6 +645,7 @@ tarobject(void *ctx, struct tar_entry *ti)
         nifd->namenode->flags &= ~fnnf_new_inarchive;
         nifd->namenode->flags &= ~fnnf_new_inarchive;
         keepexisting = true;
         keepexisting = true;
       } else {
       } else {
+        /* At this point we are replacing something without a Replaces. */
         if (!statr && S_ISDIR(stab.st_mode)) {
         if (!statr && S_ISDIR(stab.st_mode)) {
           forcibleerr(fc_overwritedir,
           forcibleerr(fc_overwritedir,
                       _("trying to overwrite directory '%.250s' "
                       _("trying to overwrite directory '%.250s' "
@@ -644,16 +654,12 @@ tarobject(void *ctx, struct tar_entry *ti)
                       versiondescribe(&otherpkg->installed.version,
                       versiondescribe(&otherpkg->installed.version,
                                       vdew_nonambig));
                                       vdew_nonambig));
         } else {
         } else {
-          /* At this point we are replacing something without a Replaces.
-           * If the new object is a directory and the previous object does
-           * not exist assume it's also a directory and don't complain. */
-          if (!(statr && ti->type == tar_filetype_dir))
-            forcibleerr(fc_overwrite,
-                        _("trying to overwrite '%.250s', "
-                          "which is also in package %.250s %.250s"),
-                        nifd->namenode->name, otherpkg->name,
-                        versiondescribe(&otherpkg->installed.version,
-                                        vdew_nonambig));
+          forcibleerr(fc_overwrite,
+                      _("trying to overwrite '%.250s', "
+                        "which is also in package %.250s %.250s"),
+                      nifd->namenode->name, otherpkg->name,
+                      versiondescribe(&otherpkg->installed.version,
+                                      vdew_nonambig));
         }
         }
       }
       }
     }
     }