aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim B. Heino <Kim.Heino@bluegiga.com>2010-03-29 14:18:27 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-29 14:18:27 +0200
commit3d43aed10c94bfcfc4a85b9b66bc60c18d22c2b1 (patch)
treefbd69052583642b77e9436ec6fc11a1461042afb
parent1d448cff653a9a68f6320d01c9f0505385aa38bd (diff)
downloadbusybox-w32-3d43aed10c94bfcfc4a85b9b66bc60c18d22c2b1.tar.gz
busybox-w32-3d43aed10c94bfcfc4a85b9b66bc60c18d22c2b1.tar.bz2
busybox-w32-3d43aed10c94bfcfc4a85b9b66bc60c18d22c2b1.zip
dpkg: support config file overwrite options
function old new delta filter_rename_config - 244 +244 static.dpkg_longopts - 112 +112 dpkg_main 3901 3980 +79 unpack_package 515 587 +72 append_control_file_to_llist - 72 +72 data_extract_all_prefix 88 116 +28 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 3/0 up/down: 607/0) Total: 607 bytes Signed-off-by: Kim B. Heino <Kim.Heino@bluegiga.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--archival/dpkg.c126
-rw-r--r--include/usage.h17
2 files changed, 127 insertions, 16 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 7187ad6a0..befb91d6a 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1308,7 +1308,7 @@ static void list_packages(const char *pattern)
1308 name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name]; 1308 name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name];
1309 vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version]; 1309 vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version];
1310 1310
1311 if (pattern && fnmatch(pattern, name_str, 0)) 1311 if (pattern && fnmatch(pattern, name_str, 0) != 0)
1312 continue; 1312 continue;
1313 1313
1314 /* get abbreviation for status field 1 */ 1314 /* get abbreviation for status field 1 */
@@ -1491,6 +1491,58 @@ static char *deb_extract_control_file_to_buffer(archive_handle_t *ar_handle, lli
1491 return ar_handle->dpkg__sub_archive->dpkg__buffer; 1491 return ar_handle->dpkg__sub_archive->dpkg__buffer;
1492} 1492}
1493 1493
1494static void append_control_file_to_llist(const char *package_name, const char *control_name, llist_t **ll)
1495{
1496 FILE *fp;
1497 char *filename, *line;
1498
1499 filename = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, control_name);
1500 fp = fopen_for_read(filename);
1501 free(filename);
1502 if (fp != NULL) {
1503 while ((line = xmalloc_fgetline(fp)) != NULL)
1504 llist_add_to(ll, line);
1505 fclose(fp);
1506 }
1507}
1508
1509static char FAST_FUNC filter_rename_config(archive_handle_t *archive_handle)
1510{
1511 int fd;
1512 char *name_ptr = archive_handle->file_header->name + 1;
1513
1514 /* Is this file marked as config file? */
1515 if (!find_list_entry(archive_handle->accept, name_ptr))
1516 return EXIT_SUCCESS; /* no */
1517
1518 fd = open(name_ptr, O_RDONLY);
1519 if (fd >= 0) {
1520 md5_ctx_t md5;
1521 char *md5line, *buf;
1522 int count;
1523
1524 /* Calculate MD5 of existing file */
1525 buf = xmalloc(4096);
1526 md5_begin(&md5);
1527 while ((count = safe_read(fd, buf, 4096)) > 0)
1528 md5_hash(buf, count, &md5);
1529 md5_end(buf, &md5); /* using buf as result storage */
1530 close(fd);
1531
1532 md5line = xmalloc(16 * 2 + 2 + strlen(name_ptr) + 1);
1533 sprintf(bin2hex(md5line, buf, 16), " %s", name_ptr);
1534 free(buf);
1535
1536 /* Is it changed after install? */
1537 if (find_list_entry(archive_handle->accept, md5line) == NULL) {
1538 printf("Warning: Creating %s as %s.dpkg-new\n", name_ptr, name_ptr);
1539 archive_handle->file_header->name = xasprintf("%s.dpkg-new", archive_handle->file_header->name);
1540 }
1541 free(md5line);
1542 }
1543 return EXIT_SUCCESS;
1544}
1545
1494static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle) 1546static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle)
1495{ 1547{
1496 char *name_ptr = archive_handle->file_header->name; 1548 char *name_ptr = archive_handle->file_header->name;
@@ -1500,7 +1552,7 @@ static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle)
1500 name_ptr++; 1552 name_ptr++;
1501 /* Skip all leading "./" and "../" */ 1553 /* Skip all leading "./" and "../" */
1502 while (name_ptr[0] == '.') { 1554 while (name_ptr[0] == '.') {
1503 if (name_ptr[1] == '.' && name_ptr[2] == '/') 1555 if (name_ptr[1] == '.')
1504 name_ptr++; 1556 name_ptr++;
1505 if (name_ptr[1] != '/') 1557 if (name_ptr[1] != '/')
1506 break; 1558 break;
@@ -1510,9 +1562,26 @@ static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle)
1510 if (name_ptr[0] != '\0') { 1562 if (name_ptr[0] != '\0') {
1511 archive_handle->file_header->name = xasprintf("%s%s", archive_handle->dpkg__buffer, name_ptr); 1563 archive_handle->file_header->name = xasprintf("%s%s", archive_handle->dpkg__buffer, name_ptr);
1512 data_extract_all(archive_handle); 1564 data_extract_all(archive_handle);
1565 if (fnmatch("*.dpkg-new", archive_handle->file_header->name, 0) == 0) {
1566 /* remove .dpkg-new suffix */
1567 archive_handle->file_header->name[strlen(archive_handle->file_header->name) - 9] = '\0';
1568 }
1513 } 1569 }
1514} 1570}
1515 1571
1572enum {
1573 OPT_configure = (1 << 0),
1574 OPT_force = (1 << 1),
1575 OPT_install = (1 << 2),
1576 OPT_list_installed = (1 << 3),
1577 OPT_purge = (1 << 4),
1578 OPT_remove = (1 << 5),
1579 OPT_unpack = (1 << 6),
1580 OPT_force_ignore_depends = (1 << 7),
1581 OPT_force_confnew = (1 << 8),
1582 OPT_force_confold = (1 << 9),
1583};
1584
1516static void unpack_package(deb_file_t *deb_file) 1585static void unpack_package(deb_file_t *deb_file)
1517{ 1586{
1518 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; 1587 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
@@ -1523,14 +1592,21 @@ static void unpack_package(deb_file_t *deb_file)
1523 archive_handle_t *archive_handle; 1592 archive_handle_t *archive_handle;
1524 FILE *out_stream; 1593 FILE *out_stream;
1525 llist_t *accept_list; 1594 llist_t *accept_list;
1595 llist_t *conffile_list;
1526 int i; 1596 int i;
1527 1597
1528 /* If existing version, remove it first */ 1598 /* If existing version, remove it first */
1599 conffile_list = NULL;
1529 if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { 1600 if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
1530 /* Package is already installed, remove old version first */ 1601 /* Package is already installed, remove old version first */
1531 printf("Preparing to replace %s %s (using %s)...\n", package_name, 1602 printf("Preparing to replace %s %s (using %s)...\n", package_name,
1532 name_hashtable[package_hashtable[status_package_num]->version], 1603 name_hashtable[package_hashtable[status_package_num]->version],
1533 deb_file->filename); 1604 deb_file->filename);
1605
1606 /* Read md5sums from old package */
1607 if (!(option_mask32 & OPT_force_confold))
1608 append_control_file_to_llist(package_name, "md5sums", &conffile_list);
1609
1534 remove_package(status_package_num, 0); 1610 remove_package(status_package_num, 0);
1535 } else { 1611 } else {
1536 printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename); 1612 printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename);
@@ -1558,9 +1634,15 @@ static void unpack_package(deb_file_t *deb_file)
1558 /* Run the preinst prior to extracting */ 1634 /* Run the preinst prior to extracting */
1559 run_package_script_or_die(package_name, "preinst"); 1635 run_package_script_or_die(package_name, "preinst");
1560 1636
1637 /* Don't overwrite existing config files */
1638 if (!(option_mask32 & OPT_force_confnew))
1639 append_control_file_to_llist(package_name, "conffiles", &conffile_list);
1640
1561 /* Extract data.tar.gz to the root directory */ 1641 /* Extract data.tar.gz to the root directory */
1562 archive_handle = init_archive_deb_ar(deb_file->filename); 1642 archive_handle = init_archive_deb_ar(deb_file->filename);
1563 init_archive_deb_data(archive_handle); 1643 init_archive_deb_data(archive_handle);
1644 archive_handle->dpkg__sub_archive->accept = conffile_list;
1645 archive_handle->dpkg__sub_archive->filter = filter_rename_config;
1564 archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix; 1646 archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix;
1565 archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */ 1647 archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */
1566 archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD; 1648 archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD;
@@ -1614,23 +1696,37 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
1614 int state_status; 1696 int state_status;
1615 int status_num; 1697 int status_num;
1616 int i; 1698 int i;
1617 enum { 1699#if ENABLE_LONG_OPTS
1618 OPT_configure = 0x1, 1700 static const char dpkg_longopts[] ALIGN1 =
1619 OPT_force_ignore_depends = 0x2, 1701// FIXME: we use -C non-compatibly, should be:
1620 OPT_install = 0x4, 1702// "-C|--audit Check for broken package(s)"
1621 OPT_list_installed = 0x8, 1703 "configure\0" No_argument "C"
1622 OPT_purge = 0x10, 1704 "force\0" Required_argument "F"
1623 OPT_remove = 0x20, 1705 "install\0" No_argument "i"
1624 OPT_unpack = 0x40, 1706 "list\0" No_argument "l"
1625 }; 1707 "purge\0" No_argument "P"
1708 "remove\0" No_argument "r"
1709 "unpack\0" No_argument "u"
1710 "force-depends\0" No_argument "\xff"
1711 "force-confnew\0" No_argument "\xfe"
1712 "force-confold\0" No_argument "\xfd"
1713 ;
1714#endif
1626 1715
1627 INIT_G(); 1716 INIT_G();
1628 1717
1718 IF_LONG_OPTS(applet_long_options = dpkg_longopts);
1629 opt = getopt32(argv, "CF:ilPru", &str_f); 1719 opt = getopt32(argv, "CF:ilPru", &str_f);
1630 //if (opt & OPT_configure) ... // -C 1720 //if (opt & OPT_configure) ... // -C
1631 if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg) 1721 if (opt & OPT_force) { // -F (--force in official dpkg)
1632 if (strcmp(str_f, "depends")) 1722 if (strcmp(str_f, "depends") == 0)
1633 opt &= ~OPT_force_ignore_depends; 1723 opt |= OPT_force_ignore_depends;
1724 else if (strcmp(str_f, "confnew") == 0)
1725 opt |= OPT_force_confnew;
1726 else if (strcmp(str_f, "confold") == 0)
1727 opt |= OPT_force_confold;
1728 else bb_show_usage();
1729 option_mask32 = opt;
1634 } 1730 }
1635 //if (opt & OPT_install) ... // -i 1731 //if (opt & OPT_install) ... // -i
1636 //if (opt & OPT_list_installed) ... // -l 1732 //if (opt & OPT_list_installed) ... // -l
@@ -1639,7 +1735,7 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
1639 //if (opt & OPT_unpack) ... // -u (--unpack in official dpkg) 1735 //if (opt & OPT_unpack) ... // -u (--unpack in official dpkg)
1640 argv += optind; 1736 argv += optind;
1641 /* check for non-option argument if expected */ 1737 /* check for non-option argument if expected */
1642 if (!opt || (!argv[0] && !(opt && OPT_list_installed))) 1738 if (!opt || (!argv[0] && !(opt & OPT_list_installed)))
1643 bb_show_usage(); 1739 bb_show_usage();
1644 1740
1645/* puts("(Reading database ... xxxxx files and directories installed.)"); */ 1741/* puts("(Reading database ... xxxxx files and directories installed.)"); */
diff --git a/include/usage.h b/include/usage.h
index 8b026b43a..cf576c666 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -931,13 +931,28 @@
931#define dpkg_full_usage "\n\n" \ 931#define dpkg_full_usage "\n\n" \
932 "Install, remove and manage Debian packages\n" \ 932 "Install, remove and manage Debian packages\n" \
933 "\nOptions:" \ 933 "\nOptions:" \
934 IF_LONG_OPTS( \
935 "\n -i,--install Install the package" \
936 "\n -l,--list List of installed packages" \
937 "\n --configure Configure an unpackaged package" \
938 "\n -P,--purge Purge all files of a package" \
939 "\n -r,--remove Remove all but the configuration files for a package" \
940 "\n --unpack Unpack a package, but don't configure it" \
941 "\n --force-depends Ignore dependency problems" \
942 "\n --force-confnew Overwrite existing config files when installing" \
943 "\n --force-confold Keep old config files when installing" \
944 ) \
945 IF_NOT_LONG_OPTS( \
934 "\n -i Install the package" \ 946 "\n -i Install the package" \
935 "\n -l List of installed packages" \ 947 "\n -l List of installed packages" \
936 "\n -C Configure an unpackaged package" \ 948 "\n -C Configure an unpackaged package" \
937 "\n -F depends Ignore dependency problems" \
938 "\n -P Purge all files of a package" \ 949 "\n -P Purge all files of a package" \
939 "\n -r Remove all but the configuration files for a package" \ 950 "\n -r Remove all but the configuration files for a package" \
940 "\n -u Unpack a package, but don't configure it" \ 951 "\n -u Unpack a package, but don't configure it" \
952 "\n -F depends Ignore dependency problems" \
953 "\n -F confnew Overwrite existing config files when installing" \
954 "\n -F confold Keep old config files when installing" \
955 )
941 956
942#define dpkg_deb_trivial_usage \ 957#define dpkg_deb_trivial_usage \
943 "[-cefxX] FILE [argument]" 958 "[-cefxX] FILE [argument]"