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