Procházet zdrojové kódy

dpkg: properly remove triggers information during package removal

Before this change, a package removal would not remove the triggers
information from the internal files. When you reinstalled the same
package without any trigger, dpkg would improperly believe that
the package implemented some triggers.

However the triggers were correctly unregistered during a package
upgrade that dropped the triggers.

With this commit, we also remove triggers interest file that are empty and
thus no longer needed.
Raphaël Hertzog před 15 roky
rodič
revize
83b591340e
3 změnil soubory, kde provedl 30 přidání a 1 odebrání
  1. 2 0
      debian/changelog
  2. 24 1
      lib/dpkg/triglib.c
  3. 4 0
      src/remove.c

+ 2 - 0
debian/changelog

@@ -17,6 +17,8 @@ dpkg (1.16.1) UNRELEASED; urgency=low
   * Do not fail when encountering a pre-dependency in triggers-awaited state,
     instead process the awaited triggers. Closes: #526774
   * "any" no longer hides "all" in the Architecture field of a .dsc.
+  * Fix dpkg --remove to really remove the triggers from the various
+    internal files in /var/lib/dpkg/info/triggers/. Closes: #525160
 
   [ Guillem Jover ]
   * Install deb-src-control(5) man pages in dpkg-dev. Closes: #620520

+ 24 - 1
lib/dpkg/triglib.c

@@ -409,6 +409,7 @@ trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg, int signum)
 	static struct varbuf newfn;
 	char buf[1024];
 	FILE *nf;
+	bool empty = true;
 
 	trk_explicit_start(trig);
 	varbuf_reset(&newfn);
@@ -424,9 +425,23 @@ trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg, int signum)
 		if (!strcmp(buf, pkg->name))
 			continue;
 		fprintf(nf, "%s\n", buf);
+		empty = false;
 	}
-	if (signum > 0)
+	if (signum > 0) {
 		fprintf(nf, "%s\n", pkg->name);
+		empty = false;
+	}
+
+	if (empty) {
+		/* The triggers interest file is no longer needed, drop it */
+		fclose(nf); /* We don't care if it fails */
+		if (unlink(newfn.buf))
+			ohshite(_("cannot remove `%.250s'"), newfn.buf);
+		if (unlink(trk_explicit_fn.buf))
+			ohshite(_("cannot remove `%.250s'"), trk_explicit_fn.buf);
+		dir_sync_path(triggersdir);
+		return;
+	}
 
 	if (ferror(nf))
 		ohshite(_("unable to write new trigger interest file `%.250s'"),
@@ -529,6 +544,14 @@ trig_file_interests_save(void)
 	if (filetriggers_edited <= 0)
 		return;
 
+	if (!filetriggers.head) {
+		/* No file trigger left, drop the file */
+		if (unlink(triggersfilefile) && errno != ENOENT)
+			ohshite(_("cannot remove `%.250s'"), triggersfilefile);
+		dir_sync_path(triggersdir);
+		return;
+	}
+
 	nf = fopen(triggersnewfilefile, "w");
 	if (!nf)
 		ohshite(_("unable to create new file triggers file `%.250s'"),

+ 4 - 0
src/remove.c

@@ -292,6 +292,10 @@ removal_bulk_remove_files(struct pkginfo *pkg)
     maintainer_script_installed(pkg, POSTRMFILE, "post-removal",
                                 "remove", NULL);
 
+    trig_parse_ci(pkgadminfile(pkg, TRIGGERSCIFILE),
+                  trig_cicb_interest_delete, NULL, pkg);
+    trig_file_interests_save();
+
     debug(dbg_general, "removal_bulk cleaning info directory");
     pkg_infodb_foreach(pkg, removal_bulk_remove_file);
     dir_sync_path(pkgadmindir());