Explorar o código

Don't drop directories that contain our conffiles too early from
our file listing. Otherwise we might leave them behind on purge
if we share them with other packages.
Closes: #174180, #198128, #198522, #318825, #366178

Frank Lichtenheld %!s(int64=20) %!d(string=hai) anos
pai
achega
e0bea5706d
Modificáronse 5 ficheiros con 43 adicións e 1 borrados
  1. 9 0
      ChangeLog
  2. 4 0
      debian/changelog
  3. 20 0
      src/help.c
  4. 1 0
      src/main.h
  5. 9 1
      src/remove.c

+ 9 - 0
ChangeLog

@@ -16,6 +16,15 @@
 
 
 2006-05-19  Frank Lichtenheld  <djpig@debian.org>
 2006-05-19  Frank Lichtenheld  <djpig@debian.org>
 
 
+	* src/help.c (hasdirectoryconffiles): New function
+	to test wether a directory contains conffiles of
+	a given package.
+	* src/main.h: Add declaration of hasdirectoryconffiles.
+	* src/remove.c (removal_bulk_remove_files): Don't
+	drop directories from our file list that hold
+	our conffiles.
+	(removal_bulk_remove_leftover_dirs) Likewise.
+
 	* utils/enoent.c: Add a comment at the top of the
 	* utils/enoent.c: Add a comment at the top of the
 	file explaining why we use this odd program at all.
 	file explaining why we use this odd program at all.
 
 

+ 4 - 0
debian/changelog

@@ -42,6 +42,10 @@ dpkg (1.13.20~) UNRELEASED; urgency=low
   * When building packages with dpkg-deb give a more useful error
   * When building packages with dpkg-deb give a more useful error
     message in case a conffile entry has leading whitespace. Patch
     message in case a conffile entry has leading whitespace. Patch
     by David Lopez Moreno. Closes: #281562
     by David Lopez Moreno. Closes: #281562
+  * Don't drop directories that contain our conffiles too early from
+    our file listing. Otherwise we might leave them behind on purge
+    if we share them with other packages.
+    Closes: #174180, #198128, #198522, #318825, #366178
   
   
   [ Nicolas François ]
   [ Nicolas François ]
   * fix typos in the Russian man pages. Thanks to Stepan Golosunov.
   * fix typos in the Russian man pages. Thanks to Stepan Golosunov.

+ 20 - 0
src/help.c

@@ -403,6 +403,26 @@ void debug(int which, const char *fmt, ...) {
   putc('\n',stderr);
   putc('\n',stderr);
 }
 }
 
 
+int hasdirectoryconffiles(struct filenamenode *file, struct pkginfo *pkg) {
+  /* Returns 1 if the directory contains conffiles belonging to pkg, 0 otherwise. */
+  struct conffile *conff;
+  size_t namelen;
+
+  debug(dbg_veryverbose, "hasdirectoryconffiles `%s' (from %s)", file->name,
+	pkg->name);
+  namelen = strlen(file->name);
+  for (conff= pkg->installed.conffiles; conff; conff= conff->next) {
+      if (!strncmp(file->name,conff->name,namelen)) {
+	debug(dbg_veryverbose, "directory %s has conffile %s from %s",
+	      file->name, conff->name, pkg->name);
+	return 1;
+      }
+  }
+  debug(dbg_veryverbose, "hasdirectoryconffiles no");
+  return 0;
+}
+
+
 int isdirectoryinuse(struct filenamenode *file, struct pkginfo *pkg) {
 int isdirectoryinuse(struct filenamenode *file, struct pkginfo *pkg) {
   /* Returns 1 if the file is used by packages other than pkg, 0 otherwise. */
   /* Returns 1 if the file is used by packages other than pkg, 0 otherwise. */
   struct filepackages *packageslump;
   struct filepackages *packageslump;

+ 1 - 0
src/main.h

@@ -203,6 +203,7 @@ int maintainer_script_alternative(struct pkginfo *pkg,
                                   const char *ifok, const char *iffallback);
                                   const char *ifok, const char *iffallback);
 void clear_istobes(void);
 void clear_istobes(void);
 int isdirectoryinuse(struct filenamenode *namenode, struct pkginfo *pkg);
 int isdirectoryinuse(struct filenamenode *namenode, struct pkginfo *pkg);
+int hasdirectoryconffiles(struct filenamenode *namenode, struct pkginfo *pkg);
 
 
 enum debugflags {
 enum debugflags {
   dbg_general=           00001,
   dbg_general=           00001,

+ 9 - 1
src/remove.c

@@ -240,7 +240,11 @@ static void removal_bulk_remove_files(
          * package which uses it.  Other files should only be listed
          * package which uses it.  Other files should only be listed
          * in this package (but we don't check).
          * in this package (but we don't check).
          */
          */
-        if (isdirectoryinuse(namenode,pkg)) continue;
+	if (hasdirectoryconffiles(namenode,pkg)) {
+	  push_leftover(&leftover,namenode);
+	  continue;
+	}
+	if (isdirectoryinuse(namenode,pkg)) continue;
       }
       }
       debug(dbg_eachfiledetail, "removal_bulk removing `%s'", fnvb.buf);
       debug(dbg_eachfiledetail, "removal_bulk removing `%s'", fnvb.buf);
       if (!rmdir(fnvb.buf) || errno == ENOENT || errno == ELOOP) continue;
       if (!rmdir(fnvb.buf) || errno == ENOENT || errno == ELOOP) continue;
@@ -350,6 +354,10 @@ static void removal_bulk_remove_leftover_dirs(struct pkginfo *pkg) {
        * package which uses it.  Other files should only be listed
        * package which uses it.  Other files should only be listed
        * in this package (but we don't check).
        * in this package (but we don't check).
        */
        */
+      if (hasdirectoryconffiles(namenode,pkg)) {
+	push_leftover(&leftover,namenode);
+	continue;
+      }
       if (isdirectoryinuse(namenode,pkg)) continue;
       if (isdirectoryinuse(namenode,pkg)) continue;
     }
     }