dpkg (1.18.25) stretch; urgency=medium
[dpkg] / src / querycmd.c
CommitLineData
1479465f
GJ
1/*
2 * dpkg-query - program for query the dpkg database
3 * querycmd.c - status enquiry and listing options
4 *
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>
10 *
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.
15 *
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.
20 *
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/>.
23 */
24
25#include <config.h>
26#include <compat.h>
27
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/ioctl.h>
31
32#if HAVE_LOCALE_H
33#include <locale.h>
34#endif
35#include <errno.h>
36#include <limits.h>
37#include <string.h>
38#include <fcntl.h>
39#include <dirent.h>
40#include <fnmatch.h>
41#include <termios.h>
42#include <unistd.h>
43#include <stdlib.h>
44#include <stdio.h>
45
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>
57
58#include "filesdb.h"
59#include "infodb.h"
60#include "main.h"
61
62static const char *showformat = "${binary:Package}\t${Version}\n";
63
64static int opt_loadavail = 0;
65
66static int getwidth(void) {
67 int fd;
68 long res;
69 struct winsize ws;
70 const char *columns;
71 char *endptr;
72
73 columns = getenv("COLUMNS");
74 if (columns) {
75 errno = 0;
76 res = strtol(columns, &endptr, 10);
77 if (errno == 0 && columns != endptr && *endptr == '\0' &&
78 res > 0 && res < INT_MAX)
79 return res;
80 }
81
82 if (!isatty(1))
83 return -1;
84 else {
85 res = 80;
86
87 fd = open("/dev/tty", O_RDONLY);
88 if (fd != -1) {
89 if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
90 res = ws.ws_col;
91 close(fd);
92 }
93
94 return res;
95 }
96}
97
98static int
99pkg_array_match_patterns(struct pkg_array *array,
100 pkg_array_visitor_func *pkg_visitor, void *pkg_data,
101 const char *const *argv)
102{
103 int argc, i, ip, *found;
104 int rc = 0;
105 struct pkg_spec *ps;
106
107 for (argc = 0; argv[argc]; argc++);
108 found = m_calloc(argc, sizeof(int));
109
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]);
114 }
115
116 for (i = 0; i < array->n_pkgs; i++) {
117 struct pkginfo *pkg;
118 bool pkg_found = false;
119
120 pkg = array->pkgs[i];
121 for (ip = 0; ip < argc; ip++) {
122 if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
123 pkg_found = true;
124 found[ip]++;
125 }
126 }
127 if (!pkg_found)
128 array->pkgs[i] = NULL;
129 }
130
131 pkg_array_foreach(array, pkg_visitor, pkg_data);
132
133 for (ip = 0; ip < argc; ip++) {
134 if (!found[ip]) {
135 notice(_("no packages found matching %s"), argv[ip]);
136 rc++;
137 }
138 pkg_spec_destroy(&ps[ip]);
139 }
140
141 free(ps);
142 free(found);
143
144 return rc;
145}
146
147struct list_format {
148 bool head;
149 int nw;
150 int vw;
151 int aw;
152 int dw;
153};
154
155static void
156list_format_init(struct list_format *fmt, struct pkg_array *array)
157{
158 int w;
159
160 if (fmt->nw != 0)
161 return;
162
163 w = getwidth();
164 if (w == -1) {
165 int i;
166
167 fmt->nw = 14;
168 fmt->vw = 12;
169 fmt->aw = 12;
170 fmt->dw = 33;
171
172 for (i = 0; i < array->n_pkgs; i++) {
173 int plen, vlen, alen, dlen;
174
175 if (array->pkgs[i] == NULL)
176 continue;
177
178 plen = str_width(pkg_name(array->pkgs[i], pnaw_nonambig));
179 vlen = str_width(versiondescribe(&array->pkgs[i]->installed.version,
180 vdew_nonambig));
181 alen = str_width(dpkg_arch_describe(array->pkgs[i]->installed.arch));
182 pkgbin_summary(array->pkgs[i], &array->pkgs[i]->installed, &dlen);
183
184 if (plen > fmt->nw)
185 fmt->nw = plen;
186 if (vlen > fmt->vw)
187 fmt->vw = vlen;
188 if (alen > fmt->aw)
189 fmt->aw = alen;
190 if (dlen > fmt->dw)
191 fmt->dw = dlen;
192 }
193 } else {
194 w -= 80;
195 /* Let's not try to deal with terminals that are too small. */
196 if (w < 0)
197 w = 0;
198 /* Halve that so we can add it to both the name and description. */
199 w >>= 1;
200 /* Name width. */
201 fmt->nw = (14 + (w / 2));
202 /* Version width. */
203 fmt->vw = (12 + (w / 4));
204 /* Architecture width. */
205 fmt->aw = (12 + (w / 4));
206 /* Description width. */
207 fmt->dw = (33 + w);
208 }
209}
210
211static void
212list_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)
216{
217 struct str_crop_info ns, vs, as, ds;
218
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);
223
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,
228 ds.str_bytes, desc);
229}
230
231static void
232list_format_print_header(struct list_format *fmt)
233{
234 int l;
235
236 if (fmt->head)
237 return;
238
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. */
245 fputs(_("\
246Desired=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);
251
252 /* Status */
253 printf("+++-");
254
255 /* Package name. */
256 for (l = 0; l < fmt->nw; l++)
257 printf("=");
258 printf("-");
259
260 /* Version. */
261 for (l = 0; l < fmt->vw; l++)
262 printf("=");
263 printf("-");
264
265 /* Architecture. */
266 for (l = 0; l < fmt->aw; l++)
267 printf("=");
268 printf("-");
269
270 /* Description. */
271 for (l = 0; l < fmt->dw; l++)
272 printf("=");
273 printf("\n");
274
275 fmt->head = true;
276}
277
278static void
279pkg_array_list_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
280{
281 struct list_format *fmt = pkg_data;
282 int l;
283 const char *pdesc;
284
285 list_format_init(fmt, array);
286 list_format_print_header(fmt);
287
288 pdesc = pkgbin_summary(pkg, &pkg->installed, &l);
289 l = min(l, fmt->dw);
290
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),
298 pdesc, l);
299}
300
301static int
302listpackages(const char *const *argv)
303{
304 struct pkg_array array;
305 struct pkginfo *pkg;
306 int i;
307 int rc = 0;
308 struct list_format fmt;
309
310 if (!opt_loadavail)
311 modstatdb_open(msdbrw_readonly);
312 else
313 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
314
315 pkg_array_init_from_db(&array);
316 pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
317
318 memset(&fmt, 0, sizeof(fmt));
319
320 if (!*argv) {
321 for (i = 0; i < array.n_pkgs; i++) {
322 pkg = array.pkgs[i];
323 if (pkg->status == PKG_STAT_NOTINSTALLED)
324 array.pkgs[i] = NULL;
325 }
326
327 pkg_array_foreach(&array, pkg_array_list_item, &fmt);
328 } else {
329 rc = pkg_array_match_patterns(&array, pkg_array_list_item, &fmt, argv);
330 }
331
332 m_output(stdout, _("<standard output>"));
333 m_output(stderr, _("<standard error>"));
334
335 pkg_array_destroy(&array);
336 modstatdb_shutdown();
337
338 return rc;
339}
340
341static int searchoutput(struct filenamenode *namenode) {
342 struct filepackages_iterator *iter;
343 struct pkginfo *pkg_owner;
344 int found;
345
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;
351
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);
357 } else {
358 printf(_("local diversion from: %s\n"), name_from);
359 printf(_("local diversion to: %s\n"), name_to);
360 }
361 }
362 found= 0;
363
364 iter = filepackages_iter_new(namenode);
365 while ((pkg_owner = filepackages_iter_next(iter))) {
366 if (found)
367 fputs(", ", stdout);
368 fputs(pkg_name(pkg_owner, pnaw_nonambig), stdout);
369 found++;
370 }
371 filepackages_iter_free(iter);
372
373 if (found) printf(": %s\n",namenode->name);
374 return found + (namenode->divert ? 1 : 0);
375}
376
377static int
378searchfiles(const char *const *argv)
379{
380 struct filenamenode *namenode;
381 struct fileiterator *iter;
382 const char *thisarg;
383 int found;
384 int failures = 0;
385 struct varbuf path = VARBUF_INIT;
386 static struct varbuf vb;
387
388 if (!*argv)
389 badusage(_("--search needs at least one file name pattern argument"));
390
391 modstatdb_open(msdbrw_readonly);
392 ensure_allinstfiles_available_quiet();
393 ensure_diversions();
394
395 while ((thisarg = *argv++) != NULL) {
396 found= 0;
397
398 if (!strchr("*[?/",*thisarg)) {
399 varbuf_reset(&vb);
400 varbuf_add_char(&vb, '*');
401 varbuf_add_str(&vb, thisarg);
402 varbuf_add_char(&vb, '*');
403 varbuf_end_str(&vb);
404 thisarg= vb.buf;
405 }
406 if (!strpbrk(thisarg, "*[?\\")) {
407 /* Trim trailing ‘/’ and ‘/.’ from the argument if it is not
408 * a pattern, just a pathname. */
409 varbuf_reset(&path);
410 varbuf_add_str(&path, thisarg);
411 varbuf_end_str(&path);
412 varbuf_trunc(&path, path_trim_slash_slashdot(path.buf));
413
414 namenode = findnamenode(path.buf, 0);
415 found += searchoutput(namenode);
416 } else {
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);
421 }
422 files_db_iter_free(iter);
423 }
424 if (!found) {
425 notice(_("no path found matching pattern %s"), thisarg);
426 failures++;
427 m_output(stderr, _("<standard error>"));
428 } else {
429 m_output(stdout, _("<standard output>"));
430 }
431 }
432 modstatdb_shutdown();
433
434 varbuf_destroy(&path);
435
436 return failures;
437}
438
439static int
440enqperpackage(const char *const *argv)
441{
442 const char *thisarg;
443 struct fileinlist *file;
444 struct pkginfo *pkg;
445 struct filenamenode *namenode;
446 int failures = 0;
447
448 if (!*argv)
449 badusage(_("--%s needs at least one package name argument"), cipaction->olong);
450
451 if (cipaction->arg_int == act_printavail)
452 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
453 else
454 modstatdb_open(msdbrw_readonly);
455
456 while ((thisarg = *argv++) != NULL) {
457 pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
458
459 switch (cipaction->arg_int) {
460 case act_status:
461 if (pkg->status == PKG_STAT_NOTINSTALLED &&
462 pkg->priority == PKG_PRIO_UNKNOWN &&
463 str_is_unset(pkg->section) &&
464 !pkg->files &&
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));
469 failures++;
470 } else {
471 writerecord(stdout, _("<standard output>"), pkg, &pkg->installed);
472 }
473 break;
474 case act_printavail:
475 if (!pkg_is_informative(pkg, &pkg->available)) {
476 notice(_("package '%s' is not available"),
477 pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
478 failures++;
479 } else {
480 writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
481 }
482 break;
483 case act_listfiles:
484 switch (pkg->status) {
485 case PKG_STAT_NOTINSTALLED:
486 notice(_("package '%s' is not installed"),
487 pkg_name(pkg, pnaw_nonambig));
488 failures++;
489 break;
490 default:
491 ensure_packagefiles_available(pkg);
492 ensure_diversions();
493 file= pkg->clientdata->files;
494 if (!file) {
495 printf(_("Package '%s' does not contain any files (!)\n"),
496 pkg_name(pkg, pnaw_nonambig));
497 } else {
498 while (file) {
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);
508 else
509 printf(_("diverted by %s to: %s\n"),
510 namenode->divert->pkgset->name,
511 namenode->divert->useinstead->name);
512 }
513 file= file->next;
514 }
515 }
516 break;
517 }
518 break;
519 default:
520 internerr("unknown action '%d'", cipaction->arg_int);
521 }
522
523 if (*argv != NULL)
524 putchar('\n');
525
526 m_output(stdout, _("<standard output>"));
527 }
528
529 if (failures) {
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>"));
533 }
534 modstatdb_shutdown();
535
536 return failures;
537}
538
539static void
540pkg_array_show_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
541{
542 struct pkg_format_node *fmt = pkg_data;
543
544 pkg_format_show(fmt, pkg, &pkg->installed);
545}
546
547static int
548showpackages(const char *const *argv)
549{
550 struct dpkg_error err;
551 struct pkg_array array;
552 struct pkginfo *pkg;
553 struct pkg_format_node *fmt;
554 int i;
555 int rc = 0;
556
557 fmt = pkg_format_parse(showformat, &err);
558 if (!fmt) {
559 notice(_("error in show format: %s"), err.str);
560 dpkg_error_destroy(&err);
561 rc++;
562 return rc;
563 }
564
565 if (!opt_loadavail)
566 modstatdb_open(msdbrw_readonly);
567 else
568 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
569
570 pkg_array_init_from_db(&array);
571 pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
572
573 if (!*argv) {
574 for (i = 0; i < array.n_pkgs; i++) {
575 pkg = array.pkgs[i];
576 if (pkg->status == PKG_STAT_NOTINSTALLED)
577 continue;
578 pkg_format_show(fmt, pkg, &pkg->installed);
579 }
580 } else {
581 rc = pkg_array_match_patterns(&array, pkg_array_show_item, fmt, argv);
582 }
583
584 m_output(stdout, _("<standard output>"));
585 m_output(stderr, _("<standard error>"));
586
587 pkg_array_destroy(&array);
588 pkg_format_free(fmt);
589 modstatdb_shutdown();
590
591 return rc;
592}
593
594static bool
595pkg_infodb_is_internal(const char *filetype)
596{
597 /* Do not expose internal database files. */
598 if (strcmp(filetype, LISTFILE) == 0 ||
599 strcmp(filetype, CONFFILESFILE) == 0)
600 return true;
601
602 if (strlen(filetype) > MAXCONTROLFILENAME)
603 return true;
604
605 return false;
606}
607
608static void
609pkg_infodb_check_filetype(const char *filetype)
610{
611 const char *c;
612
613 /* Validate control file name for sanity. */
614 for (c = "/."; *c; c++)
615 if (strchr(filetype, *c))
616 badusage(_("control file contains %c"), *c);
617}
618
619static void
620pkg_infodb_print_filename(const char *filename, const char *filetype)
621{
622 if (pkg_infodb_is_internal(filetype))
623 return;
624
625 printf("%s\n", filename);
626}
627
628static void
629pkg_infodb_print_filetype(const char *filename, const char *filetype)
630{
631 if (pkg_infodb_is_internal(filetype))
632 return;
633
634 printf("%s\n", filetype);
635}
636
637static void
638control_path_file(struct pkginfo *pkg, const char *control_file)
639{
640 const char *control_path;
641 struct stat st;
642
643 control_path = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
644 if (stat(control_path, &st) < 0)
645 return;
646 if (!S_ISREG(st.st_mode))
647 return;
648
649 pkg_infodb_print_filename(control_path, control_file);
650}
651
652static int
653control_path(const char *const *argv)
654{
655 struct pkginfo *pkg;
656 const char *pkgname;
657 const char *control_file;
658
659 pkgname = *argv++;
660 if (!pkgname)
661 badusage(_("--%s needs at least one package name argument"),
662 cipaction->olong);
663
664 control_file = *argv++;
665 if (control_file && *argv)
666 badusage(_("--%s takes at most two arguments"), cipaction->olong);
667
668 if (control_file)
669 pkg_infodb_check_filetype(control_file);
670
671 modstatdb_open(msdbrw_readonly);
672
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));
677
678 if (control_file)
679 control_path_file(pkg, control_file);
680 else
681 pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filename);
682
683 modstatdb_shutdown();
684
685 return 0;
686}
687
688static int
689control_list(const char *const *argv)
690{
691 struct pkginfo *pkg;
692 const char *pkgname;
693
694 pkgname = *argv++;
695 if (!pkgname || *argv)
696 badusage(_("--%s takes one package name argument"), cipaction->olong);
697
698 modstatdb_open(msdbrw_readonly);
699
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));
703
704 pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filetype);
705
706 modstatdb_shutdown();
707
708 return 0;
709}
710
711static int
712control_show(const char *const *argv)
713{
714 struct pkginfo *pkg;
715 const char *pkgname;
716 const char *filename;
717 const char *control_file;
718
719 pkgname = *argv++;
720 if (!pkgname || !*argv)
721 badusage(_("--%s takes exactly two arguments"),
722 cipaction->olong);
723
724 control_file = *argv++;
725 if (!control_file || *argv)
726 badusage(_("--%s takes exactly two arguments"), cipaction->olong);
727
728 pkg_infodb_check_filetype(control_file);
729
730 modstatdb_open(msdbrw_readonly);
731
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));
735
736 if (pkg_infodb_has_file(pkg, &pkg->installed, control_file))
737 filename = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
738 else
739 ohshit(_("control file '%s' does not exist"), control_file);
740
741 modstatdb_shutdown();
742
743 file_show(filename);
744
745 return 0;
746}
747
748static void DPKG_ATTR_NORET
749printversion(const struct cmdinfo *ci, const char *value)
750{
751 printf(_("Debian %s package management program query tool version %s.\n"),
752 DPKGQUERY, PACKAGE_RELEASE);
753 printf(_(
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"));
756
757 m_output(stdout, _("<standard output>"));
758
759 exit(0);
760}
761
762static void DPKG_ATTR_NORET
763usage(const struct cmdinfo *ci, const char *value)
764{
765 printf(_(
766"Usage: %s [<option> ...] <command>\n"
767"\n"), DPKGQUERY);
768
769 printf(_(
770"Commands:\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"
782"\n"));
783
784 printf(_(
785" -?, --help Show this help message.\n"
786" --version Show the version.\n"
787"\n"));
788
789 printf(_(
790"Options:\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"
794"\n"), ADMINDIR);
795
796 printf(_(
797"Format syntax:\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"));
804
805 m_output(stdout, _("<standard output>"));
806
807 exit(0);
808}
809
810static const char printforhelp[] = N_(
811"Use --help for help about querying packages.");
812
813static const char *admindir;
814
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. */
818static 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 ),
828
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 }
835};
836
837int main(int argc, const char *const *argv) {
838 int ret;
839
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);
844
845 admindir = dpkg_db_set_dir(admindir);
846
847 if (!cipaction) badusage(_("need an action option"));
848
849 filesdbinit();
850
851 ret = cipaction->action(argv);
852
853 dpkg_program_done();
854
855 return !!ret;
856}