LCOV - code coverage report
Current view: top level - src/query - main.c (source / functions) Coverage Total Hit
Test: dpkg 1.22.7-3-g89f48 C code coverage Lines: 4.1 % 386 16
Test Date: 2024-07-17 02:53:43 Functions: 7.7 % 26 2
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0.5 % 192 1

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

Generated by: LCOV version 2.0-1