chiark / gitweb /
lib/dpkg/tarfn.c: Kludge `tar_header_decode' to handle spurious `errno'.
[dpkg] / src / querycmd.c
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
62 static const char *showformat = "${binary:Package}\t${Version}\n";
63
64 static int opt_loadavail = 0;
65
66 static 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
98 static int
99 pkg_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
147 struct list_format {
148   bool head;
149   int nw;
150   int vw;
151   int aw;
152   int dw;
153 };
154
155 static void
156 list_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
211 static void
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)
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
231 static void
232 list_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(_("\
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);
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
278 static void
279 pkg_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
301 static int
302 listpackages(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
341 static 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
377 static int
378 searchfiles(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
439 static int
440 enqperpackage(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
539 static void
540 pkg_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
547 static int
548 showpackages(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
594 static bool
595 pkg_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
608 static void
609 pkg_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
619 static void
620 pkg_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
628 static void
629 pkg_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
637 static void
638 control_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
652 static int
653 control_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
688 static int
689 control_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
711 static int
712 control_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
748 static void DPKG_ATTR_NORET
749 printversion(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
762 static void DPKG_ATTR_NORET
763 usage(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
810 static const char printforhelp[] = N_(
811 "Use --help for help about querying packages.");
812
813 static 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. */
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    ),
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
837 int 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 }