2 * dpkg-query - program for query the dpkg database
3 * querycmd.c - status enquiry and listing options
5 * Copyright © 1995,1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2000,2001 Wichert Akkerman <wakkerma@debian.org>
7 * Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
8 * Copyright © 2011 Linaro Limited
9 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 #include <sys/types.h>
30 #include <sys/ioctl.h>
46 #include <dpkg/i18n.h>
47 #include <dpkg/dpkg.h>
48 #include <dpkg/dpkg-db.h>
49 #include <dpkg/pkg-array.h>
50 #include <dpkg/pkg-spec.h>
51 #include <dpkg/pkg-format.h>
52 #include <dpkg/pkg-show.h>
53 #include <dpkg/string.h>
54 #include <dpkg/path.h>
55 #include <dpkg/file.h>
56 #include <dpkg/options.h>
62 static const char *showformat
= "${binary:Package}\t${Version}\n";
64 static int opt_loadavail
= 0;
66 static int getwidth(void) {
73 columns
= getenv("COLUMNS");
76 res
= strtol(columns
, &endptr
, 10);
77 if (errno
== 0 && columns
!= endptr
&& *endptr
== '\0' &&
78 res
> 0 && res
< INT_MAX
)
87 fd
= open("/dev/tty", O_RDONLY
);
89 if (ioctl(fd
, TIOCGWINSZ
, &ws
) == 0)
99 pkg_array_match_patterns(struct pkg_array
*array
,
100 pkg_array_visitor_func
*pkg_visitor
, void *pkg_data
,
101 const char *const *argv
)
103 int argc
, i
, ip
, *found
;
107 for (argc
= 0; argv
[argc
]; argc
++);
108 found
= m_calloc(argc
, sizeof(int));
110 ps
= m_malloc(sizeof(*ps
) * argc
);
111 for (ip
= 0; ip
< argc
; ip
++) {
112 pkg_spec_init(&ps
[ip
], PKG_SPEC_PATTERNS
| PKG_SPEC_ARCH_WILDCARD
);
113 pkg_spec_parse(&ps
[ip
], argv
[ip
]);
116 for (i
= 0; i
< array
->n_pkgs
; i
++) {
118 bool pkg_found
= false;
120 pkg
= array
->pkgs
[i
];
121 for (ip
= 0; ip
< argc
; ip
++) {
122 if (pkg_spec_match_pkg(&ps
[ip
], pkg
, &pkg
->installed
)) {
128 array
->pkgs
[i
] = NULL
;
131 pkg_array_foreach(array
, pkg_visitor
, pkg_data
);
133 for (ip
= 0; ip
< argc
; ip
++) {
135 notice(_("no packages found matching %s"), argv
[ip
]);
138 pkg_spec_destroy(&ps
[ip
]);
156 list_format_init(struct list_format
*fmt
, struct pkg_array
*array
)
172 for (i
= 0; i
< array
->n_pkgs
; i
++) {
173 int plen
, vlen
, alen
, dlen
;
175 if (array
->pkgs
[i
] == NULL
)
178 plen
= str_width(pkg_name(array
->pkgs
[i
], pnaw_nonambig
));
179 vlen
= str_width(versiondescribe(&array
->pkgs
[i
]->installed
.version
,
181 alen
= str_width(dpkg_arch_describe(array
->pkgs
[i
]->installed
.arch
));
182 pkgbin_summary(array
->pkgs
[i
], &array
->pkgs
[i
]->installed
, &dlen
);
195 /* Let's not try to deal with terminals that are too small. */
198 /* Halve that so we can add it to both the name and description. */
201 fmt
->nw
= (14 + (w
/ 2));
203 fmt
->vw
= (12 + (w
/ 4));
204 /* Architecture width. */
205 fmt
->aw
= (12 + (w
/ 4));
206 /* Description width. */
212 list_format_print(struct list_format
*fmt
,
213 int c_want
, int c_status
, int c_eflag
,
214 const char *name
, const char *version
, const char *arch
,
215 const char *desc
, int desc_len
)
217 struct str_crop_info ns
, vs
, as
, ds
;
219 str_gen_crop(name
, fmt
->nw
, &ns
);
220 str_gen_crop(version
, fmt
->vw
, &vs
);
221 str_gen_crop(arch
, fmt
->aw
, &as
);
222 str_gen_crop(desc
, desc_len
, &ds
);
224 printf("%c%c%c %-*.*s %-*.*s %-*.*s %.*s\n", c_want
, c_status
, c_eflag
,
225 ns
.max_bytes
, ns
.str_bytes
, name
,
226 vs
.max_bytes
, vs
.str_bytes
, version
,
227 as
.max_bytes
, as
.str_bytes
, arch
,
232 list_format_print_header(struct list_format
*fmt
)
239 /* TRANSLATORS: This is the header that appears on 'dpkg-query -l'. The
240 * string should remain under 80 characters. The uppercase letters in
241 * the state values denote the abbreviated letter that will appear on
242 * the first three columns, which should ideally match the English one
243 * (e.g. Remove → supRimeix), see dpkg-query(1) for further details. The
244 * translated message can use additional lines if needed. */
246 Desired=Unknown/Install/Remove/Purge/Hold\n\
247 | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\n\
248 |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\n"), stdout
);
249 list_format_print(fmt
, '|', '|', '/', _("Name"), _("Version"),
250 _("Architecture"), _("Description"), fmt
->dw
);
256 for (l
= 0; l
< fmt
->nw
; l
++)
261 for (l
= 0; l
< fmt
->vw
; l
++)
266 for (l
= 0; l
< fmt
->aw
; l
++)
271 for (l
= 0; l
< fmt
->dw
; l
++)
279 pkg_array_list_item(struct pkg_array
*array
, struct pkginfo
*pkg
, void *pkg_data
)
281 struct list_format
*fmt
= pkg_data
;
285 list_format_init(fmt
, array
);
286 list_format_print_header(fmt
);
288 pdesc
= pkgbin_summary(pkg
, &pkg
->installed
, &l
);
291 list_format_print(fmt
,
292 pkg_abbrev_want(pkg
),
293 pkg_abbrev_status(pkg
),
294 pkg_abbrev_eflag(pkg
),
295 pkg_name(pkg
, pnaw_nonambig
),
296 versiondescribe(&pkg
->installed
.version
, vdew_nonambig
),
297 dpkg_arch_describe(pkg
->installed
.arch
),
302 listpackages(const char *const *argv
)
304 struct pkg_array array
;
308 struct list_format fmt
;
311 modstatdb_open(msdbrw_readonly
);
313 modstatdb_open(msdbrw_readonly
| msdbrw_available_readonly
);
315 pkg_array_init_from_db(&array
);
316 pkg_array_sort(&array
, pkg_sorter_by_nonambig_name_arch
);
318 memset(&fmt
, 0, sizeof(fmt
));
321 for (i
= 0; i
< array
.n_pkgs
; i
++) {
323 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
324 array
.pkgs
[i
] = NULL
;
327 pkg_array_foreach(&array
, pkg_array_list_item
, &fmt
);
329 rc
= pkg_array_match_patterns(&array
, pkg_array_list_item
, &fmt
, argv
);
332 m_output(stdout
, _("<standard output>"));
333 m_output(stderr
, _("<standard error>"));
335 pkg_array_destroy(&array
);
336 modstatdb_shutdown();
341 static int searchoutput(struct filenamenode
*namenode
) {
342 struct filepackages_iterator
*iter
;
343 struct pkginfo
*pkg_owner
;
346 if (namenode
->divert
) {
347 const char *name_from
= namenode
->divert
->camefrom ?
348 namenode
->divert
->camefrom
->name
: namenode
->name
;
349 const char *name_to
= namenode
->divert
->useinstead ?
350 namenode
->divert
->useinstead
->name
: namenode
->name
;
352 if (namenode
->divert
->pkgset
) {
353 printf(_("diversion by %s from: %s\n"),
354 namenode
->divert
->pkgset
->name
, name_from
);
355 printf(_("diversion by %s to: %s\n"),
356 namenode
->divert
->pkgset
->name
, name_to
);
358 printf(_("local diversion from: %s\n"), name_from
);
359 printf(_("local diversion to: %s\n"), name_to
);
364 iter
= filepackages_iter_new(namenode
);
365 while ((pkg_owner
= filepackages_iter_next(iter
))) {
368 fputs(pkg_name(pkg_owner
, pnaw_nonambig
), stdout
);
371 filepackages_iter_free(iter
);
373 if (found
) printf(": %s\n",namenode
->name
);
374 return found
+ (namenode
->divert ?
1 : 0);
378 searchfiles(const char *const *argv
)
380 struct filenamenode
*namenode
;
381 struct fileiterator
*iter
;
385 struct varbuf path
= VARBUF_INIT
;
386 static struct varbuf vb
;
389 badusage(_("--search needs at least one file name pattern argument"));
391 modstatdb_open(msdbrw_readonly
);
392 ensure_allinstfiles_available_quiet();
395 while ((thisarg
= *argv
++) != NULL
) {
398 if (!strchr("*[?/",*thisarg
)) {
400 varbuf_add_char(&vb
, '*');
401 varbuf_add_str(&vb
, thisarg
);
402 varbuf_add_char(&vb
, '*');
406 if (!strpbrk(thisarg
, "*[?\\")) {
407 /* Trim trailing ‘/’ and ‘/.’ from the argument if it is not
408 * a pattern, just a pathname. */
410 varbuf_add_str(&path
, thisarg
);
411 varbuf_end_str(&path
);
412 varbuf_trunc(&path
, path_trim_slash_slashdot(path
.buf
));
414 namenode
= findnamenode(path
.buf
, 0);
415 found
+= searchoutput(namenode
);
417 iter
= files_db_iter_new();
418 while ((namenode
= files_db_iter_next(iter
)) != NULL
) {
419 if (fnmatch(thisarg
,namenode
->name
,0)) continue;
420 found
+= searchoutput(namenode
);
422 files_db_iter_free(iter
);
425 notice(_("no path found matching pattern %s"), thisarg
);
427 m_output(stderr
, _("<standard error>"));
429 m_output(stdout
, _("<standard output>"));
432 modstatdb_shutdown();
434 varbuf_destroy(&path
);
440 enqperpackage(const char *const *argv
)
443 struct fileinlist
*file
;
445 struct filenamenode
*namenode
;
449 badusage(_("--%s needs at least one package name argument"), cipaction
->olong
);
451 if (cipaction
->arg_int
== act_printavail
)
452 modstatdb_open(msdbrw_readonly
| msdbrw_available_readonly
);
454 modstatdb_open(msdbrw_readonly
);
456 while ((thisarg
= *argv
++) != NULL
) {
457 pkg
= dpkg_options_parse_pkgname(cipaction
, thisarg
);
459 switch (cipaction
->arg_int
) {
461 if (pkg
->status
== PKG_STAT_NOTINSTALLED
&&
462 pkg
->priority
== PKG_PRIO_UNKNOWN
&&
463 str_is_unset(pkg
->section
) &&
465 pkg
->want
== PKG_WANT_UNKNOWN
&&
466 !pkg_is_informative(pkg
, &pkg
->installed
)) {
467 notice(_("package '%s' is not installed and no information is available"),
468 pkg_name(pkg
, pnaw_nonambig
));
471 writerecord(stdout
, _("<standard output>"), pkg
, &pkg
->installed
);
475 if (!pkg_is_informative(pkg
, &pkg
->available
)) {
476 notice(_("package '%s' is not available"),
477 pkgbin_name(pkg
, &pkg
->available
, pnaw_nonambig
));
480 writerecord(stdout
, _("<standard output>"), pkg
, &pkg
->available
);
484 switch (pkg
->status
) {
485 case PKG_STAT_NOTINSTALLED
:
486 notice(_("package '%s' is not installed"),
487 pkg_name(pkg
, pnaw_nonambig
));
491 ensure_packagefiles_available(pkg
);
493 file
= pkg
->clientdata
->files
;
495 printf(_("Package '%s' does not contain any files (!)\n"),
496 pkg_name(pkg
, pnaw_nonambig
));
499 namenode
= file
->namenode
;
500 puts(namenode
->name
);
501 if (namenode
->divert
&& !namenode
->divert
->camefrom
) {
502 if (!namenode
->divert
->pkgset
)
503 printf(_("locally diverted to: %s\n"),
504 namenode
->divert
->useinstead
->name
);
505 else if (pkg
->set
== namenode
->divert
->pkgset
)
506 printf(_("package diverts others to: %s\n"),
507 namenode
->divert
->useinstead
->name
);
509 printf(_("diverted by %s to: %s\n"),
510 namenode
->divert
->pkgset
->name
,
511 namenode
->divert
->useinstead
->name
);
520 internerr("unknown action '%d'", cipaction
->arg_int
);
526 m_output(stdout
, _("<standard output>"));
530 fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files,\n"
531 "and dpkg --contents (= dpkg-deb --contents) to list their contents.\n"),stderr
);
532 m_output(stderr
, _("<standard error>"));
534 modstatdb_shutdown();
540 pkg_array_show_item(struct pkg_array
*array
, struct pkginfo
*pkg
, void *pkg_data
)
542 struct pkg_format_node
*fmt
= pkg_data
;
544 pkg_format_show(fmt
, pkg
, &pkg
->installed
);
548 showpackages(const char *const *argv
)
550 struct dpkg_error err
;
551 struct pkg_array array
;
553 struct pkg_format_node
*fmt
;
557 fmt
= pkg_format_parse(showformat
, &err
);
559 notice(_("error in show format: %s"), err
.str
);
560 dpkg_error_destroy(&err
);
566 modstatdb_open(msdbrw_readonly
);
568 modstatdb_open(msdbrw_readonly
| msdbrw_available_readonly
);
570 pkg_array_init_from_db(&array
);
571 pkg_array_sort(&array
, pkg_sorter_by_nonambig_name_arch
);
574 for (i
= 0; i
< array
.n_pkgs
; i
++) {
576 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
578 pkg_format_show(fmt
, pkg
, &pkg
->installed
);
581 rc
= pkg_array_match_patterns(&array
, pkg_array_show_item
, fmt
, argv
);
584 m_output(stdout
, _("<standard output>"));
585 m_output(stderr
, _("<standard error>"));
587 pkg_array_destroy(&array
);
588 pkg_format_free(fmt
);
589 modstatdb_shutdown();
595 pkg_infodb_is_internal(const char *filetype
)
597 /* Do not expose internal database files. */
598 if (strcmp(filetype
, LISTFILE
) == 0 ||
599 strcmp(filetype
, CONFFILESFILE
) == 0)
602 if (strlen(filetype
) > MAXCONTROLFILENAME
)
609 pkg_infodb_check_filetype(const char *filetype
)
613 /* Validate control file name for sanity. */
614 for (c
= "/."; *c
; c
++)
615 if (strchr(filetype
, *c
))
616 badusage(_("control file contains %c"), *c
);
620 pkg_infodb_print_filename(const char *filename
, const char *filetype
)
622 if (pkg_infodb_is_internal(filetype
))
625 printf("%s\n", filename
);
629 pkg_infodb_print_filetype(const char *filename
, const char *filetype
)
631 if (pkg_infodb_is_internal(filetype
))
634 printf("%s\n", filetype
);
638 control_path_file(struct pkginfo
*pkg
, const char *control_file
)
640 const char *control_path
;
643 control_path
= pkg_infodb_get_file(pkg
, &pkg
->installed
, control_file
);
644 if (stat(control_path
, &st
) < 0)
646 if (!S_ISREG(st
.st_mode
))
649 pkg_infodb_print_filename(control_path
, control_file
);
653 control_path(const char *const *argv
)
657 const char *control_file
;
661 badusage(_("--%s needs at least one package name argument"),
664 control_file
= *argv
++;
665 if (control_file
&& *argv
)
666 badusage(_("--%s takes at most two arguments"), cipaction
->olong
);
669 pkg_infodb_check_filetype(control_file
);
671 modstatdb_open(msdbrw_readonly
);
673 pkg
= dpkg_options_parse_pkgname(cipaction
, pkgname
);
674 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
675 ohshit(_("package '%s' is not installed"),
676 pkg_name(pkg
, pnaw_nonambig
));
679 control_path_file(pkg
, control_file
);
681 pkg_infodb_foreach(pkg
, &pkg
->installed
, pkg_infodb_print_filename
);
683 modstatdb_shutdown();
689 control_list(const char *const *argv
)
695 if (!pkgname
|| *argv
)
696 badusage(_("--%s takes one package name argument"), cipaction
->olong
);
698 modstatdb_open(msdbrw_readonly
);
700 pkg
= dpkg_options_parse_pkgname(cipaction
, pkgname
);
701 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
702 ohshit(_("package '%s' is not installed"), pkg_name(pkg
, pnaw_nonambig
));
704 pkg_infodb_foreach(pkg
, &pkg
->installed
, pkg_infodb_print_filetype
);
706 modstatdb_shutdown();
712 control_show(const char *const *argv
)
716 const char *filename
;
717 const char *control_file
;
720 if (!pkgname
|| !*argv
)
721 badusage(_("--%s takes exactly two arguments"),
724 control_file
= *argv
++;
725 if (!control_file
|| *argv
)
726 badusage(_("--%s takes exactly two arguments"), cipaction
->olong
);
728 pkg_infodb_check_filetype(control_file
);
730 modstatdb_open(msdbrw_readonly
);
732 pkg
= dpkg_options_parse_pkgname(cipaction
, pkgname
);
733 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
734 ohshit(_("package '%s' is not installed"), pkg_name(pkg
, pnaw_nonambig
));
736 if (pkg_infodb_has_file(pkg
, &pkg
->installed
, control_file
))
737 filename
= pkg_infodb_get_file(pkg
, &pkg
->installed
, control_file
);
739 ohshit(_("control file '%s' does not exist"), control_file
);
741 modstatdb_shutdown();
748 static void DPKG_ATTR_NORET
749 printversion(const struct cmdinfo
*ci
, const char *value
)
751 printf(_("Debian %s package management program query tool version %s.\n"),
752 DPKGQUERY
, PACKAGE_RELEASE
);
754 "This is free software; see the GNU General Public License version 2 or\n"
755 "later for copying conditions. There is NO warranty.\n"));
757 m_output(stdout
, _("<standard output>"));
762 static void DPKG_ATTR_NORET
763 usage(const struct cmdinfo
*ci
, const char *value
)
766 "Usage: %s [<option> ...] <command>\n"
771 " -s|--status <package> ... Display package status details.\n"
772 " -p|--print-avail <package> ... Display available version details.\n"
773 " -L|--listfiles <package> ... List files 'owned' by package(s).\n"
774 " -l|--list [<pattern> ...] List packages concisely.\n"
775 " -W|--show [<pattern> ...] Show information on package(s).\n"
776 " -S|--search <pattern> ... Find package(s) owning file(s).\n"
777 " --control-list <package> Print the package control file list.\n"
778 " --control-show <package> <file>\n"
779 " Show the package control file.\n"
780 " -c|--control-path <package> [<file>]\n"
781 " Print path for package control file.\n"
785 " -?, --help Show this help message.\n"
786 " --version Show the version.\n"
791 " --admindir=<directory> Use <directory> instead of %s.\n"
792 " --load-avail Use available file on --show and --list.\n"
793 " -f|--showformat=<format> Use alternative format for --show.\n"
798 " A format is a string that will be output for each package. The format\n"
799 " can include the standard escape sequences \\n (newline), \\r (carriage\n"
800 " return) or \\\\ (plain backslash). Package information can be included\n"
801 " by inserting variable references to package fields using the ${var[;width]}\n"
802 " syntax. Fields will be right-aligned unless the width is negative in which\n"
803 " case left alignment will be used.\n"));
805 m_output(stdout
, _("<standard output>"));
810 static const char printforhelp
[] = N_(
811 "Use --help for help about querying packages.");
813 static const char *admindir
;
815 /* This table has both the action entries in it and the normal options.
816 * The action entries are made with the ACTION macro, as they all
817 * have a very similar structure. */
818 static const struct cmdinfo cmdinfos
[]= {
819 ACTION( "listfiles", 'L', act_listfiles
, enqperpackage
),
820 ACTION( "status", 's', act_status
, enqperpackage
),
821 ACTION( "print-avail", 'p', act_printavail
, enqperpackage
),
822 ACTION( "list", 'l', act_listpackages
, listpackages
),
823 ACTION( "search", 'S', act_searchfiles
, searchfiles
),
824 ACTION( "show", 'W', act_listpackages
, showpackages
),
825 ACTION( "control-path", 'c', act_controlpath
, control_path
),
826 ACTION( "control-list", 0, act_controllist
, control_list
),
827 ACTION( "control-show", 0, act_controlshow
, control_show
),
829 { "admindir", 0, 1, NULL
, &admindir
, NULL
},
830 { "load-avail", 0, 0, &opt_loadavail
, NULL
, NULL
, 1 },
831 { "showformat", 'f', 1, NULL
, &showformat
, NULL
},
832 { "help", '?', 0, NULL
, NULL
, usage
},
833 { "version", 0, 0, NULL
, NULL
, printversion
},
834 { NULL
, 0, 0, NULL
, NULL
, NULL
}
837 int main(int argc
, const char *const *argv
) {
840 dpkg_set_report_piped_mode(_IOFBF
);
841 dpkg_locales_init(PACKAGE
);
842 dpkg_program_init("dpkg-query");
843 dpkg_options_parse(&argv
, cmdinfos
, printforhelp
);
845 admindir
= dpkg_db_set_dir(admindir
);
847 if (!cipaction
) badusage(_("need an action option"));
851 ret
= cipaction
->action(argv
);