[PATCH] no config file overwrite for dpkg

Kim B. Heino Kim.Heino at bluegiga.com
Mon Feb 22 08:47:36 UTC 2010


This patch adds new option for dpkg:

  By default dpkg will overwrite existing config files when
  upgrading. With this feature enabled new config files will be
  created as filename.dpkg-new.

This version is using the preferred "if (ENABLE_xxx)" style.


Signed-off-by: Kim B. Heino <Kim.Heino at bluegiga.com>


diff -ur orig-1.16.0/archival/Config.in busybox-1.16.0/archival/Config.in
--- orig-1.16.0/archival/Config.in	2010-01-25 02:59:38.000000000 +0200
+++ busybox-1.16.0/archival/Config.in	2010-02-18 17:59:54.274564790 +0200
@@ -128,6 +128,15 @@
 	  This implementation of dpkg has a number of limitations,
 	  you should use the official dpkg if possible.
 
+config FEATURE_DPKG_NO_CONFIG_OVERWRITE
+	bool "Don't overwrite existing config files"
+	default n
+	depends on DPKG
+	help
+	  By default dpkg will overwrite existing config files when
+	  upgrading. With this feature enabled new config files will be
+	  created as filename.dpkg-new.
+
 config DPKG_DEB
 	bool "dpkg_deb"
 	default n
diff -ur orig-1.16.0/archival/dpkg.c busybox-1.16.0/archival/dpkg.c
--- orig-1.16.0/archival/dpkg.c	2010-01-25 02:59:38.000000000 +0200
+++ busybox-1.16.0/archival/dpkg.c	2010-02-19 15:56:35.175814529 +0200
@@ -1489,6 +1489,21 @@
 	return ar_handle->dpkg__sub_archive->dpkg__buffer;
 }
 
+static char FAST_FUNC filter_rename_config(archive_handle_t *archive_handle)
+{
+	if (ENABLE_FEATURE_DPKG_NO_CONFIG_OVERWRITE) {
+		struct stat dummystat;
+		char *name_ptr = archive_handle->file_header->name + 1;
+
+		if (find_list_entry(archive_handle->accept, name_ptr) &&
+		    stat(name_ptr, &dummystat) == 0) {
+			printf("Warning: Creating %s as %s.dpkg-new\n", name_ptr, name_ptr);
+			archive_handle->file_header->name = xasprintf("%s.dpkg-new", archive_handle->file_header->name);
+		}
+	}
+	return EXIT_SUCCESS;
+}
+
 static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle)
 {
 	char *name_ptr = archive_handle->file_header->name;
@@ -1508,6 +1523,9 @@
 	if (name_ptr[0] != '\0') {
 		archive_handle->file_header->name = xasprintf("%s%s", archive_handle->dpkg__buffer, name_ptr);
 		data_extract_all(archive_handle);
+		if (ENABLE_FEATURE_DPKG_NO_CONFIG_OVERWRITE &&
+		    fnmatch("*.dpkg-new", archive_handle->file_header->name, 0) == 0)
+			archive_handle->file_header->name[strlen(archive_handle->file_header->name) - 9] = 0;
 	}
 }
 
@@ -1522,6 +1540,9 @@
 	FILE *out_stream;
 	llist_t *accept_list;
 	int i;
+	llist_t *conffile_list;
+	FILE *conffile_file;
+	char *conffile_name, *conffile_line;
 
 	/* If existing version, remove it first */
 	if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
@@ -1556,9 +1577,23 @@
 	/* Run the preinst prior to extracting */
 	run_package_script_or_die(package_name, "preinst");
 
+	/* Don't overwrite existing config files */
+	conffile_list = NULL;
+	if (ENABLE_FEATURE_DPKG_NO_CONFIG_OVERWRITE) {
+		conffile_name = xasprintf("/var/lib/dpkg/info/%s.conffiles", package_name);
+		if ((conffile_file = fopen_for_read(conffile_name)) != NULL) {
+			while ((conffile_line = xmalloc_fgetline(conffile_file)) != NULL)
+				llist_add_to(&conffile_list, conffile_line);
+			fclose(conffile_file);
+		}
+		free(conffile_name);
+	}
+
 	/* Extract data.tar.gz to the root directory */
 	archive_handle = init_archive_deb_ar(deb_file->filename);
 	init_archive_deb_data(archive_handle);
+	archive_handle->dpkg__sub_archive->accept = conffile_list;
+	archive_handle->dpkg__sub_archive->filter = filter_rename_config;
 	archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix;
 	archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */
 	archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD;


More information about the busybox mailing list