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

dpkg: Activate all path components for file triggers

File triggers have been activated up to now explicitly whenever seen,
and only the requested pathname. While unpacking or removing, this is
not an issue as dpkg will traverse the hierarchy and trigger parent
directories during the process.

Because conffiles get a two staged installation, first unpacked into
<conffile>.dpkg-new and then installed in place on configure, a trigger
activated only after unpack will not see the <conffile> at its final
location or see it at all if it correctly ignores those file extensions.

This is an issue for conffiles or explicit dpkg-trigger file triggers,
as an interest on parent paths will not activate the trigger as those
parents are not traversed. With the subsequent cause of missed updates
because code has not been run on the actual installation of conffiles.

Closes: #675613, #676061, #676062, #676107, #676118, #676122
Guillem Jover лет назад: 14
Родитель
Сommit
2f19452e96
5 измененных файлов с 42 добавлено и 3 удалено
  1. 3 0
      debian/changelog
  2. 1 0
      lib/dpkg/libdpkg.map
  3. 35 1
      lib/dpkg/triglib.c
  4. 1 0
      lib/dpkg/triglib.h
  5. 2 2
      src/configure.c

+ 3 - 0
debian/changelog

@@ -61,6 +61,9 @@ dpkg (1.16.4) UNRELEASED; urgency=low
   * Add support for liblzma to handle .xz and .lzma compressed files, and
     switch to it instead of using xz-utils. This removes the xz-utils
     Pre-Depends from dpkg. Thanks to Jonathan Nieder <jrnieder@gmail.com>.
+  * Always activate all path components for file triggers, this fixes file
+    trigger handling for conffiles and dpkg-trigger invokations.
+    Closes: #675613, #676061, #676062, #676107, #676118, #676122
 
   [ Updated man page translations ]
   * German (Helge Kreutzmann).

+ 1 - 0
lib/dpkg/libdpkg.map

@@ -312,6 +312,7 @@ LIBDPKG_PRIVATE {
 	trig_override_hooks;
 	trig_file_activate_byname;
 	trig_file_activate;
+	trig_path_activate;
 	trig_note_pend;
 	trig_note_aw;
 	trig_clear_awaiters;

+ 35 - 1
lib/dpkg/triglib.c

@@ -553,6 +553,40 @@ trig_file_activate(struct filenamenode *trig, struct pkginfo *aw)
 		                       NULL : aw, trigh.namenode_name(trig));
 }
 
+static void
+trig_file_activate_parents(const char *trig, struct pkginfo *aw)
+{
+	char *path, *slash;
+
+	/* Traverse the whole pathname to activate all of its components. */
+	path = m_strdup(trig);
+
+	while ((slash = strrchr(path, '/'))) {
+		*slash = '\0';
+		trig_file_activate_byname(path, aw);
+	}
+
+	free(path);
+}
+
+void
+trig_path_activate(struct filenamenode *trig, struct pkginfo *aw)
+{
+	trig_file_activate(trig, aw);
+	trig_file_activate_parents(trigh.namenode_name(trig), aw);
+}
+
+static void
+trig_path_activate_byname(const char *trig, struct pkginfo *aw)
+{
+	struct filenamenode *fnn = trigh.namenode_find(trig, 1);
+
+	if (fnn)
+		trig_file_activate(fnn, aw);
+
+	trig_file_activate_parents(trig, aw);
+}
+
 static void
 trk_file_activate_start(void)
 {
@@ -561,7 +595,7 @@ trk_file_activate_start(void)
 static void
 trk_file_activate_awaiter(struct pkginfo *aw)
 {
-	trig_file_activate_byname(trig_activating_name, aw);
+	trig_path_activate_byname(trig_activating_name, aw);
 }
 
 static void

+ 1 - 0
lib/dpkg/triglib.h

@@ -86,6 +86,7 @@ void trig_override_hooks(const struct trig_hooks *hooks);
 
 void trig_file_activate_byname(const char *trig, struct pkginfo *aw);
 void trig_file_activate(struct filenamenode *trig, struct pkginfo *aw);
+void trig_path_activate(struct filenamenode *trig, struct pkginfo *aw);
 
 bool trig_note_pend_core(struct pkginfo *pend, const char *trig /*not copied!*/);
 bool trig_note_pend(struct pkginfo *pend, const char *trig /*not copied!*/);

+ 2 - 2
src/configure.c

@@ -193,7 +193,7 @@ deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
 		varbuf_add_str(&cdr, DPKGDISTEXT);
 		varbuf_end_str(&cdr);
 		strcpy(cdr2rest, DPKGNEWEXT);
-		trig_file_activate(usenode, pkg);
+		trig_path_activate(usenode, pkg);
 		if (rename(cdr2.buf, cdr.buf))
 			warning(_("%s: failed to rename '%.250s' to '%.250s': %s"),
 			        pkg_name(pkg, pnaw_nonambig), cdr2.buf, cdr.buf,
@@ -228,7 +228,7 @@ deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
 		       usenode->name);
 	case cfo_newconff:
 		strcpy(cdr2rest, DPKGNEWEXT);
-		trig_file_activate(usenode, pkg);
+		trig_path_activate(usenode, pkg);
 		if (rename(cdr2.buf, cdr.buf))
 			ohshite(_("unable to install `%.250s' as `%.250s'"),
 			        cdr2.buf, cdr.buf);