diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-09-21 04:30:51 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-09-21 04:30:51 +0000 |
commit | e73866181f553067cae3411608f3cf1677d63a8b (patch) | |
tree | 10e6b46b81fcd28039f16c8b8ba2cf3956f56ad7 | |
parent | 4c67c596d1aa3aafde0bc8182e9a5d54ee67a05f (diff) | |
download | busybox-e73866181f553067cae3411608f3cf1677d63a8b.tar.gz |
Implement dpkg -l option, from Stefan Soucek (slightly modified)
-rw-r--r-- | archival/dpkg.c | 57 | ||||
-rw-r--r-- | dpkg.c | 57 |
2 files changed, 106 insertions, 8 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index d7279cfd0..e58052d8b 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -1127,6 +1127,48 @@ void all_control_list(char **remove_files, const char *package_name) remove_files[10] = NULL; } + +/* This function lists information on the installed packages. It loops through + * the status_hashtable to retrieve the info. This results in smaller code than + * scanning the status file. The resulting list, however, is unsorted. + */ +void list_packages(void) +{ + int i; + + printf(" Name Version\n"); + printf("+++-==============-==============\n"); + + /* go through status hash, dereference package hash and finally strings */ + for (i=0; i<STATUS_HASH_PRIME+1; i++) { + + if (status_hashtable[i]) { + const char *stat_str; /* status string */ + const char *name_str; /* package name */ + const char *vers_str; /* version */ + char s1, s2; /* status abbreviations */ + int spccnt; /* space count */ + int j; + + stat_str = name_hashtable[status_hashtable[i]->status]; + name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name]; + vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version]; + + /* get abbreviation for status field 1 */ + s1 = stat_str[0] == 'i' ? 'i' : 'r'; + + /* get abbreviation for status field 2 */ + for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) { + if (stat_str[j] == ' ') spccnt++; + } + s2 = stat_str[j]; + + /* print out the line formatted like Debian dpkg */ + printf("%c%c %-14s %s\n", s1, s2, name_str, vers_str); + } + } +} + void remove_package(const unsigned int package_num) { const char *package_name = name_hashtable[package_hashtable[package_num]->name]; @@ -1304,6 +1346,7 @@ extern int dpkg_main(int argc, char **argv) break; case 'l': dpkg_opt |= dpkg_opt_list_installed; + break; case 'P': dpkg_opt |= dpkg_opt_purge; dpkg_opt |= dpkg_opt_package_name; @@ -1320,14 +1363,20 @@ extern int dpkg_main(int argc, char **argv) show_usage(); } } - - if ((argc == optind) || (dpkg_opt == 0)) { + /* check for non-otion argument if expected */ + if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) { show_usage(); - } + } - puts("(Reading database ... xxxxx files and directories installed.)"); +/* puts("(Reading database ... xxxxx files and directories installed.)"); */ index_status_file("/var/lib/dpkg/status"); + /* if the list action was given print the installed packages and exit */ + if (dpkg_opt & dpkg_opt_list_installed) { + list_packages(); + return(EXIT_SUCCESS); + } + /* Read arguments and store relevant info in structs */ deb_file = xmalloc(sizeof(deb_file_t)); while (optind < argc) { @@ -1127,6 +1127,48 @@ void all_control_list(char **remove_files, const char *package_name) remove_files[10] = NULL; } + +/* This function lists information on the installed packages. It loops through + * the status_hashtable to retrieve the info. This results in smaller code than + * scanning the status file. The resulting list, however, is unsorted. + */ +void list_packages(void) +{ + int i; + + printf(" Name Version\n"); + printf("+++-==============-==============\n"); + + /* go through status hash, dereference package hash and finally strings */ + for (i=0; i<STATUS_HASH_PRIME+1; i++) { + + if (status_hashtable[i]) { + const char *stat_str; /* status string */ + const char *name_str; /* package name */ + const char *vers_str; /* version */ + char s1, s2; /* status abbreviations */ + int spccnt; /* space count */ + int j; + + stat_str = name_hashtable[status_hashtable[i]->status]; + name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name]; + vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version]; + + /* get abbreviation for status field 1 */ + s1 = stat_str[0] == 'i' ? 'i' : 'r'; + + /* get abbreviation for status field 2 */ + for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) { + if (stat_str[j] == ' ') spccnt++; + } + s2 = stat_str[j]; + + /* print out the line formatted like Debian dpkg */ + printf("%c%c %-14s %s\n", s1, s2, name_str, vers_str); + } + } +} + void remove_package(const unsigned int package_num) { const char *package_name = name_hashtable[package_hashtable[package_num]->name]; @@ -1304,6 +1346,7 @@ extern int dpkg_main(int argc, char **argv) break; case 'l': dpkg_opt |= dpkg_opt_list_installed; + break; case 'P': dpkg_opt |= dpkg_opt_purge; dpkg_opt |= dpkg_opt_package_name; @@ -1320,14 +1363,20 @@ extern int dpkg_main(int argc, char **argv) show_usage(); } } - - if ((argc == optind) || (dpkg_opt == 0)) { + /* check for non-otion argument if expected */ + if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) { show_usage(); - } + } - puts("(Reading database ... xxxxx files and directories installed.)"); +/* puts("(Reading database ... xxxxx files and directories installed.)"); */ index_status_file("/var/lib/dpkg/status"); + /* if the list action was given print the installed packages and exit */ + if (dpkg_opt & dpkg_opt_list_installed) { + list_packages(); + return(EXIT_SUCCESS); + } + /* Read arguments and store relevant info in structs */ deb_file = xmalloc(sizeof(deb_file_t)); while (optind < argc) { |