Browse Source

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 20 years ago
parent
commit
e0bea5706d
5 changed files with 43 additions and 1 deletions
  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>
 
+	* 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
 	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
     message in case a conffile entry has leading whitespace. Patch
     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 ]
   * 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);
 }
 
+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) {
   /* Returns 1 if the file is used by packages other than pkg, 0 otherwise. */
   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);
 void clear_istobes(void);
 int isdirectoryinuse(struct filenamenode *namenode, struct pkginfo *pkg);
+int hasdirectoryconffiles(struct filenamenode *namenode, struct pkginfo *pkg);
 
 enum debugflags {
   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
          * 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);
       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
        * in this package (but we don't check).
        */
+      if (hasdirectoryconffiles(namenode,pkg)) {
+	push_leftover(&leftover,namenode);
+	continue;
+      }
       if (isdirectoryinuse(namenode,pkg)) continue;
     }