LCOV - code coverage report
Current view: top level - lib/dpkg - pkg-show.c (source / functions) Hit Total Coverage
Test: dpkg 1.21.11 C code coverage Lines: 60 114 52.6 %
Date: 2022-12-03 00:40:01 Functions: 8 19 42.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 25 54 46.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * libdpkg - Debian packaging suite library routines
       3                 :            :  * pkg-show.c - primitives for pkg information display
       4                 :            :  *
       5                 :            :  * Copyright © 1995,1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
       6                 :            :  * Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
       7                 :            :  *
       8                 :            :  * This is free software; you can redistribute it and/or modify
       9                 :            :  * it under the terms of the GNU General Public License as published by
      10                 :            :  * the Free Software Foundation; either version 2 of the License, or
      11                 :            :  * (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : #include <compat.h>
      24                 :            : 
      25                 :            : #include <string.h>
      26                 :            : 
      27                 :            : #include <dpkg/macros.h>
      28                 :            : #include <dpkg/i18n.h>
      29                 :            : #include <dpkg/dpkg.h>
      30                 :            : #include <dpkg/dpkg-db.h>
      31                 :            : #include <dpkg/pkg-show.h>
      32                 :            : 
      33                 :            : static bool
      34                 :         13 : pkgbin_name_needs_arch(const struct pkgbin *pkgbin,
      35                 :            :                        enum pkg_name_arch_when pnaw)
      36                 :            : {
      37         [ +  + ]:         13 :         if (pkgbin->arch->type == DPKG_ARCH_NONE ||
      38         [ -  + ]:          5 :             pkgbin->arch->type == DPKG_ARCH_EMPTY)
      39                 :          8 :                 return false;
      40                 :            : 
      41   [ +  +  +  -  :          5 :         switch (pnaw) {
                   +  - ]
      42                 :          1 :         case pnaw_never:
      43                 :          1 :                 break;
      44                 :          2 :         case pnaw_same:
      45         [ +  + ]:          2 :                 if (pkgbin->multiarch == PKG_MULTIARCH_SAME)
      46                 :          1 :                         return true;
      47                 :          1 :                 return false;
      48                 :          1 :         case pnaw_nonambig:
      49         [ -  + ]:          1 :                 if (pkgbin->multiarch == PKG_MULTIARCH_SAME)
      50                 :          0 :                         return true;
      51                 :            :         /* Fall through. */
      52                 :            :         case pnaw_foreign:
      53         [ +  - ]:          1 :                 if (pkgbin->arch->type == DPKG_ARCH_NATIVE ||
      54         [ +  - ]:          1 :                     pkgbin->arch->type == DPKG_ARCH_ALL)
      55                 :            :                         break;
      56                 :            :         /* Fall through. */
      57                 :            :         case pnaw_always:
      58                 :          2 :                 return true;
      59                 :            :         }
      60                 :            : 
      61                 :          1 :         return false;
      62                 :            : }
      63                 :            : 
      64                 :            : /**
      65                 :            :  * Add a string representation of the package name to a varbuf.
      66                 :            :  *
      67                 :            :  * Works exactly like pkgbin_name() but acts on the varbuf instead of
      68                 :            :  * returning a string. It NUL terminates the varbuf.
      69                 :            :  *
      70                 :            :  * @param vb      The varbuf struct to modify.
      71                 :            :  * @param pkg     The package to consider.
      72                 :            :  * @param pkgbin  The binary package instance to consider.
      73                 :            :  * @param pnaw    When to display the architecture qualifier.
      74                 :            :  */
      75                 :            : void
      76                 :          0 : varbuf_add_pkgbin_name(struct varbuf *vb,
      77                 :            :                        const struct pkginfo *pkg, const struct pkgbin *pkgbin,
      78                 :            :                        enum pkg_name_arch_when pnaw)
      79                 :            : {
      80                 :          0 :         varbuf_add_str(vb, pkg->set->name);
      81         [ #  # ]:          0 :         if (pkgbin_name_needs_arch(pkgbin, pnaw))
      82                 :          0 :                 varbuf_add_archqual(vb, pkgbin->arch);
      83                 :          0 :         varbuf_end_str(vb);
      84                 :          0 : }
      85                 :            : 
      86                 :            : const char *
      87                 :         25 : pkgbin_name_archqual(const struct pkginfo *pkg, const struct pkgbin *pkgbin)
      88                 :            : {
      89                 :            :         char *pkgname;
      90                 :            : 
      91         [ +  - ]:         25 :         if (pkgbin->arch->type == DPKG_ARCH_NONE ||
      92         [ -  + ]:         25 :             pkgbin->arch->type == DPKG_ARCH_EMPTY)
      93                 :          0 :                 return pkg->set->name;
      94                 :            : 
      95                 :         25 :         pkgname = nfmalloc(strlen(pkg->set->name) + 1 +
      96                 :         25 :                            strlen(pkgbin->arch->name) + 1);
      97                 :         25 :         str_concat(pkgname, pkg->set->name, ":",
      98                 :         25 :                             pkgbin->arch->name, NULL);
      99                 :            : 
     100                 :         25 :         return pkgname;
     101                 :            : }
     102                 :            : 
     103                 :            : /**
     104                 :            :  * Return a string representation of the package name.
     105                 :            :  *
     106                 :            :  * The returned string must not be freed, and it's permanently allocated so
     107                 :            :  * can be used as long as the non-freeing memory pool has not been freed.
     108                 :            :  *
     109                 :            :  * Note, that this const variant will "leak" a new non-freeing string on
     110                 :            :  * each call if the internal cache has not been previously initialized,
     111                 :            :  * so it is advised to use it only in error reporting code paths.
     112                 :            :  *
     113                 :            :  * The pnaw parameter should be one of pnaw_never (never print arch),
     114                 :            :  * pnaw_foreign (print arch for foreign packages only), pnaw_nonambig (print
     115                 :            :  * arch for non ambiguous cases) or pnaw_always (always print arch),
     116                 :            :  *
     117                 :            :  * @param pkg     The package to consider.
     118                 :            :  * @param pkgbin  The binary package instance to consider.
     119                 :            :  * @param pnaw    When to display the architecture qualifier.
     120                 :            :  *
     121                 :            :  * @return The string representation.
     122                 :            :  */
     123                 :            : const char *
     124                 :          0 : pkgbin_name_const(const struct pkginfo *pkg, const struct pkgbin *pkgbin,
     125                 :            :             enum pkg_name_arch_when pnaw)
     126                 :            : {
     127         [ #  # ]:          0 :         if (!pkgbin_name_needs_arch(pkgbin, pnaw))
     128                 :          0 :                 return pkg->set->name;
     129                 :            : 
     130                 :            :         /* Return a non-freeing package name representation, which
     131                 :            :          * is intended to be used in error-handling code, as we will keep
     132                 :            :          * "leaking" them until the next memory pool flush. */
     133         [ #  # ]:          0 :         if (pkgbin->pkgname_archqual == NULL)
     134                 :          0 :                 return pkgbin_name_archqual(pkg, pkgbin);
     135                 :            : 
     136                 :          0 :         return pkgbin->pkgname_archqual;
     137                 :            : }
     138                 :            : 
     139                 :            : /**
     140                 :            :  * Return a string representation of the installed package name.
     141                 :            :  *
     142                 :            :  * This is equivalent to pkgbin_name_const() but just for its installed pkgbin.
     143                 :            :  *
     144                 :            :  * @param pkg   The package to consider.
     145                 :            :  * @param pnaw  When to display the architecture qualifier.
     146                 :            :  *
     147                 :            :  * @return The string representation.
     148                 :            :  */
     149                 :            : const char *
     150                 :          0 : pkg_name_const(const struct pkginfo *pkg, enum pkg_name_arch_when pnaw)
     151                 :            : {
     152                 :          0 :         return pkgbin_name_const(pkg, &pkg->installed, pnaw);
     153                 :            : }
     154                 :            : 
     155                 :            : /**
     156                 :            :  * Return a string representation of the package name.
     157                 :            :  *
     158                 :            :  * The returned string must not be freed, and it's permanently allocated so
     159                 :            :  * can be used as long as the non-freeing memory pool has not been freed.
     160                 :            :  *
     161                 :            :  * The pnaw parameter should be one of pnaw_never (never print arch),
     162                 :            :  * pnaw_foreign (print arch for foreign packages only), pnaw_nonambig (print
     163                 :            :  * arch for non ambiguous cases) or pnaw_always (always print arch),
     164                 :            :  *
     165                 :            :  * @param pkg     The package to consider.
     166                 :            :  * @param pkgbin  The binary package instance to consider.
     167                 :            :  * @param pnaw    When to display the architecture qualifier.
     168                 :            :  *
     169                 :            :  * @return The string representation.
     170                 :            :  */
     171                 :            : const char *
     172                 :         13 : pkgbin_name(struct pkginfo *pkg, struct pkgbin *pkgbin,
     173                 :            :             enum pkg_name_arch_when pnaw)
     174                 :            : {
     175         [ +  + ]:         13 :         if (!pkgbin_name_needs_arch(pkgbin, pnaw))
     176                 :         10 :                 return pkg->set->name;
     177                 :            : 
     178                 :            :         /* Cache the package name representation, for later reuse. */
     179         [ +  + ]:          3 :         if (pkgbin->pkgname_archqual == NULL)
     180                 :          1 :                 pkgbin->pkgname_archqual = pkgbin_name_archqual(pkg, pkgbin);
     181                 :            : 
     182                 :          3 :         return pkgbin->pkgname_archqual;
     183                 :            : }
     184                 :            : 
     185                 :            : /**
     186                 :            :  * Return a string representation of the installed package name.
     187                 :            :  *
     188                 :            :  * This is equivalent to pkgbin_name() but just for its installed pkgbin.
     189                 :            :  *
     190                 :            :  * @param pkg   The package to consider.
     191                 :            :  * @param pnaw  When to display the architecture qualifier.
     192                 :            :  *
     193                 :            :  * @return The string representation.
     194                 :            :  */
     195                 :            : const char *
     196                 :          5 : pkg_name(struct pkginfo *pkg, enum pkg_name_arch_when pnaw)
     197                 :            : {
     198                 :          5 :         return pkgbin_name(pkg, &pkg->installed, pnaw);
     199                 :            : }
     200                 :            : 
     201                 :            : /**
     202                 :            :  * Return a string representation of the package synopsis.
     203                 :            :  *
     204                 :            :  * The returned string must not be freed, and it's permanently allocated so
     205                 :            :  * can be used as long as the non-freeing memory pool has not been freed.
     206                 :            :  *
     207                 :            :  * The package synopsis is the short description, but it is not NUL terminated,
     208                 :            :  * so the output len argument should be used to limit the string length.
     209                 :            :  *
     210                 :            :  * @param pkg      The package to consider.
     211                 :            :  * @param pkgbin   The binary package instance to consider.
     212                 :            :  * @param[out] len The length of the synopsis string within the description.
     213                 :            :  *
     214                 :            :  * @return The string representation.
     215                 :            :  */
     216                 :            : const char *
     217                 :          2 : pkgbin_synopsis(const struct pkginfo *pkg, const struct pkgbin *pkgbin, int *len)
     218                 :            : {
     219                 :            :         const char *pdesc;
     220                 :            : 
     221                 :          2 :         pdesc = pkgbin->description;
     222         [ -  + ]:          2 :         if (!pdesc)
     223                 :          0 :                 pdesc = _("(no description available)");
     224                 :            : 
     225                 :          2 :         *len = strcspn(pdesc, "\n");
     226                 :            : 
     227                 :          2 :         return pdesc;
     228                 :            : }
     229                 :            : 
     230                 :            : /**
     231                 :            :  * Return a string representation of the package synopsis.
     232                 :            :  *
     233                 :            :  * The returned string must not be freed, and it's permanently allocated so
     234                 :            :  * can be used as long as the non-freeing memory pool has not been freed.
     235                 :            :  *
     236                 :            :  * It will try to use the installed version, otherwise it will fallback to
     237                 :            :  * use the available version.
     238                 :            :  *
     239                 :            :  * The package synopsis is the short description, but it is not NUL terminated,
     240                 :            :  * so the output len argument should be used to limit the string length.
     241                 :            :  *
     242                 :            :  * @param pkg      The package to consider.
     243                 :            :  * @param[out] len The length of the synopsis string within the description.
     244                 :            :  *
     245                 :            :  * @return The string representation.
     246                 :            :  */
     247                 :            : const char *
     248                 :          0 : pkg_synopsis(const struct pkginfo *pkg, int *len)
     249                 :            : {
     250                 :            :         const char *pdesc;
     251                 :            : 
     252                 :          0 :         pdesc = pkg->installed.description;
     253         [ #  # ]:          0 :         if (!pdesc)
     254                 :          0 :                 pdesc = pkg->available.description;
     255         [ #  # ]:          0 :         if (!pdesc)
     256                 :          0 :                 pdesc = _("(no description available)");
     257                 :            : 
     258                 :          0 :         *len = strcspn(pdesc, "\n");
     259                 :            : 
     260                 :          0 :         return pdesc;
     261                 :            : }
     262                 :            : 
     263                 :            : /**
     264                 :            :  * Return a character abbreviated representation of the package want status.
     265                 :            :  *
     266                 :            :  * @param pkg The package to consider.
     267                 :            :  *
     268                 :            :  * @return The character abbreviated representation.
     269                 :            :  */
     270                 :            : int
     271                 :          0 : pkg_abbrev_want(const struct pkginfo *pkg)
     272                 :            : {
     273                 :          0 :         return "uihrp"[pkg->want];
     274                 :            : }
     275                 :            : 
     276                 :            : /**
     277                 :            :  * Return a character abbreviated representation of the package current status.
     278                 :            :  *
     279                 :            :  * @param pkg The package to consider.
     280                 :            :  *
     281                 :            :  * @return The character abbreviated representation.
     282                 :            :  */
     283                 :            : int
     284                 :          0 : pkg_abbrev_status(const struct pkginfo *pkg)
     285                 :            : {
     286                 :          0 :         return "ncHUFWti"[pkg->status];
     287                 :            : }
     288                 :            : 
     289                 :            : /**
     290                 :            :  * Return a character abbreviated representation of the package eflag status.
     291                 :            :  *
     292                 :            :  * @param pkg The package to consider.
     293                 :            :  *
     294                 :            :  * @return The character abbreviated representation.
     295                 :            :  */
     296                 :            : int
     297                 :          0 : pkg_abbrev_eflag(const struct pkginfo *pkg)
     298                 :            : {
     299                 :          0 :         return " R"[pkg->eflag];
     300                 :            : }
     301                 :            : 
     302                 :            : /**
     303                 :            :  * Return a string representation of the package want status name.
     304                 :            :  *
     305                 :            :  * @param pkg The package to consider.
     306                 :            :  *
     307                 :            :  * @return The string representation.
     308                 :            :  */
     309                 :            : const char *
     310                 :          0 : pkg_want_name(const struct pkginfo *pkg)
     311                 :            : {
     312                 :          0 :         return wantinfos[pkg->want].name;
     313                 :            : }
     314                 :            : 
     315                 :            : /**
     316                 :            :  * Return a string representation of the package eflag status name.
     317                 :            :  *
     318                 :            :  * @param pkg The package to consider.
     319                 :            :  *
     320                 :            :  * @return The string representation.
     321                 :            :  */
     322                 :            : const char *
     323                 :          0 : pkg_eflag_name(const struct pkginfo *pkg)
     324                 :            : {
     325                 :          0 :         return eflaginfos[pkg->eflag].name;
     326                 :            : }
     327                 :            : 
     328                 :            : /**
     329                 :            :  * Return a string representation of the package current status name.
     330                 :            :  *
     331                 :            :  * @param pkg The package to consider.
     332                 :            :  *
     333                 :            :  * @return The string representation.
     334                 :            :  */
     335                 :            : const char *
     336                 :          0 : pkg_status_name(const struct pkginfo *pkg)
     337                 :            : {
     338                 :          0 :         return statusinfos[pkg->status].name;
     339                 :            : }
     340                 :            : 
     341                 :            : /**
     342                 :            :  * Return a string representation of the package priority name.
     343                 :            :  *
     344                 :            :  * @param pkg The package to consider.
     345                 :            :  *
     346                 :            :  * @return The string representation.
     347                 :            :  */
     348                 :            : const char *
     349                 :          2 : pkg_priority_name(const struct pkginfo *pkg)
     350                 :            : {
     351         [ -  + ]:          2 :         if (pkg->priority == PKG_PRIO_OTHER)
     352                 :          0 :                 return pkg->otherpriority;
     353                 :            :         else
     354                 :          2 :                 return priorityinfos[pkg->priority].name;
     355                 :            : }
     356                 :            : 
     357                 :            : /**
     358                 :            :  * Compare a package to be sorted by non-ambiguous name and architecture.
     359                 :            :  *
     360                 :            :  * @param a A pointer of a pointer to a struct pkginfo.
     361                 :            :  * @param b A pointer of a pointer to a struct pkginfo.
     362                 :            :  *
     363                 :            :  * @return An integer with the result of the comparison.
     364                 :            :  * @retval -1 a is earlier than b.
     365                 :            :  * @retval 0 a is equal to b.
     366                 :            :  * @retval 1 a is later than b.
     367                 :            :  */
     368                 :            : int
     369                 :          0 : pkg_sorter_by_nonambig_name_arch(const void *a, const void *b)
     370                 :            : {
     371                 :          0 :         const struct pkginfo *pa = *(const struct pkginfo **)a;
     372                 :          0 :         const struct pkginfo *pb = *(const struct pkginfo **)b;
     373                 :          0 :         const struct pkgbin *pbina = &pa->installed;
     374                 :          0 :         const struct pkgbin *pbinb = &pb->installed;
     375                 :            :         int res;
     376                 :            : 
     377                 :          0 :         res = strcmp(pa->set->name, pb->set->name);
     378         [ #  # ]:          0 :         if (res)
     379                 :          0 :                 return res;
     380                 :            : 
     381         [ #  # ]:          0 :         if (pbina->arch == pbinb->arch)
     382                 :          0 :                 return 0;
     383                 :            : 
     384         [ #  # ]:          0 :         if (pkgbin_name_needs_arch(pbina, pnaw_nonambig)) {
     385         [ #  # ]:          0 :                 if (pkgbin_name_needs_arch(pbinb, pnaw_nonambig))
     386                 :          0 :                         return strcmp(pbina->arch->name, pbinb->arch->name);
     387                 :            :                 else
     388                 :          0 :                         return 1;
     389                 :            :         } else {
     390                 :          0 :                 return -1;
     391                 :            :         }
     392                 :            : }
     393                 :            : 
     394                 :            : /**
     395                 :            :  * Add a string representation of the source package version to a varbuf.
     396                 :            :  *
     397                 :            :  * It parses the Source field (if present), and extracts the optional
     398                 :            :  * version enclosed in parenthesis. Otherwise it fallsback to use the
     399                 :            :  * binary package version. It NUL terminates the varbuf.
     400                 :            :  *
     401                 :            :  * @param vb      The varbuf struct to modify.
     402                 :            :  * @param pkg     The package to consider.
     403                 :            :  * @param pkgbin  The binary package instance to consider.
     404                 :            :  */
     405                 :            : void
     406                 :          3 : varbuf_add_source_version(struct varbuf *vb,
     407                 :            :                           const struct pkginfo *pkg, const struct pkgbin *pkgbin)
     408                 :            : {
     409                 :          3 :         struct dpkg_version version = DPKG_VERSION_INIT;
     410                 :            : 
     411                 :          3 :         pkg_source_version(&version, pkg, pkgbin);
     412                 :          3 :         varbufversion(vb, &version, vdew_nonambig);
     413                 :          3 :         varbuf_end_str(vb);
     414                 :          3 : }
     415                 :            : 
     416                 :            : void
     417                 :          5 : pkg_source_version(struct dpkg_version *version,
     418                 :            :                    const struct pkginfo *pkg, const struct pkgbin *pkgbin)
     419                 :            : {
     420                 :            :         const char *version_str;
     421                 :            : 
     422         [ +  + ]:          5 :         if (pkgbin->source)
     423                 :          4 :                 version_str = strchr(pkgbin->source, '(');
     424                 :            :         else
     425                 :          1 :                 version_str = NULL;
     426                 :            : 
     427         [ +  + ]:          5 :         if (version_str == NULL) {
     428                 :          3 :                 *version = pkgbin->version;
     429                 :            :         } else {
     430                 :            :                 struct dpkg_error err;
     431                 :          2 :                 struct varbuf vb = VARBUF_INIT;
     432                 :            :                 size_t len;
     433                 :            : 
     434                 :          2 :                 version_str++;
     435                 :          2 :                 len = strcspn(version_str, ")");
     436                 :          2 :                 varbuf_add_buf(&vb, version_str, len);
     437                 :          2 :                 varbuf_end_str(&vb);
     438                 :            : 
     439         [ -  + ]:          2 :                 if (parseversion(version, vb.buf, &err) < 0)
     440                 :          0 :                         ohshit(_("version '%s' has bad syntax: %s"),
     441                 :            :                                vb.buf, err.str);
     442                 :            :         }
     443                 :          5 : }

Generated by: LCOV version 1.16