[BusyBox-cvs] busybox/archival dpkg.c,1.73,1.74

Glenn McGrath bug1 at busybox.net
Wed Nov 26 21:53:42 UTC 2003


Update of /var/cvs/busybox/archival
In directory winder:/tmp/cvs-serv10780/archival

Modified Files:
	dpkg.c 
Log Message:
Important bugfixes from Ian Campbell.
init_archive_deb_data()
        We want to filter for data.tar.* in the AR file not the TAR
        file, else we get nothing.

all_control_list()
        Make the 'extensions' array of control file names a global so it
        can be used in unpack_package as well. Name the global
        all_control_files. Don't hard code the length of
        all_control_files but instead used sizeof.

unpack_package()
        Only unpack the control files we are interested in (from
        all_control_files). Extract the data.tar.gz into / rather than
        the current directory.

dpkg_main()
        Configure packages in a second pass so all the packages being
        installed are unpacked before configuring. 

Some purely cosmetic changes:

header
        update list of differences since two of them are no longer true.
        The .control file is no longer stored as a result of this patch
        -- it was redundant since the info is in status. New packages
        appear to be added to the end of the status file now rather than
        the start.

remove_package()
        Make message printing optional, so we can avoid a redundant
        message when replacing/upgrading a package. When we do print
        stuff then include the version number.

purge_package()
        Print "Purging xxx (yyy) ..." message like the other actions.

configure_package()
        Add "..." to "Setting up" message to be consistent with other
        actions.


Index: dpkg.c
===================================================================
RCS file: /var/cvs/busybox/archival/dpkg.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- dpkg.c	15 Sep 2003 08:06:15 -0000	1.73
+++ dpkg.c	26 Nov 2003 21:53:37 -0000	1.74
@@ -27,11 +27,8 @@
  * consider important, its worth keeping a note of differences anyway, just to
  * make it easier to maintain.
  *  - The first value for the Confflile: field isnt placed on a new line.
- *  - The <package>.control file is extracted and kept in the info dir.
  *  - When installing a package the Status: field is placed at the end of the
  *      section, rather than just after the Package: field.
- *  - Packages with previously unknown status are inserted at the begining of
- *      the status file
  *
  * Bugs that need to be fixed
  *  - (unknown, please let me know when you find any)
@@ -1138,21 +1135,22 @@
 	return(result);
 }
 
+const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm",
+	"list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL };
+
 char **all_control_list(const char *package_name)
 {
-	const char *extensions[11] = {"preinst", "postinst", "prerm", "postrm",
-		"list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL };
 	unsigned short i = 0;
 	char **remove_files;
 
 	/* Create a list of all /var/lib/dpkg/info/<package> files */
-	remove_files = malloc(sizeof(char *) * 11);
-	while (extensions[i]) {
-		remove_files[i] = xmalloc(strlen(package_name) + strlen(extensions[i]) + 21);
-		sprintf(remove_files[i], "/var/lib/dpkg/info/%s.%s", package_name, extensions[i]);
+	remove_files = malloc(sizeof(all_control_files));
+	while (all_control_files[i]) {
+		remove_files[i] = xmalloc(strlen(package_name) + strlen(all_control_files[i]) + 21);
+		sprintf(remove_files[i], "/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
 		i++;
 	}
-	remove_files[10] = NULL;
+	remove_files[sizeof(all_control_files)/sizeof(char*) - 1] = NULL;
 
 	return(remove_files);
 }
@@ -1211,9 +1209,10 @@
     }
 }
 
-void remove_package(const unsigned int package_num)
+void remove_package(const unsigned int package_num, int noisy)
 {
 	const char *package_name = name_hashtable[package_hashtable[package_num]->name];
+	const char *package_version = name_hashtable[package_hashtable[package_num]->version];
 	const unsigned int status_num = search_status_hashtable(package_name);
 	const int package_name_length = strlen(package_name);
 	char **remove_files;
@@ -1222,7 +1221,8 @@
 	char conffile_name[package_name_length + 30];
 	int return_value;
 
-	printf("Removing %s ...\n", package_name);
+	if ( noisy ) 
+		printf("Removing %s (%s) ...\n", package_name, package_version);
 
 	/* run prerm script */
 	return_value = run_package_script(package_name, "prerm");
@@ -1267,11 +1267,14 @@
 void purge_package(const unsigned int package_num)
 {
 	const char *package_name = name_hashtable[package_hashtable[package_num]->name];
+	const char *package_version = name_hashtable[package_hashtable[package_num]->version];
 	const unsigned int status_num = search_status_hashtable(package_name);
 	char **remove_files;
 	char **exclude_files;
 	char list_name[strlen(package_name) + 25];
 
+	printf("Purging %s (%s) ...\n", package_name, package_version);
+
 	/* run prerm script */
 	if (run_package_script(package_name, "prerm") != 0) {
 		bb_error_msg_and_die("script failed, prerm failure");
@@ -1322,7 +1325,6 @@
 
 	/* Setup the tar archive handle */
 	tar_handle = init_handle();
-	tar_handle->filter = filter_accept_list;
 	tar_handle->src_fd = ar_handle->src_fd;
 
 	/* We dont care about data.tar.* or debian-binary, just control.tar.* */
@@ -1345,15 +1347,14 @@
 
 	/* Setup the tar archive handle */
 	tar_handle = init_handle();
-	tar_handle->filter = filter_accept_all;
 	tar_handle->src_fd = ar_handle->src_fd;
 
-	/* We dont care about data.tar.* or debian-binary, just control.tar.* */
+	/* We dont care about control.tar.* or debian-binary, just data.tar.* */
 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
-	tar_handle->accept = llist_add_to(NULL, "data.tar.gz");
+	ar_handle->accept = llist_add_to(NULL, "data.tar.gz");
 #endif
 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
-	tar_handle->accept = llist_add_to(ar_handle->accept, "data.tar.bz2");
+	ar_handle->accept = llist_add_to(ar_handle->accept, "data.tar.bz2");
 #endif
 
 	/* Assign the tar handle as a subarchive of the ar handle */
@@ -1395,6 +1396,8 @@
 	char *info_prefix;
 	archive_handle_t *archive_handle;
 	FILE *out_stream;
+	llist_t *accept_list = NULL;
+	int i = 0;
 
 	/* If existing version, remove it first */
 	if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
@@ -1402,7 +1405,7 @@
 		printf("Preparing to replace %s %s (using %s) ...\n", package_name,
 			name_hashtable[package_hashtable[status_package_num]->version],
 			deb_file->filename);
-		remove_package(status_package_num);
+		remove_package(status_package_num, 0);
 	} else {
 		printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename);
 	}
@@ -1412,8 +1415,18 @@
 	sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name);
 	archive_handle = init_archive_deb_ar(deb_file->filename);
 	init_archive_deb_control(archive_handle);
+
+	while(all_control_files[i]) {
+		char *c = (char *) xmalloc(3 + bb_strlen(all_control_files[i]));
+		sprintf(c, "./%s", all_control_files[i]);
+		accept_list= llist_add_to(accept_list, c);
+		i++;
+	}
+	archive_handle->sub_archive->accept = accept_list;
+	archive_handle->sub_archive->filter = filter_accept_list;
 	archive_handle->sub_archive->action_data = data_extract_all_prefix;
 	archive_handle->sub_archive->buffer = info_prefix;
+	archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
 	unpack_ar_archive(archive_handle);
 
 	/* Run the preinst prior to extracting */
@@ -1425,16 +1438,19 @@
 	/* 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->sub_archive->action_data = data_extract_all_prefix;
+	archive_handle->sub_archive->buffer = "/";
+	archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
 	unpack_ar_archive(archive_handle);
 
 	/* Create the list file */
 	strcat(info_prefix, "list");
 	out_stream = bb_xfopen(info_prefix, "w");			
-	while (archive_handle->passed) {
-		/* blindly skip over the leading '.' */
-		fputs(archive_handle->passed->data + 1, out_stream);
+	while (archive_handle->sub_archive->passed) {
+		/* the leading . has been stripped by data_extract_all_prefix already */
+		fputs(archive_handle->sub_archive->passed->data, out_stream);
 		fputc('\n', out_stream);
-		archive_handle->passed = archive_handle->passed->link;
+		archive_handle->sub_archive->passed = archive_handle->sub_archive->passed->link;
 	}
 	fclose(out_stream);
 
@@ -1451,7 +1467,7 @@
 	const char *package_version = name_hashtable[package_hashtable[deb_file->package]->version];
 	const int status_num = search_status_hashtable(package_name);
 
-	printf("Setting up %s (%s)\n", package_name, package_version);
+	printf("Setting up %s (%s) ...\n", package_name, package_version);
 
 	/* Run the postinst script */
 	if (run_package_script(package_name, "postinst") != 0) {
@@ -1562,7 +1578,7 @@
 					status_node->status = search_name_hashtable("want-install reinstreq not-installed");
 					status_hashtable[status_num] = status_node;
 				} else {
-					status_hashtable[status_num]->status = search_name_hashtable("want-install reinstreq not-installed");
+					status_hashtable[status_num]->status = search_name_hashtable("want-install reinstreq installed");
 				}
 			}
 		}
@@ -1604,10 +1620,11 @@
 		}
 	}
 
+	/* TODO: install or remove packages in the correct dependency order */
 	for (i = 0; i < deb_count; i++) {
 		/* Remove or purge packages */
 		if (dpkg_opt & dpkg_opt_remove) {
-			remove_package(deb_file[i]->package);
+			remove_package(deb_file[i]->package, 1);
 		}
 		else if (dpkg_opt & dpkg_opt_purge) {
 			purge_package(deb_file[i]->package);
@@ -1617,12 +1634,17 @@
 		}
 		else if (dpkg_opt & dpkg_opt_install) {
 			unpack_package(deb_file[i]);
-			configure_package(deb_file[i]);
+			/* package is configured in second pass below */
 		}
 		else if (dpkg_opt & dpkg_opt_configure) {
 			configure_package(deb_file[i]);
 		}
 	}
+	/* configure installed packages */
+	if (dpkg_opt & dpkg_opt_install) {
+		for (i = 0; i < deb_count; i++)
+			configure_package(deb_file[i]);
+	}
 
 	write_status_file(deb_file);
 




More information about the busybox-cvs mailing list