diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-26 21:53:37 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-11-26 21:53:37 +0000 |
commit | fea4b446df1b4d7c81804252ec7978092143f36e (patch) | |
tree | 1d6adcd3573f22185d4e256cb3acdeb14e5c1e65 | |
parent | 4ddddd180eaa7a1f4b2071c37425d99c3ef8040d (diff) | |
download | busybox-w32-fea4b446df1b4d7c81804252ec7978092143f36e.tar.gz busybox-w32-fea4b446df1b4d7c81804252ec7978092143f36e.tar.bz2 busybox-w32-fea4b446df1b4d7c81804252ec7978092143f36e.zip |
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.
-rw-r--r-- | archival/dpkg.c | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index eadc056eb..93f9f0673 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -27,11 +27,8 @@ | |||
27 | * consider important, its worth keeping a note of differences anyway, just to | 27 | * consider important, its worth keeping a note of differences anyway, just to |
28 | * make it easier to maintain. | 28 | * make it easier to maintain. |
29 | * - The first value for the Confflile: field isnt placed on a new line. | 29 | * - The first value for the Confflile: field isnt placed on a new line. |
30 | * - The <package>.control file is extracted and kept in the info dir. | ||
31 | * - When installing a package the Status: field is placed at the end of the | 30 | * - When installing a package the Status: field is placed at the end of the |
32 | * section, rather than just after the Package: field. | 31 | * section, rather than just after the Package: field. |
33 | * - Packages with previously unknown status are inserted at the begining of | ||
34 | * the status file | ||
35 | * | 32 | * |
36 | * Bugs that need to be fixed | 33 | * Bugs that need to be fixed |
37 | * - (unknown, please let me know when you find any) | 34 | * - (unknown, please let me know when you find any) |
@@ -1138,21 +1135,22 @@ int run_package_script(const char *package_name, const char *script_type) | |||
1138 | return(result); | 1135 | return(result); |
1139 | } | 1136 | } |
1140 | 1137 | ||
1138 | const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm", | ||
1139 | "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; | ||
1140 | |||
1141 | char **all_control_list(const char *package_name) | 1141 | char **all_control_list(const char *package_name) |
1142 | { | 1142 | { |
1143 | const char *extensions[11] = {"preinst", "postinst", "prerm", "postrm", | ||
1144 | "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; | ||
1145 | unsigned short i = 0; | 1143 | unsigned short i = 0; |
1146 | char **remove_files; | 1144 | char **remove_files; |
1147 | 1145 | ||
1148 | /* Create a list of all /var/lib/dpkg/info/<package> files */ | 1146 | /* Create a list of all /var/lib/dpkg/info/<package> files */ |
1149 | remove_files = malloc(sizeof(char *) * 11); | 1147 | remove_files = malloc(sizeof(all_control_files)); |
1150 | while (extensions[i]) { | 1148 | while (all_control_files[i]) { |
1151 | remove_files[i] = xmalloc(strlen(package_name) + strlen(extensions[i]) + 21); | 1149 | remove_files[i] = xmalloc(strlen(package_name) + strlen(all_control_files[i]) + 21); |
1152 | sprintf(remove_files[i], "/var/lib/dpkg/info/%s.%s", package_name, extensions[i]); | 1150 | sprintf(remove_files[i], "/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]); |
1153 | i++; | 1151 | i++; |
1154 | } | 1152 | } |
1155 | remove_files[10] = NULL; | 1153 | remove_files[sizeof(all_control_files)/sizeof(char*) - 1] = NULL; |
1156 | 1154 | ||
1157 | return(remove_files); | 1155 | return(remove_files); |
1158 | } | 1156 | } |
@@ -1211,9 +1209,10 @@ void list_packages(void) | |||
1211 | } | 1209 | } |
1212 | } | 1210 | } |
1213 | 1211 | ||
1214 | void remove_package(const unsigned int package_num) | 1212 | void remove_package(const unsigned int package_num, int noisy) |
1215 | { | 1213 | { |
1216 | const char *package_name = name_hashtable[package_hashtable[package_num]->name]; | 1214 | const char *package_name = name_hashtable[package_hashtable[package_num]->name]; |
1215 | const char *package_version = name_hashtable[package_hashtable[package_num]->version]; | ||
1217 | const unsigned int status_num = search_status_hashtable(package_name); | 1216 | const unsigned int status_num = search_status_hashtable(package_name); |
1218 | const int package_name_length = strlen(package_name); | 1217 | const int package_name_length = strlen(package_name); |
1219 | char **remove_files; | 1218 | char **remove_files; |
@@ -1222,7 +1221,8 @@ void remove_package(const unsigned int package_num) | |||
1222 | char conffile_name[package_name_length + 30]; | 1221 | char conffile_name[package_name_length + 30]; |
1223 | int return_value; | 1222 | int return_value; |
1224 | 1223 | ||
1225 | printf("Removing %s ...\n", package_name); | 1224 | if ( noisy ) |
1225 | printf("Removing %s (%s) ...\n", package_name, package_version); | ||
1226 | 1226 | ||
1227 | /* run prerm script */ | 1227 | /* run prerm script */ |
1228 | return_value = run_package_script(package_name, "prerm"); | 1228 | return_value = run_package_script(package_name, "prerm"); |
@@ -1267,11 +1267,14 @@ void remove_package(const unsigned int package_num) | |||
1267 | void purge_package(const unsigned int package_num) | 1267 | void purge_package(const unsigned int package_num) |
1268 | { | 1268 | { |
1269 | const char *package_name = name_hashtable[package_hashtable[package_num]->name]; | 1269 | const char *package_name = name_hashtable[package_hashtable[package_num]->name]; |
1270 | const char *package_version = name_hashtable[package_hashtable[package_num]->version]; | ||
1270 | const unsigned int status_num = search_status_hashtable(package_name); | 1271 | const unsigned int status_num = search_status_hashtable(package_name); |
1271 | char **remove_files; | 1272 | char **remove_files; |
1272 | char **exclude_files; | 1273 | char **exclude_files; |
1273 | char list_name[strlen(package_name) + 25]; | 1274 | char list_name[strlen(package_name) + 25]; |
1274 | 1275 | ||
1276 | printf("Purging %s (%s) ...\n", package_name, package_version); | ||
1277 | |||
1275 | /* run prerm script */ | 1278 | /* run prerm script */ |
1276 | if (run_package_script(package_name, "prerm") != 0) { | 1279 | if (run_package_script(package_name, "prerm") != 0) { |
1277 | bb_error_msg_and_die("script failed, prerm failure"); | 1280 | bb_error_msg_and_die("script failed, prerm failure"); |
@@ -1322,7 +1325,6 @@ static void init_archive_deb_control(archive_handle_t *ar_handle) | |||
1322 | 1325 | ||
1323 | /* Setup the tar archive handle */ | 1326 | /* Setup the tar archive handle */ |
1324 | tar_handle = init_handle(); | 1327 | tar_handle = init_handle(); |
1325 | tar_handle->filter = filter_accept_list; | ||
1326 | tar_handle->src_fd = ar_handle->src_fd; | 1328 | tar_handle->src_fd = ar_handle->src_fd; |
1327 | 1329 | ||
1328 | /* We dont care about data.tar.* or debian-binary, just control.tar.* */ | 1330 | /* We dont care about data.tar.* or debian-binary, just control.tar.* */ |
@@ -1345,15 +1347,14 @@ static void init_archive_deb_data(archive_handle_t *ar_handle) | |||
1345 | 1347 | ||
1346 | /* Setup the tar archive handle */ | 1348 | /* Setup the tar archive handle */ |
1347 | tar_handle = init_handle(); | 1349 | tar_handle = init_handle(); |
1348 | tar_handle->filter = filter_accept_all; | ||
1349 | tar_handle->src_fd = ar_handle->src_fd; | 1350 | tar_handle->src_fd = ar_handle->src_fd; |
1350 | 1351 | ||
1351 | /* We dont care about data.tar.* or debian-binary, just control.tar.* */ | 1352 | /* We dont care about control.tar.* or debian-binary, just data.tar.* */ |
1352 | #ifdef CONFIG_FEATURE_DEB_TAR_GZ | 1353 | #ifdef CONFIG_FEATURE_DEB_TAR_GZ |
1353 | tar_handle->accept = llist_add_to(NULL, "data.tar.gz"); | 1354 | ar_handle->accept = llist_add_to(NULL, "data.tar.gz"); |
1354 | #endif | 1355 | #endif |
1355 | #ifdef CONFIG_FEATURE_DEB_TAR_BZ2 | 1356 | #ifdef CONFIG_FEATURE_DEB_TAR_BZ2 |
1356 | tar_handle->accept = llist_add_to(ar_handle->accept, "data.tar.bz2"); | 1357 | ar_handle->accept = llist_add_to(ar_handle->accept, "data.tar.bz2"); |
1357 | #endif | 1358 | #endif |
1358 | 1359 | ||
1359 | /* Assign the tar handle as a subarchive of the ar handle */ | 1360 | /* Assign the tar handle as a subarchive of the ar handle */ |
@@ -1395,6 +1396,8 @@ static void unpack_package(deb_file_t *deb_file) | |||
1395 | char *info_prefix; | 1396 | char *info_prefix; |
1396 | archive_handle_t *archive_handle; | 1397 | archive_handle_t *archive_handle; |
1397 | FILE *out_stream; | 1398 | FILE *out_stream; |
1399 | llist_t *accept_list = NULL; | ||
1400 | int i = 0; | ||
1398 | 1401 | ||
1399 | /* If existing version, remove it first */ | 1402 | /* If existing version, remove it first */ |
1400 | if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { | 1403 | if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { |
@@ -1402,7 +1405,7 @@ static void unpack_package(deb_file_t *deb_file) | |||
1402 | printf("Preparing to replace %s %s (using %s) ...\n", package_name, | 1405 | printf("Preparing to replace %s %s (using %s) ...\n", package_name, |
1403 | name_hashtable[package_hashtable[status_package_num]->version], | 1406 | name_hashtable[package_hashtable[status_package_num]->version], |
1404 | deb_file->filename); | 1407 | deb_file->filename); |
1405 | remove_package(status_package_num); | 1408 | remove_package(status_package_num, 0); |
1406 | } else { | 1409 | } else { |
1407 | printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename); | 1410 | printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename); |
1408 | } | 1411 | } |
@@ -1412,8 +1415,18 @@ static void unpack_package(deb_file_t *deb_file) | |||
1412 | sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name); | 1415 | sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name); |
1413 | archive_handle = init_archive_deb_ar(deb_file->filename); | 1416 | archive_handle = init_archive_deb_ar(deb_file->filename); |
1414 | init_archive_deb_control(archive_handle); | 1417 | init_archive_deb_control(archive_handle); |
1418 | |||
1419 | while(all_control_files[i]) { | ||
1420 | char *c = (char *) xmalloc(3 + bb_strlen(all_control_files[i])); | ||
1421 | sprintf(c, "./%s", all_control_files[i]); | ||
1422 | accept_list= llist_add_to(accept_list, c); | ||
1423 | i++; | ||
1424 | } | ||
1425 | archive_handle->sub_archive->accept = accept_list; | ||
1426 | archive_handle->sub_archive->filter = filter_accept_list; | ||
1415 | archive_handle->sub_archive->action_data = data_extract_all_prefix; | 1427 | archive_handle->sub_archive->action_data = data_extract_all_prefix; |
1416 | archive_handle->sub_archive->buffer = info_prefix; | 1428 | archive_handle->sub_archive->buffer = info_prefix; |
1429 | archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; | ||
1417 | unpack_ar_archive(archive_handle); | 1430 | unpack_ar_archive(archive_handle); |
1418 | 1431 | ||
1419 | /* Run the preinst prior to extracting */ | 1432 | /* Run the preinst prior to extracting */ |
@@ -1425,16 +1438,19 @@ static void unpack_package(deb_file_t *deb_file) | |||
1425 | /* Extract data.tar.gz to the root directory */ | 1438 | /* Extract data.tar.gz to the root directory */ |
1426 | archive_handle = init_archive_deb_ar(deb_file->filename); | 1439 | archive_handle = init_archive_deb_ar(deb_file->filename); |
1427 | init_archive_deb_data(archive_handle); | 1440 | init_archive_deb_data(archive_handle); |
1441 | archive_handle->sub_archive->action_data = data_extract_all_prefix; | ||
1442 | archive_handle->sub_archive->buffer = "/"; | ||
1443 | archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; | ||
1428 | unpack_ar_archive(archive_handle); | 1444 | unpack_ar_archive(archive_handle); |
1429 | 1445 | ||
1430 | /* Create the list file */ | 1446 | /* Create the list file */ |
1431 | strcat(info_prefix, "list"); | 1447 | strcat(info_prefix, "list"); |
1432 | out_stream = bb_xfopen(info_prefix, "w"); | 1448 | out_stream = bb_xfopen(info_prefix, "w"); |
1433 | while (archive_handle->passed) { | 1449 | while (archive_handle->sub_archive->passed) { |
1434 | /* blindly skip over the leading '.' */ | 1450 | /* the leading . has been stripped by data_extract_all_prefix already */ |
1435 | fputs(archive_handle->passed->data + 1, out_stream); | 1451 | fputs(archive_handle->sub_archive->passed->data, out_stream); |
1436 | fputc('\n', out_stream); | 1452 | fputc('\n', out_stream); |
1437 | archive_handle->passed = archive_handle->passed->link; | 1453 | archive_handle->sub_archive->passed = archive_handle->sub_archive->passed->link; |
1438 | } | 1454 | } |
1439 | fclose(out_stream); | 1455 | fclose(out_stream); |
1440 | 1456 | ||
@@ -1451,7 +1467,7 @@ void configure_package(deb_file_t *deb_file) | |||
1451 | const char *package_version = name_hashtable[package_hashtable[deb_file->package]->version]; | 1467 | const char *package_version = name_hashtable[package_hashtable[deb_file->package]->version]; |
1452 | const int status_num = search_status_hashtable(package_name); | 1468 | const int status_num = search_status_hashtable(package_name); |
1453 | 1469 | ||
1454 | printf("Setting up %s (%s)\n", package_name, package_version); | 1470 | printf("Setting up %s (%s) ...\n", package_name, package_version); |
1455 | 1471 | ||
1456 | /* Run the postinst script */ | 1472 | /* Run the postinst script */ |
1457 | if (run_package_script(package_name, "postinst") != 0) { | 1473 | if (run_package_script(package_name, "postinst") != 0) { |
@@ -1562,7 +1578,7 @@ int dpkg_main(int argc, char **argv) | |||
1562 | status_node->status = search_name_hashtable("want-install reinstreq not-installed"); | 1578 | status_node->status = search_name_hashtable("want-install reinstreq not-installed"); |
1563 | status_hashtable[status_num] = status_node; | 1579 | status_hashtable[status_num] = status_node; |
1564 | } else { | 1580 | } else { |
1565 | status_hashtable[status_num]->status = search_name_hashtable("want-install reinstreq not-installed"); | 1581 | status_hashtable[status_num]->status = search_name_hashtable("want-install reinstreq installed"); |
1566 | } | 1582 | } |
1567 | } | 1583 | } |
1568 | } | 1584 | } |
@@ -1604,10 +1620,11 @@ int dpkg_main(int argc, char **argv) | |||
1604 | } | 1620 | } |
1605 | } | 1621 | } |
1606 | 1622 | ||
1623 | /* TODO: install or remove packages in the correct dependency order */ | ||
1607 | for (i = 0; i < deb_count; i++) { | 1624 | for (i = 0; i < deb_count; i++) { |
1608 | /* Remove or purge packages */ | 1625 | /* Remove or purge packages */ |
1609 | if (dpkg_opt & dpkg_opt_remove) { | 1626 | if (dpkg_opt & dpkg_opt_remove) { |
1610 | remove_package(deb_file[i]->package); | 1627 | remove_package(deb_file[i]->package, 1); |
1611 | } | 1628 | } |
1612 | else if (dpkg_opt & dpkg_opt_purge) { | 1629 | else if (dpkg_opt & dpkg_opt_purge) { |
1613 | purge_package(deb_file[i]->package); | 1630 | purge_package(deb_file[i]->package); |
@@ -1617,12 +1634,17 @@ int dpkg_main(int argc, char **argv) | |||
1617 | } | 1634 | } |
1618 | else if (dpkg_opt & dpkg_opt_install) { | 1635 | else if (dpkg_opt & dpkg_opt_install) { |
1619 | unpack_package(deb_file[i]); | 1636 | unpack_package(deb_file[i]); |
1620 | configure_package(deb_file[i]); | 1637 | /* package is configured in second pass below */ |
1621 | } | 1638 | } |
1622 | else if (dpkg_opt & dpkg_opt_configure) { | 1639 | else if (dpkg_opt & dpkg_opt_configure) { |
1623 | configure_package(deb_file[i]); | 1640 | configure_package(deb_file[i]); |
1624 | } | 1641 | } |
1625 | } | 1642 | } |
1643 | /* configure installed packages */ | ||
1644 | if (dpkg_opt & dpkg_opt_install) { | ||
1645 | for (i = 0; i < deb_count; i++) | ||
1646 | configure_package(deb_file[i]); | ||
1647 | } | ||
1626 | 1648 | ||
1627 | write_status_file(deb_file); | 1649 | write_status_file(deb_file); |
1628 | 1650 | ||