summaryrefslogtreecommitdiff
path: root/src/querycmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/querycmd.c')
-rw-r--r--src/querycmd.c344
1 files changed, 178 insertions, 166 deletions
diff --git a/src/querycmd.c b/src/querycmd.c
index 127f0c883..eba5e53ef 100644
--- a/src/querycmd.c
+++ b/src/querycmd.c
@@ -27,7 +27,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/ioctl.h>
#if HAVE_LOCALE_H
#include <locale.h>
@@ -38,7 +37,6 @@
#include <fcntl.h>
#include <dirent.h>
#include <fnmatch.h>
-#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -53,48 +51,17 @@
#include <dpkg/string.h>
#include <dpkg/path.h>
#include <dpkg/file.h>
+#include <dpkg/pager.h>
#include <dpkg/options.h>
+#include <dpkg/db-ctrl.h>
+#include <dpkg/db-fsys.h>
-#include "filesdb.h"
-#include "infodb.h"
#include "main.h"
static const char *showformat = "${binary:Package}\t${Version}\n";
static int opt_loadavail = 0;
-static int getwidth(void) {
- int fd;
- long res;
- struct winsize ws;
- const char *columns;
- char *endptr;
-
- columns = getenv("COLUMNS");
- if (columns) {
- errno = 0;
- res = strtol(columns, &endptr, 10);
- if (errno == 0 && columns != endptr && *endptr == '\0' &&
- res > 0 && res < INT_MAX)
- return res;
- }
-
- if (!isatty(1))
- return -1;
- else {
- res = 80;
-
- fd = open("/dev/tty", O_RDONLY);
- if (fd != -1) {
- if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
- res = ws.ws_col;
- close(fd);
- }
-
- return res;
- }
-}
-
static int
pkg_array_match_patterns(struct pkg_array *array,
pkg_array_visitor_func *pkg_visitor, void *pkg_data,
@@ -155,56 +122,36 @@ struct list_format {
static void
list_format_init(struct list_format *fmt, struct pkg_array *array)
{
- int w;
+ int i;
if (fmt->nw != 0)
return;
- w = getwidth();
- if (w == -1) {
- int i;
-
- fmt->nw = 14;
- fmt->vw = 12;
- fmt->aw = 12;
- fmt->dw = 33;
-
- for (i = 0; i < array->n_pkgs; i++) {
- int plen, vlen, alen, dlen;
-
- if (array->pkgs[i] == NULL)
- continue;
+ fmt->nw = 14;
+ fmt->vw = 12;
+ fmt->aw = 12;
+ fmt->dw = 33;
- plen = str_width(pkg_name(array->pkgs[i], pnaw_nonambig));
- vlen = str_width(versiondescribe(&array->pkgs[i]->installed.version,
- vdew_nonambig));
- alen = str_width(dpkg_arch_describe(array->pkgs[i]->installed.arch));
- pkgbin_summary(array->pkgs[i], &array->pkgs[i]->installed, &dlen);
-
- if (plen > fmt->nw)
- fmt->nw = plen;
- if (vlen > fmt->vw)
- fmt->vw = vlen;
- if (alen > fmt->aw)
- fmt->aw = alen;
- if (dlen > fmt->dw)
- fmt->dw = dlen;
- }
- } else {
- w -= 80;
- /* Let's not try to deal with terminals that are too small. */
- if (w < 0)
- w = 0;
- /* Halve that so we can add it to both the name and description. */
- w >>= 1;
- /* Name width. */
- fmt->nw = (14 + (w / 2));
- /* Version width. */
- fmt->vw = (12 + (w / 4));
- /* Architecture width. */
- fmt->aw = (12 + (w / 4));
- /* Description width. */
- fmt->dw = (33 + w);
+ for (i = 0; i < array->n_pkgs; i++) {
+ int plen, vlen, alen, dlen;
+
+ if (array->pkgs[i] == NULL)
+ continue;
+
+ plen = str_width(pkg_name(array->pkgs[i], pnaw_nonambig));
+ vlen = str_width(versiondescribe(&array->pkgs[i]->installed.version,
+ vdew_nonambig));
+ alen = str_width(dpkg_arch_describe(array->pkgs[i]->installed.arch));
+ pkg_synopsis(array->pkgs[i], &dlen);
+
+ if (plen > fmt->nw)
+ fmt->nw = plen;
+ if (vlen > fmt->vw)
+ fmt->vw = vlen;
+ if (alen > fmt->aw)
+ fmt->aw = alen;
+ if (dlen > fmt->dw)
+ fmt->dw = dlen;
}
}
@@ -285,7 +232,7 @@ pkg_array_list_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data
list_format_init(fmt, array);
list_format_print_header(fmt);
- pdesc = pkgbin_summary(pkg, &pkg->installed, &l);
+ pdesc = pkg_synopsis(pkg, &l);
l = min(l, fmt->dw);
list_format_print(fmt,
@@ -306,17 +253,20 @@ listpackages(const char *const *argv)
int i;
int rc = 0;
struct list_format fmt;
+ struct pager *pager;
if (!opt_loadavail)
modstatdb_open(msdbrw_readonly);
else
modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
- pkg_array_init_from_db(&array);
+ pkg_array_init_from_hash(&array);
pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
memset(&fmt, 0, sizeof(fmt));
+ pager = pager_spawn(_("showing package list on pager"));
+
if (!*argv) {
for (i = 0; i < array.n_pkgs; i++) {
pkg = array.pkgs[i];
@@ -332,14 +282,18 @@ listpackages(const char *const *argv)
m_output(stdout, _("<standard output>"));
m_output(stderr, _("<standard error>"));
+ pager_reap(pager);
+
pkg_array_destroy(&array);
modstatdb_shutdown();
return rc;
}
-static int searchoutput(struct filenamenode *namenode) {
- struct filepackages_iterator *iter;
+static int
+searchoutput(struct fsys_namenode *namenode)
+{
+ struct fsys_node_pkgs_iter *iter;
struct pkginfo *pkg_owner;
int found;
@@ -361,14 +315,14 @@ static int searchoutput(struct filenamenode *namenode) {
}
found= 0;
- iter = filepackages_iter_new(namenode);
- while ((pkg_owner = filepackages_iter_next(iter))) {
+ iter = fsys_node_pkgs_iter_new(namenode);
+ while ((pkg_owner = fsys_node_pkgs_iter_next(iter))) {
if (found)
fputs(", ", stdout);
fputs(pkg_name(pkg_owner, pnaw_nonambig), stdout);
found++;
}
- filepackages_iter_free(iter);
+ fsys_node_pkgs_iter_free(iter);
if (found) printf(": %s\n",namenode->name);
return found + (namenode->divert ? 1 : 0);
@@ -377,8 +331,8 @@ static int searchoutput(struct filenamenode *namenode) {
static int
searchfiles(const char *const *argv)
{
- struct filenamenode *namenode;
- struct fileiterator *iter;
+ struct fsys_namenode *namenode;
+ struct fsys_hash_iter *iter;
const char *thisarg;
int found;
int failures = 0;
@@ -411,15 +365,15 @@ searchfiles(const char *const *argv)
varbuf_end_str(&path);
varbuf_trunc(&path, path_trim_slash_slashdot(path.buf));
- namenode = findnamenode(path.buf, 0);
+ namenode = fsys_hash_find_node(path.buf, 0);
found += searchoutput(namenode);
} else {
- iter = files_db_iter_new();
- while ((namenode = files_db_iter_next(iter)) != NULL) {
+ iter = fsys_hash_iter_new();
+ while ((namenode = fsys_hash_iter_next(iter)) != NULL) {
if (fnmatch(thisarg,namenode->name,0)) continue;
found+= searchoutput(namenode);
}
- files_db_iter_free(iter);
+ fsys_hash_iter_free(iter);
}
if (!found) {
notice(_("no path found matching pattern %s"), thisarg);
@@ -437,31 +391,24 @@ searchfiles(const char *const *argv)
}
static int
-enqperpackage(const char *const *argv)
+print_status(const char *const *argv)
{
const char *thisarg;
- struct fileinlist *file;
struct pkginfo *pkg;
- struct filenamenode *namenode;
int failures = 0;
- if (!*argv)
- badusage(_("--%s needs at least one package name argument"), cipaction->olong);
-
- if (cipaction->arg_int == act_printavail)
- modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
- else
- modstatdb_open(msdbrw_readonly);
+ modstatdb_open(msdbrw_readonly);
- while ((thisarg = *argv++) != NULL) {
- pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
+ if (!*argv) {
+ writedb_records(stdout, _("<standard output>"), 0);
+ } else {
+ while ((thisarg = *argv++) != NULL) {
+ pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
- switch (cipaction->arg_int) {
- case act_status:
if (pkg->status == PKG_STAT_NOTINSTALLED &&
pkg->priority == PKG_PRIO_UNKNOWN &&
str_is_unset(pkg->section) &&
- !pkg->files &&
+ !pkg->archives &&
pkg->want == PKG_WANT_UNKNOWN &&
!pkg_is_informative(pkg, &pkg->installed)) {
notice(_("package '%s' is not installed and no information is available"),
@@ -470,8 +417,39 @@ enqperpackage(const char *const *argv)
} else {
writerecord(stdout, _("<standard output>"), pkg, &pkg->installed);
}
- break;
- case act_printavail:
+
+ if (*argv != NULL)
+ putchar('\n');
+ }
+ }
+
+ m_output(stdout, _("<standard output>"));
+ if (failures) {
+ fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files.\n"),
+ stderr);
+ m_output(stderr, _("<standard error>"));
+ }
+
+ modstatdb_shutdown();
+
+ return failures;
+}
+
+static int
+print_avail(const char *const *argv)
+{
+ const char *thisarg;
+ struct pkginfo *pkg;
+ int failures = 0;
+
+ modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
+
+ if (!*argv) {
+ writedb_records(stdout, _("<standard output>"), wdb_dump_available);
+ } else {
+ while ((thisarg = *argv++) != NULL) {
+ pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
+
if (!pkg_is_informative(pkg, &pkg->available)) {
notice(_("package '%s' is not available"),
pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
@@ -479,58 +457,84 @@ enqperpackage(const char *const *argv)
} else {
writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
}
+
+ if (*argv != NULL)
+ putchar('\n');
+ }
+ }
+
+ m_output(stdout, _("<standard output>"));
+ if (failures)
+ m_output(stderr, _("<standard error>"));
+
+ modstatdb_shutdown();
+
+ return failures;
+}
+
+static int
+list_files(const char *const *argv)
+{
+ const char *thisarg;
+ struct fsys_namenode_list *file;
+ struct pkginfo *pkg;
+ struct fsys_namenode *namenode;
+ int failures = 0;
+
+ if (!*argv)
+ badusage(_("--%s needs at least one package name argument"), cipaction->olong);
+
+ modstatdb_open(msdbrw_readonly);
+
+ while ((thisarg = *argv++) != NULL) {
+ pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
+
+ switch (pkg->status) {
+ case PKG_STAT_NOTINSTALLED:
+ notice(_("package '%s' is not installed"),
+ pkg_name(pkg, pnaw_nonambig));
+ failures++;
break;
- case act_listfiles:
- switch (pkg->status) {
- case PKG_STAT_NOTINSTALLED:
- notice(_("package '%s' is not installed"),
+ default:
+ ensure_packagefiles_available(pkg);
+ ensure_diversions();
+ file = pkg->files;
+ if (!file) {
+ printf(_("Package '%s' does not contain any files (!)\n"),
pkg_name(pkg, pnaw_nonambig));
- failures++;
- break;
- default:
- ensure_packagefiles_available(pkg);
- ensure_diversions();
- file= pkg->clientdata->files;
- if (!file) {
- printf(_("Package '%s' does not contain any files (!)\n"),
- pkg_name(pkg, pnaw_nonambig));
- } else {
- while (file) {
- namenode= file->namenode;
- puts(namenode->name);
- if (namenode->divert && !namenode->divert->camefrom) {
- if (!namenode->divert->pkgset)
- printf(_("locally diverted to: %s\n"),
- namenode->divert->useinstead->name);
- else if (pkg->set == namenode->divert->pkgset)
- printf(_("package diverts others to: %s\n"),
- namenode->divert->useinstead->name);
- else
- printf(_("diverted by %s to: %s\n"),
- namenode->divert->pkgset->name,
- namenode->divert->useinstead->name);
- }
- file= file->next;
+ } else {
+ while (file) {
+ namenode = file->namenode;
+ puts(namenode->name);
+ if (namenode->divert && !namenode->divert->camefrom) {
+ if (!namenode->divert->pkgset)
+ printf(_("locally diverted to: %s\n"),
+ namenode->divert->useinstead->name);
+ else if (pkg->set == namenode->divert->pkgset)
+ printf(_("package diverts others to: %s\n"),
+ namenode->divert->useinstead->name);
+ else
+ printf(_("diverted by %s to: %s\n"),
+ namenode->divert->pkgset->name,
+ namenode->divert->useinstead->name);
}
+ file = file->next;
}
- break;
}
break;
- default:
- internerr("unknown action '%d'", cipaction->arg_int);
}
if (*argv != NULL)
putchar('\n');
-
- m_output(stdout, _("<standard output>"));
}
+ m_output(stdout, _("<standard output>"));
if (failures) {
- fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files,\n"
- "and dpkg --contents (= dpkg-deb --contents) to list their contents.\n"),stderr);
+ fputs(_("Use dpkg --contents (= dpkg-deb --contents) to list archive files contents.\n"),
+ stderr);
m_output(stderr, _("<standard error>"));
}
+
modstatdb_shutdown();
return failures;
@@ -567,7 +571,7 @@ showpackages(const char *const *argv)
else
modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
- pkg_array_init_from_db(&array);
+ pkg_array_init_from_hash(&array);
pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
if (!*argv) {
@@ -637,16 +641,16 @@ pkg_infodb_print_filetype(const char *filename, const char *filetype)
static void
control_path_file(struct pkginfo *pkg, const char *control_file)
{
- const char *control_path;
+ const char *control_pathname;
struct stat st;
- control_path = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
- if (stat(control_path, &st) < 0)
+ control_pathname = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
+ if (stat(control_pathname, &st) < 0)
return;
if (!S_ISREG(st.st_mode))
return;
- pkg_infodb_print_filename(control_path, control_file);
+ pkg_infodb_print_filename(control_pathname, control_file);
}
static int
@@ -745,6 +749,12 @@ control_show(const char *const *argv)
return 0;
}
+static void
+set_no_pager(const struct cmdinfo *ci, const char *value)
+{
+ pager_enable(false);
+}
+
static void DPKG_ATTR_NORET
printversion(const struct cmdinfo *ci, const char *value)
{
@@ -768,16 +778,16 @@ usage(const struct cmdinfo *ci, const char *value)
printf(_(
"Commands:\n"
-" -s|--status <package> ... Display package status details.\n"
-" -p|--print-avail <package> ... Display available version details.\n"
-" -L|--listfiles <package> ... List files 'owned' by package(s).\n"
-" -l|--list [<pattern> ...] List packages concisely.\n"
-" -W|--show [<pattern> ...] Show information on package(s).\n"
-" -S|--search <pattern> ... Find package(s) owning file(s).\n"
-" --control-list <package> Print the package control file list.\n"
-" --control-show <package> <file>\n"
+" -s, --status [<package>...] Display package status details.\n"
+" -p, --print-avail [<package>...] Display available version details.\n"
+" -L, --listfiles <package>... List files 'owned' by package(s).\n"
+" -l, --list [<pattern>...] List packages concisely.\n"
+" -W, --show [<pattern>...] Show information on package(s).\n"
+" -S, --search <pattern>... Find package(s) owning file(s).\n"
+" --control-list <package> Print the package control file list.\n"
+" --control-show <package> <file>\n"
" Show the package control file.\n"
-" -c|--control-path <package> [<file>]\n"
+" -c, --control-path <package> [<file>]\n"
" Print path for package control file.\n"
"\n"));
@@ -816,9 +826,9 @@ static const char *admindir;
* The action entries are made with the ACTION macro, as they all
* have a very similar structure. */
static const struct cmdinfo cmdinfos[]= {
- ACTION( "listfiles", 'L', act_listfiles, enqperpackage ),
- ACTION( "status", 's', act_status, enqperpackage ),
- ACTION( "print-avail", 'p', act_printavail, enqperpackage ),
+ ACTION( "listfiles", 'L', act_listfiles, list_files ),
+ ACTION( "status", 's', act_status, print_status ),
+ ACTION( "print-avail", 'p', act_printavail, print_avail ),
ACTION( "list", 'l', act_listpackages, listpackages ),
ACTION( "search", 'S', act_searchfiles, searchfiles ),
ACTION( "show", 'W', act_listpackages, showpackages ),
@@ -829,6 +839,7 @@ static const struct cmdinfo cmdinfos[]= {
{ "admindir", 0, 1, NULL, &admindir, NULL },
{ "load-avail", 0, 0, &opt_loadavail, NULL, NULL, 1 },
{ "showformat", 'f', 1, NULL, &showformat, NULL },
+ { "no-pager", 0, 0, NULL, NULL, set_no_pager },
{ "help", '?', 0, NULL, NULL, usage },
{ "version", 0, 0, NULL, NULL, printversion },
{ NULL, 0, 0, NULL, NULL, NULL }
@@ -846,11 +857,12 @@ int main(int argc, const char *const *argv) {
if (!cipaction) badusage(_("need an action option"));
- filesdbinit();
+ fsys_hash_init();
ret = cipaction->action(argv);
dpkg_program_done();
+ dpkg_locales_done();
return !!ret;
}