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 | ||
