Package: dpkg
Severity: normal
Tags: patch

When a conffile (e.g. /etc/ldap/ldap.conf) is diverted, and one upgrades the package containing the conffile, dpkg sometimes fails to copy the .dpkg-new file onto the diverted conffile location. The cause is that it uses the diverted location when unpacking files, but the non-diverted location when comparing the user's and maintainer's changes.

A transcript you can use to reproduce the problem is below (the version of libldap2.deb being installed has had its conffile modified and version bumped).

While I realize that using dpkg-divert on conffiles is an uncommon practice, the current behavior is clearly wrong.

I've attached a simple git patch against current head that fixes this.

Thanks,

        -Tim Abbott

mega-man:~# dpkg-divert --list | grep ldap
diversion of /etc/ldap/ldap.conf to /etc/ldap/ldap.conf.debathena-orig by 
debathena-ldap-config

mega-man:~# ls /etc/ldap/
ldap.conf  ldap.conf.debathena  ldap.conf.debathena-orig

mega-man:~# dpkg -D200 -i libldap2.deb
(Reading database ... 323858 files and directories currently installed.)
Preparing to replace libldap2 2.1.30-13.3 (using x.deb) ...
D000200: process_archive conffile `/etc/ldap/ldap.conf' in package libldap2 - conff ?
D000200: oldconffsetflags `/etc/ldap/ldap.conf' namenode 0x88dc304 flags 5
Unpacking replacement libldap2 ...
D000200: conffderef in=`etc/ldap/ldap.conf.debathena-orig' current working=`/etc/ldap/ldap.conf.debathena-orig'
D000200: tarobject conffile extracted
Replaced by files in installed package libldap-2.3-0 ...
Setting up libldap2 (2.1.30-13.3tabbott) ...
D000200: conffderef in=`/etc/ldap/ldap.conf' current working=`/etc/ldap/ldap.conf'
D000200: conffderef symlink loopprotect=0
D000200: conffderef readlink realloc(255)=0x829b040
D000200: conffderef readlink gave 19, `ldap.conf.debathena'
D000200: conffderef readlink relative to `/etc/ldap/'
D000200: conffderef in=`/etc/ldap/ldap.conf' current working=`/etc/ldap/ldap.conf.debathena'

mega-man:~# ls /etc/ldap/
ldap.conf  ldap.conf.debathena  ldap.conf.debathena-orig  
ldap.conf.debathena-orig.dpkg-new
commit 790a35bd65c0449bd8d60dae5053f97ab75c3ab5
Author: Timothy G Abbott <[EMAIL PROTECTED]>
Date:   Sat Apr 19 22:26:11 2008 -0400

    Don't leave new conffiles as .dpkg-new versions when the conffile has been diverted.
    
    * src/configure.c: (deferred_configure) Compare the diverted versions of conffiles.

diff --git a/src/configure.c b/src/configure.c
index cde2c68..e67f57e 100644
--- a/src/configure.c
+++ b/src/configure.c
@@ -85,6 +85,7 @@ void deferred_configure(struct pkginfo *pkg) {
 	struct stat stab;
 	enum conffopt what;
 	static const char *EMPTY_HASH = "-";
+	const char *usename;
 
 	if (pkg->status == stat_notinstalled)
 		ohshit(_("no package named `%s' is installed, cannot configure"),pkg->name);
@@ -173,7 +174,8 @@ void deferred_configure(struct pkginfo *pkg) {
 		varbufinit(&cdr);
 		varbufinit(&cdr2);
 		for (conff= pkg->installed.conffiles; conff; conff= conff->next) {
-			r= conffderef(pkg, &cdr, conff->name);
+			usename = namenodetouse(findnamenode(conff->name,fnn_nocopy),pkg)->name;
+			r= conffderef(pkg, &cdr, usename);
 			if (r == -1) {
 				conff->hash= EMPTY_HASH;
 				continue;
@@ -209,7 +211,7 @@ void deferred_configure(struct pkginfo *pkg) {
 				what= cfo_identical;
 			} else if (!strcmp(currenthash,NONEXISTENTFLAG) && fc_conff_miss) {
 				fprintf(stderr, _("\nConfiguration file `%s', does not exist on system.\n"
-							"Installing new config file as you request.\n"), conff->name);
+							"Installing new config file as you request.\n"), usename);
 				what= cfo_newconff;
 				useredited= -1;
 				distedited= -1;
@@ -233,9 +235,9 @@ void deferred_configure(struct pkginfo *pkg) {
 
 			debug(dbg_conff,
 					"deferred_configure `%s' (= `%s') useredited=%d distedited=%d what=%o",
-					conff->name, cdr.buf, useredited, distedited, what);
+					usename, cdr.buf, useredited, distedited, what);
 
-			what=promptconfaction(conff->name, cdr.buf, cdr2.buf, useredited, distedited, what);
+			what=promptconfaction(usename, cdr.buf, cdr2.buf, useredited, distedited, what);
 
 			switch (what & ~(cfof_isnew|cfof_userrmd)) {
 				case cfo_keep | cfof_backup:
@@ -281,7 +283,7 @@ void deferred_configure(struct pkginfo *pkg) {
 								pkg->name, cdr.buf, cdr2.buf, strerror(errno));
 					/* fall through */
 				case cfo_install:
-					printf(_("Installing new version of config file %s ...\n"),conff->name);
+					printf(_("Installing new version of config file %s ...\n"),usename);
 				case cfo_newconff:
 					strcpy(cdr2rest,DPKGNEWEXT);
 					trig_file_activate_byname(conff->name, pkg);

Reply via email to