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
31 #if HAVE_LOCALE_H
32 #include <locale.h>
33 #endif
34 #include <errno.h>
35 #include <limits.h>
36 #include <string.h>
37 #include <fcntl.h>
38 #include <dirent.h>
39 #include <fnmatch.h>
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43
44 #include <dpkg/i18n.h>
45 #include <dpkg/dpkg.h>
46 #include <dpkg/dpkg-db.h>
47 #include <dpkg/pkg-array.h>
48 #include <dpkg/pkg-spec.h>
49 #include <dpkg/pkg-format.h>
50 #include <dpkg/pkg-show.h>
51 #include <dpkg/string.h>
52 #include <dpkg/path.h>
53 #include <dpkg/file.h>
54 #include <dpkg/pager.h>
55 #include <dpkg/options.h>
56 #include <dpkg/db-ctrl.h>
57 #include <dpkg/db-fsys.h>
58
59 #include "main.h"
60
61 static const char *showformat = "${binary:Package}\t${Version}\n";
62
63 static int opt_loadavail = 0;
64
65 static int
pkg_array_match_patterns(struct pkg_array * array,pkg_array_visitor_func * pkg_visitor,void * pkg_data,const char * const * argv)66 pkg_array_match_patterns(struct pkg_array *array,
67 pkg_array_visitor_func *pkg_visitor, void *pkg_data,
68 const char *const *argv)
69 {
70 int argc, i, ip, *found;
71 int rc = 0;
72 struct pkg_spec *ps;
73
74 for (argc = 0; argv[argc]; argc++);
75 found = m_calloc(argc, sizeof(int));
76
77 ps = m_malloc(sizeof(*ps) * argc);
78 for (ip = 0; ip < argc; ip++) {
79 pkg_spec_init(&ps[ip], PKG_SPEC_PATTERNS | PKG_SPEC_ARCH_WILDCARD);
80 pkg_spec_parse(&ps[ip], argv[ip]);
81 }
82
83 for (i = 0; i < array->n_pkgs; i++) {
84 struct pkginfo *pkg;
85 bool pkg_found = false;
86
87 pkg = array->pkgs[i];
88 for (ip = 0; ip < argc; ip++) {
89 if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
90 pkg_found = true;
91 found[ip]++;
92 }
93 }
94 if (!pkg_found)
95 array->pkgs[i] = NULL;
96 }
97
98 pkg_array_foreach(array, pkg_visitor, pkg_data);
99
100 for (ip = 0; ip < argc; ip++) {
101 if (!found[ip]) {
102 notice(_("no packages found matching %s"), argv[ip]);
103 rc++;
104 }
105 pkg_spec_destroy(&ps[ip]);
106 }
107
108 free(ps);
109 free(found);
110
111 return rc;
112 }
113
114 struct list_format {
115 bool head;
116 int nw;
117 int vw;
118 int aw;
119 int dw;
120 };
121
122 static void
list_format_init(struct list_format * fmt,struct pkg_array * array)123 list_format_init(struct list_format *fmt, struct pkg_array *array)
124 {
125 int i;
126
127 if (fmt->nw != 0)
128 return;
129
130 fmt->nw = 14;
131 fmt->vw = 12;
132 fmt->aw = 12;
133 fmt->dw = 33;
134
135 for (i = 0; i < array->n_pkgs; i++) {
136 int plen, vlen, alen, dlen;
137
138 if (array->pkgs[i] == NULL)
139 continue;
140
141 plen = str_width(pkg_name(array->pkgs[i], pnaw_nonambig));
142 vlen = str_width(versiondescribe(&array->pkgs[i]->installed.version,
143 vdew_nonambig));
144 alen = str_width(dpkg_arch_describe(array->pkgs[i]->installed.arch));
145 pkgbin_synopsis(array->pkgs[i], &array->pkgs[i]->installed, &dlen);
146
147 if (plen > fmt->nw)
148 fmt->nw = plen;
149 if (vlen > fmt->vw)
150 fmt->vw = vlen;
151 if (alen > fmt->aw)
152 fmt->aw = alen;
153 if (dlen > fmt->dw)
154 fmt->dw = dlen;
155 }
156 }
157
158 static void
list_format_print(struct list_format * fmt,int c_want,int c_status,int c_eflag,const char * name,const char * version,const char * arch,const char * desc,int desc_len)159 list_format_print(struct list_format *fmt,
160 int c_want, int c_status, int c_eflag,
161 const char *name, const char *version, const char *arch,
162 const char *desc, int desc_len)
163 {
164 struct str_crop_info ns, vs, as, ds;
165
166 str_gen_crop(name, fmt->nw, &ns);
167 str_gen_crop(version, fmt->vw, &vs);
168 str_gen_crop(arch, fmt->aw, &as);
169 str_gen_crop(desc, desc_len, &ds);
170
171 printf("%c%c%c %-*.*s %-*.*s %-*.*s %.*s\n", c_want, c_status, c_eflag,
172 ns.max_bytes, ns.str_bytes, name,
173 vs.max_bytes, vs.str_bytes, version,
174 as.max_bytes, as.str_bytes, arch,
175 ds.str_bytes, desc);
176 }
177
178 static void
list_format_print_header(struct list_format * fmt)179 list_format_print_header(struct list_format *fmt)
180 {
181 int l;
182
183 if (fmt->head)
184 return;
185
186 /* TRANSLATORS: This is the header that appears on 'dpkg-query -l'. The
187 * string should remain under 80 characters. The uppercase letters in
188 * the state values denote the abbreviated letter that will appear on
189 * the first three columns, which should ideally match the English one
190 * (e.g. Remove → supRimeix), see dpkg-query(1) for further details. The
191 * translated message can use additional lines if needed. */
192 fputs(_("\
193 Desired=Unknown/Install/Remove/Purge/Hold\n\
194 | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\n\
195 |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\n"), stdout);
196 list_format_print(fmt, '|', '|', '/', _("Name"), _("Version"),
197 _("Architecture"), _("Description"), fmt->dw);
198
199 /* Status */
200 printf("+++-");
201
202 /* Package name. */
203 for (l = 0; l < fmt->nw; l++)
204 printf("=");
205 printf("-");
206
207 /* Version. */
208 for (l = 0; l < fmt->vw; l++)
209 printf("=");
210 printf("-");
211
212 /* Architecture. */
213 for (l = 0; l < fmt->aw; l++)
214 printf("=");
215 printf("-");
216
217 /* Description. */
218 for (l = 0; l < fmt->dw; l++)
219 printf("=");
220 printf("\n");
221
222 fmt->head = true;
223 }
224
225 static void
pkg_array_list_item(struct pkg_array * array,struct pkginfo * pkg,void * pkg_data)226 pkg_array_list_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
227 {
228 struct list_format *fmt = pkg_data;
229 int l;
230 const char *pdesc;
231
232 list_format_init(fmt, array);
233 list_format_print_header(fmt);
234
235 pdesc = pkgbin_synopsis(pkg, &pkg->installed, &l);
236 l = min(l, fmt->dw);
237
238 list_format_print(fmt,
239 pkg_abbrev_want(pkg),
240 pkg_abbrev_status(pkg),
241 pkg_abbrev_eflag(pkg),
242 pkg_name(pkg, pnaw_nonambig),
243 versiondescribe(&pkg->installed.version, vdew_nonambig),
244 dpkg_arch_describe(pkg->installed.arch),
245 pdesc, l);
246 }
247
248 static int
listpackages(const char * const * argv)249 listpackages(const char *const *argv)
250 {
251 struct pkg_array array;
252 struct pkginfo *pkg;
253 int i;
254 int rc = 0;
255 struct list_format fmt;
256 struct pager *pager;
257
258 if (!opt_loadavail)
259 modstatdb_open(msdbrw_readonly);
260 else
261 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
262
263 pkg_array_init_from_hash(&array);
264 pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
265
266 memset(&fmt, 0, sizeof(fmt));
267
268 pager = pager_spawn(_("showing package list on pager"));
269
270 if (!*argv) {
271 for (i = 0; i < array.n_pkgs; i++) {
272 pkg = array.pkgs[i];
273 if (pkg->status == PKG_STAT_NOTINSTALLED)
274 array.pkgs[i] = NULL;
275 }
276
277 pkg_array_foreach(&array, pkg_array_list_item, &fmt);
278 } else {
279 rc = pkg_array_match_patterns(&array, pkg_array_list_item, &fmt, argv);
280 }
281
282 m_output(stdout, _("<standard output>"));
283 m_output(stderr, _("<standard error>"));
284
285 pager_reap(pager);
286
287 pkg_array_destroy(&array);
288 modstatdb_shutdown();
289
290 return rc;
291 }
292
293 static int
searchoutput(struct fsys_namenode * namenode)294 searchoutput(struct fsys_namenode *namenode)
295 {
296 struct fsys_node_pkgs_iter *iter;
297 struct pkginfo *pkg_owner;
298 int found;
299
300 if (namenode->divert) {
301 const char *name_from = namenode->divert->camefrom ?
302 namenode->divert->camefrom->name : namenode->name;
303 const char *name_to = namenode->divert->useinstead ?
304 namenode->divert->useinstead->name : namenode->name;
305
306 if (namenode->divert->pkgset) {
307 printf(_("diversion by %s from: %s\n"),
308 namenode->divert->pkgset->name, name_from);
309 printf(_("diversion by %s to: %s\n"),
310 namenode->divert->pkgset->name, name_to);
311 } else {
312 printf(_("local diversion from: %s\n"), name_from);
313 printf(_("local diversion to: %s\n"), name_to);
314 }
315 }
316 found= 0;
317
318 iter = fsys_node_pkgs_iter_new(namenode);
319 while ((pkg_owner = fsys_node_pkgs_iter_next(iter))) {
320 if (found)
321 fputs(", ", stdout);
322 fputs(pkg_name(pkg_owner, pnaw_nonambig), stdout);
323 found++;
324 }
325 fsys_node_pkgs_iter_free(iter);
326
327 if (found) printf(": %s\n",namenode->name);
328 return found + (namenode->divert ? 1 : 0);
329 }
330
331 static int
searchfiles(const char * const * argv)332 searchfiles(const char *const *argv)
333 {
334 struct fsys_namenode *namenode;
335 struct fsys_hash_iter *iter;
336 const char *thisarg;
337 int found;
338 int failures = 0;
339 struct varbuf path = VARBUF_INIT;
340 static struct varbuf vb;
341
342 if (!*argv)
343 badusage(_("--search needs at least one file name pattern argument"));
344
345 modstatdb_open(msdbrw_readonly);
346 ensure_allinstfiles_available_quiet();
347 ensure_diversions();
348
349 while ((thisarg = *argv++) != NULL) {
350 found= 0;
351
352 if (!strchr("*[?/",*thisarg)) {
353 varbuf_reset(&vb);
354 varbuf_add_char(&vb, '*');
355 varbuf_add_str(&vb, thisarg);
356 varbuf_add_char(&vb, '*');
357 varbuf_end_str(&vb);
358 thisarg= vb.buf;
359 }
360 if (!strpbrk(thisarg, "*[?\\")) {
361 /* Trim trailing ‘/’ and ‘/.’ from the argument if it is not
362 * a pattern, just a pathname. */
363 varbuf_reset(&path);
364 varbuf_add_str(&path, thisarg);
365 varbuf_end_str(&path);
366 varbuf_trunc(&path, path_trim_slash_slashdot(path.buf));
367
368 namenode = fsys_hash_find_node(path.buf, 0);
369 found += searchoutput(namenode);
370 } else {
371 iter = fsys_hash_iter_new();
372 while ((namenode = fsys_hash_iter_next(iter)) != NULL) {
373 if (fnmatch(thisarg,namenode->name,0)) continue;
374 found+= searchoutput(namenode);
375 }
376 fsys_hash_iter_free(iter);
377 }
378 if (!found) {
379 notice(_("no path found matching pattern %s"), thisarg);
380 failures++;
381 m_output(stderr, _("<standard error>"));
382 } else {
383 m_output(stdout, _("<standard output>"));
384 }
385 }
386 modstatdb_shutdown();
387
388 varbuf_destroy(&path);
389
390 return failures;
391 }
392
393 static int
print_status(const char * const * argv)394 print_status(const char *const *argv)
395 {
396 const char *thisarg;
397 struct pkginfo *pkg;
398 int failures = 0;
399
400 modstatdb_open(msdbrw_readonly);
401
402 if (!*argv) {
403 writedb_records(stdout, _("<standard output>"), 0);
404 } else {
405 while ((thisarg = *argv++) != NULL) {
406 pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
407
408 if (pkg->status == PKG_STAT_NOTINSTALLED &&
409 pkg->priority == PKG_PRIO_UNKNOWN &&
410 str_is_unset(pkg->section) &&
411 !pkg->archives &&
412 pkg->want == PKG_WANT_UNKNOWN &&
413 !pkg_is_informative(pkg, &pkg->installed)) {
414 notice(_("package '%s' is not installed and no information is available"),
415 pkg_name(pkg, pnaw_nonambig));
416 failures++;
417 } else {
418 writerecord(stdout, _("<standard output>"), pkg, &pkg->installed);
419 }
420
421 if (*argv != NULL)
422 putchar('\n');
423 }
424 }
425
426 m_output(stdout, _("<standard output>"));
427 if (failures) {
428 fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files.\n"),
429 stderr);
430 m_output(stderr, _("<standard error>"));
431 }
432
433 modstatdb_shutdown();
434
435 return failures;
436 }
437
438 static int
print_avail(const char * const * argv)439 print_avail(const char *const *argv)
440 {
441 const char *thisarg;
442 struct pkginfo *pkg;
443 int failures = 0;
444
445 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
446
447 if (!*argv) {
448 writedb_records(stdout, _("<standard output>"), wdb_dump_available);
449 } else {
450 while ((thisarg = *argv++) != NULL) {
451 pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
452
453 if (!pkg_is_informative(pkg, &pkg->available)) {
454 notice(_("package '%s' is not available"),
455 pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
456 failures++;
457 } else {
458 writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
459 }
460
461 if (*argv != NULL)
462 putchar('\n');
463 }
464 }
465
466 m_output(stdout, _("<standard output>"));
467 if (failures)
468 m_output(stderr, _("<standard error>"));
469
470 modstatdb_shutdown();
471
472 return failures;
473 }
474
475 static int
list_files(const char * const * argv)476 list_files(const char *const *argv)
477 {
478 const char *thisarg;
479 struct fsys_namenode_list *file;
480 struct pkginfo *pkg;
481 struct fsys_namenode *namenode;
482 int failures = 0;
483
484 if (!*argv)
485 badusage(_("--%s needs at least one package name argument"), cipaction->olong);
486
487 modstatdb_open(msdbrw_readonly);
488
489 while ((thisarg = *argv++) != NULL) {
490 pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
491
492 switch (pkg->status) {
493 case PKG_STAT_NOTINSTALLED:
494 notice(_("package '%s' is not installed"),
495 pkg_name(pkg, pnaw_nonambig));
496 failures++;
497 break;
498 default:
499 ensure_packagefiles_available(pkg);
500 ensure_diversions();
501 file = pkg->files;
502 if (!file) {
503 printf(_("Package '%s' does not contain any files (!)\n"),
504 pkg_name(pkg, pnaw_nonambig));
505 } else {
506 while (file) {
507 namenode = file->namenode;
508 puts(namenode->name);
509 if (namenode->divert && !namenode->divert->camefrom) {
510 if (!namenode->divert->pkgset)
511 printf(_("locally diverted to: %s\n"),
512 namenode->divert->useinstead->name);
513 else if (pkg->set == namenode->divert->pkgset)
514 printf(_("package diverts others to: %s\n"),
515 namenode->divert->useinstead->name);
516 else
517 printf(_("diverted by %s to: %s\n"),
518 namenode->divert->pkgset->name,
519 namenode->divert->useinstead->name);
520 }
521 file = file->next;
522 }
523 }
524 break;
525 }
526
527 if (*argv != NULL)
528 putchar('\n');
529 }
530
531 m_output(stdout, _("<standard output>"));
532 if (failures) {
533 fputs(_("Use dpkg --contents (= dpkg-deb --contents) to list archive files contents.\n"),
534 stderr);
535 m_output(stderr, _("<standard error>"));
536 }
537
538 modstatdb_shutdown();
539
540 return failures;
541 }
542
543 static void
pkg_array_show_item(struct pkg_array * array,struct pkginfo * pkg,void * pkg_data)544 pkg_array_show_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
545 {
546 struct pkg_format_node *fmt = pkg_data;
547
548 pkg_format_show(fmt, pkg, &pkg->installed);
549 }
550
551 static int
showpackages(const char * const * argv)552 showpackages(const char *const *argv)
553 {
554 struct dpkg_error err;
555 struct pkg_array array;
556 struct pkginfo *pkg;
557 struct pkg_format_node *fmt;
558 int i;
559 int rc = 0;
560
561 fmt = pkg_format_parse(showformat, &err);
562 if (!fmt) {
563 notice(_("error in show format: %s"), err.str);
564 dpkg_error_destroy(&err);
565 rc++;
566 return rc;
567 }
568
569 if (!opt_loadavail)
570 modstatdb_open(msdbrw_readonly);
571 else
572 modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
573
574 pkg_array_init_from_hash(&array);
575 pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
576
577 if (!*argv) {
578 for (i = 0; i < array.n_pkgs; i++) {
579 pkg = array.pkgs[i];
580 if (pkg->status == PKG_STAT_NOTINSTALLED)
581 continue;
582 pkg_format_show(fmt, pkg, &pkg->installed);
583 }
584 } else {
585 rc = pkg_array_match_patterns(&array, pkg_array_show_item, fmt, argv);
586 }
587
588 m_output(stdout, _("<standard output>"));
589 m_output(stderr, _("<standard error>"));
590
591 pkg_array_destroy(&array);
592 pkg_format_free(fmt);
593 modstatdb_shutdown();
594
595 return rc;
596 }
597
598 static bool
pkg_infodb_is_internal(const char * filetype)599 pkg_infodb_is_internal(const char *filetype)
600 {
601 /* Do not expose internal database files. */
602 if (strcmp(filetype, LISTFILE) == 0 ||
603 strcmp(filetype, CONFFILESFILE) == 0)
604 return true;
605
606 if (strlen(filetype) > MAXCONTROLFILENAME)
607 return true;
608
609 return false;
610 }
611
612 static void
pkg_infodb_check_filetype(const char * filetype)613 pkg_infodb_check_filetype(const char *filetype)
614 {
615 const char *c;
616
617 /* Validate control file name for sanity. */
618 for (c = "/."; *c; c++)
619 if (strchr(filetype, *c))
620 badusage(_("control file contains %c"), *c);
621 }
622
623 static void
pkg_infodb_print_filename(const char * filename,const char * filetype)624 pkg_infodb_print_filename(const char *filename, const char *filetype)
625 {
626 if (pkg_infodb_is_internal(filetype))
627 return;
628
629 printf("%s\n", filename);
630 }
631
632 static void
pkg_infodb_print_filetype(const char * filename,const char * filetype)633 pkg_infodb_print_filetype(const char *filename, const char *filetype)
634 {
635 if (pkg_infodb_is_internal(filetype))
636 return;
637
638 printf("%s\n", filetype);
639 }
640
641 static void
control_path_file(struct pkginfo * pkg,const char * control_file)642 control_path_file(struct pkginfo *pkg, const char *control_file)
643 {
644 const char *control_pathname;
645 struct stat st;
646
647 control_pathname = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
648 if (stat(control_pathname, &st) < 0)
649 return;
650 if (!S_ISREG(st.st_mode))
651 return;
652
653 pkg_infodb_print_filename(control_pathname, control_file);
654 }
655
656 static int
control_path(const char * const * argv)657 control_path(const char *const *argv)
658 {
659 struct pkginfo *pkg;
660 const char *pkgname;
661 const char *control_file;
662
663 pkgname = *argv++;
664 if (!pkgname)
665 badusage(_("--%s needs at least one package name argument"),
666 cipaction->olong);
667
668 control_file = *argv++;
669 if (control_file && *argv)
670 badusage(_("--%s takes at most two arguments"), cipaction->olong);
671
672 if (control_file)
673 pkg_infodb_check_filetype(control_file);
674
675 modstatdb_open(msdbrw_readonly);
676
677 pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
678 if (pkg->status == PKG_STAT_NOTINSTALLED)
679 ohshit(_("package '%s' is not installed"),
680 pkg_name(pkg, pnaw_nonambig));
681
682 if (control_file)
683 control_path_file(pkg, control_file);
684 else
685 pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filename);
686
687 modstatdb_shutdown();
688
689 return 0;
690 }
691
692 static int
control_list(const char * const * argv)693 control_list(const char *const *argv)
694 {
695 struct pkginfo *pkg;
696 const char *pkgname;
697
698 pkgname = *argv++;
699 if (!pkgname || *argv)
700 badusage(_("--%s takes one package name argument"), cipaction->olong);
701
702 modstatdb_open(msdbrw_readonly);
703
704 pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
705 if (pkg->status == PKG_STAT_NOTINSTALLED)
706 ohshit(_("package '%s' is not installed"), pkg_name(pkg, pnaw_nonambig));
707
708 pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filetype);
709
710 modstatdb_shutdown();
711
712 return 0;
713 }
714
715 static int
control_show(const char * const * argv)716 control_show(const char *const *argv)
717 {
718 struct pkginfo *pkg;
719 const char *pkgname;
720 const char *filename;
721 const char *control_file;
722
723 pkgname = *argv++;
724 if (!pkgname || !*argv)
725 badusage(_("--%s takes exactly two arguments"),
726 cipaction->olong);
727
728 control_file = *argv++;
729 if (!control_file || *argv)
730 badusage(_("--%s takes exactly two arguments"), cipaction->olong);
731
732 pkg_infodb_check_filetype(control_file);
733
734 modstatdb_open(msdbrw_readonly);
735
736 pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
737 if (pkg->status == PKG_STAT_NOTINSTALLED)
738 ohshit(_("package '%s' is not installed"), pkg_name(pkg, pnaw_nonambig));
739
740 if (pkg_infodb_has_file(pkg, &pkg->installed, control_file))
741 filename = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
742 else
743 ohshit(_("control file '%s' does not exist"), control_file);
744
745 modstatdb_shutdown();
746
747 file_show(filename);
748
749 return 0;
750 }
751
752 static void
set_no_pager(const struct cmdinfo * ci,const char * value)753 set_no_pager(const struct cmdinfo *ci, const char *value)
754 {
755 pager_enable(false);
756 }
757
758 static void DPKG_ATTR_NORET
printversion(const struct cmdinfo * ci,const char * value)759 printversion(const struct cmdinfo *ci, const char *value)
760 {
761 printf(_("Debian %s package management program query tool version %s.\n"),
762 DPKGQUERY, PACKAGE_RELEASE);
763 printf(_(
764 "This is free software; see the GNU General Public License version 2 or\n"
765 "later for copying conditions. There is NO warranty.\n"));
766
767 m_output(stdout, _("<standard output>"));
768
769 exit(0);
770 }
771
772 static void DPKG_ATTR_NORET
usage(const struct cmdinfo * ci,const char * value)773 usage(const struct cmdinfo *ci, const char *value)
774 {
775 printf(_(
776 "Usage: %s [<option> ...] <command>\n"
777 "\n"), DPKGQUERY);
778
779 printf(_(
780 "Commands:\n"
781 " -s, --status [<package>...] Display package status details.\n"
782 " -p, --print-avail [<package>...] Display available version details.\n"
783 " -L, --listfiles <package>... List files 'owned' by package(s).\n"
784 " -l, --list [<pattern>...] List packages concisely.\n"
785 " -W, --show [<pattern>...] Show information on package(s).\n"
786 " -S, --search <pattern>... Find package(s) owning file(s).\n"
787 " --control-list <package> Print the package control file list.\n"
788 " --control-show <package> <file>\n"
789 " Show the package control file.\n"
790 " -c, --control-path <package> [<file>]\n"
791 " Print path for package control file.\n"
792 "\n"));
793
794 printf(_(
795 " -?, --help Show this help message.\n"
796 " --version Show the version.\n"
797 "\n"));
798
799 printf(_(
800 "Options:\n"
801 " --admindir=<directory> Use <directory> instead of %s.\n"
802 " --load-avail Use available file on --show and --list.\n"
803 " -f|--showformat=<format> Use alternative format for --show.\n"
804 "\n"), ADMINDIR);
805
806 printf(_(
807 "Format syntax:\n"
808 " A format is a string that will be output for each package. The format\n"
809 " can include the standard escape sequences \\n (newline), \\r (carriage\n"
810 " return) or \\\\ (plain backslash). Package information can be included\n"
811 " by inserting variable references to package fields using the ${var[;width]}\n"
812 " syntax. Fields will be right-aligned unless the width is negative in which\n"
813 " case left alignment will be used.\n"));
814
815 m_output(stdout, _("<standard output>"));
816
817 exit(0);
818 }
819
820 static const char printforhelp[] = N_(
821 "Use --help for help about querying packages.");
822
823 static const char *admindir;
824
825 /* This table has both the action entries in it and the normal options.
826 * The action entries are made with the ACTION macro, as they all
827 * have a very similar structure. */
828 static const struct cmdinfo cmdinfos[]= {
829 ACTION( "listfiles", 'L', act_listfiles, list_files ),
830 ACTION( "status", 's', act_status, print_status ),
831 ACTION( "print-avail", 'p', act_printavail, print_avail ),
832 ACTION( "list", 'l', act_listpackages, listpackages ),
833 ACTION( "search", 'S', act_searchfiles, searchfiles ),
834 ACTION( "show", 'W', act_listpackages, showpackages ),
835 ACTION( "control-path", 'c', act_controlpath, control_path ),
836 ACTION( "control-list", 0, act_controllist, control_list ),
837 ACTION( "control-show", 0, act_controlshow, control_show ),
838
839 { "admindir", 0, 1, NULL, &admindir, NULL },
840 { "load-avail", 0, 0, &opt_loadavail, NULL, NULL, 1 },
841 { "showformat", 'f', 1, NULL, &showformat, NULL },
842 { "no-pager", 0, 0, NULL, NULL, set_no_pager },
843 { "help", '?', 0, NULL, NULL, usage },
844 { "version", 0, 0, NULL, NULL, printversion },
845 { NULL, 0, 0, NULL, NULL, NULL }
846 };
847
main(int argc,const char * const * argv)848 int main(int argc, const char *const *argv) {
849 int ret;
850
851 dpkg_set_report_piped_mode(_IOFBF);
852 dpkg_locales_init(PACKAGE);
853 dpkg_program_init("dpkg-query");
854 dpkg_options_parse(&argv, cmdinfos, printforhelp);
855
856 admindir = dpkg_db_set_dir(admindir);
857
858 if (!cipaction) badusage(_("need an action option"));
859
860 fsys_hash_init();
861
862 ret = cipaction->action(argv);
863
864 dpkg_program_done();
865
866 return !!ret;
867 }
868