LCOV - code coverage report
Current view: top level - src - utils.c (source / functions) Hit Total Coverage
Test: plop Lines: 391 729 53.6 %
Date: 2024-12-30 07:09:03 Functions: 10 13 76.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 243 598 40.6 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
       5                 :            :  * Copyright (c) 2012-2015 Matthew Seaman <matthew@FreeBSD.org>
       6                 :            :  * Copyright (c) 2013-2016 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       7                 :            :  *
       8                 :            :  * SPDX-License-Identifier: BSD-2-Clause
       9                 :            :  */
      10                 :            : 
      11                 :            : #ifdef HAVE_CONFIG_H
      12                 :            : #include "pkg_config.h"
      13                 :            : #endif
      14                 :            : 
      15                 :            : #include <sys/param.h>
      16                 :            : #include <sys/stat.h>
      17                 :            : 
      18                 :            : #include <err.h>
      19                 :            : #include <fcntl.h>
      20                 :            : #include <grp.h>
      21                 :            : #include <inttypes.h>
      22                 :            : #ifdef HAVE_LIBUTIL_H
      23                 :            : #include <libutil.h>
      24                 :            : #endif
      25                 :            : #include <string.h>
      26                 :            : #include <unistd.h>
      27                 :            : #include <stdarg.h>
      28                 :            : #include <paths.h>
      29                 :            : #include <stdio.h>
      30                 :            : #include <stdlib.h>
      31                 :            : #include <errno.h>
      32                 :            : #include <pwd.h>
      33                 :            : #include <pkg.h>
      34                 :            : #include <tllist.h>
      35                 :            : #include <xmalloc.h>
      36                 :            : 
      37                 :            : #include <bsd_compat.h>
      38                 :            : 
      39                 :            : #include "pkgcli.h"
      40                 :            : 
      41                 :            : struct jobs_sum_number {
      42                 :            :         int install;
      43                 :            :         int reinstall;
      44                 :            :         int downgrade;
      45                 :            :         int upgrade;
      46                 :            :         int delete;
      47                 :            :         int fetch;
      48                 :            :         int group_install;
      49                 :            :         int group_upgrade;
      50                 :            : };
      51                 :            : 
      52                 :            : void
      53                 :          0 : append_yesno(bool r, char *yesnomsg, size_t len)
      54                 :            : {
      55                 :            :         static const char       trunc[] = "\n[truncated] ";
      56                 :            :         /* These two strings must be the same length. */
      57                 :            :         static const char       yes[] = "[Y/n]: ";
      58                 :            :         static const char       no[] = "[y/N]: ";
      59                 :            : 
      60                 :          0 :         size_t  msglen = strlen(yesnomsg);
      61                 :            : 
      62         [ #  # ]:          0 :         if (msglen > len - sizeof yes) {
      63                 :          0 :                 yesnomsg[len - sizeof trunc - sizeof yes] = '\0';
      64                 :          0 :                 strlcat(yesnomsg, trunc, len);
      65                 :          0 :         }
      66                 :          0 :         strlcat(yesnomsg, r ? yes : no, len);
      67                 :          0 : }
      68                 :            : 
      69                 :            : bool
      70                 :          0 : query_tty_yesno(bool r, const char *msg, ...)
      71                 :            : {
      72                 :            :         int      c;
      73                 :            :         va_list  ap;
      74                 :            :         int      tty_fd;
      75                 :            :         FILE    *tty;
      76                 :          0 :         int      tty_flags = O_RDWR;
      77                 :            :         char    yesnomsg[65536];
      78                 :            : 
      79                 :            : #ifdef O_TTY_INIT
      80                 :          0 :         tty_flags |= O_TTY_INIT;
      81                 :            : #endif
      82                 :          0 :         tty_fd = open(_PATH_TTY, tty_flags);
      83         [ #  # ]:          0 :         if (tty_fd == -1) {
      84                 :            :                 /* No ctty -- return the default answer */
      85         [ #  # ]:          0 :                 if (default_yes)
      86                 :          0 :                         return (true);
      87                 :          0 :                 return (r);
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         tty = fdopen(tty_fd, "r+");
      91                 :            : 
      92                 :          0 :         strlcpy(yesnomsg, msg, sizeof(yesnomsg));
      93   [ #  #  #  # ]:          0 :         append_yesno(default_yes || r, yesnomsg, sizeof yesnomsg);
      94                 :            : 
      95                 :          0 :         va_start(ap, msg);
      96                 :          0 :         pkg_vfprintf(tty, yesnomsg, ap);
      97                 :          0 :         va_end(ap);
      98                 :            : 
      99                 :          0 :         fflush(tty);
     100   [ #  #  #  # ]:          0 :         c = getc(tty);
     101   [ #  #  #  # ]:          0 :         if (c == 'y' || c == 'Y')
     102                 :          0 :                 r = true;
     103   [ #  #  #  # ]:          0 :         else if (c == 'n' || c == 'N')
     104                 :          0 :                 r = false;
     105   [ #  #  #  # ]:          0 :         else if (c == '\n' || c == EOF) {
     106         [ #  # ]:          0 :                 if (default_yes)
     107                 :          0 :                         r = true;
     108                 :            :                 /* Else, r is not modified. It's default value is kept. */
     109                 :          0 :                 goto cleanup;
     110                 :            :         }
     111                 :            : 
     112   [ #  #  #  #  :          0 :         while ((c = getc(tty)) != '\n' && c != EOF)
          #  #  #  #  #  
                      # ]
     113                 :          0 :                 continue;
     114                 :            : 
     115                 :            : cleanup:
     116                 :          0 :         fclose(tty);
     117                 :            : 
     118                 :          0 :         return (r);
     119                 :          0 : }
     120                 :            : 
     121                 :            : static bool
     122                 :         94 : vquery_yesno(bool deft, const char *msg, va_list ap)
     123                 :            : {
     124                 :         94 :         char *line = NULL;
     125                 :            :         char *out;
     126                 :         94 :         size_t linecap = 0;
     127                 :            :         int linelen;
     128                 :         94 :         bool     r = deft;
     129                 :            :         char    yesnomsg[65536];
     130                 :            : 
     131                 :            :         /* We use default value of yes or default in case of quiet mode */
     132         [ -  + ]:         94 :         if (quiet)
     133   [ #  #  #  #  :          0 :                 return (yes || default_yes || r);
                   #  # ]
     134                 :            : 
     135         [ -  + ]:         94 :         if (dry_run)
     136   [ #  #  #  #  :          0 :                 return (yes || default_yes || r );
                   #  # ]
     137                 :            : 
     138                 :            :         /* Do not query user if we have specified yes flag */
     139         [ +  - ]:         94 :         if (yes)
     140                 :         94 :                 return (true);
     141                 :            : 
     142                 :          0 :         strlcpy(yesnomsg, msg, sizeof(yesnomsg));
     143   [ #  #  #  # ]:          0 :         append_yesno(default_yes || r, yesnomsg, sizeof yesnomsg);
     144                 :            : 
     145                 :          0 :         pkg_vasprintf(&out, yesnomsg, ap);
     146                 :          0 :         printf("%s", out);
     147                 :            : 
     148                 :          0 :         for (;;) {
     149         [ #  # ]:          0 :                 if ((linelen = getline(&line, &linecap, stdin)) != -1) {
     150                 :            : 
     151   [ #  #  #  # ]:          0 :                         if (linelen == 1 && line[0] == '\n') {
     152         [ #  # ]:          0 :                                 if (default_yes)
     153                 :          0 :                                         r = true;
     154                 :          0 :                                 break;
     155                 :            :                         }
     156         [ #  # ]:          0 :                         else if (linelen == 2) {
     157   [ #  #  #  # ]:          0 :                                 if (line[0] == 'y' || line[0] == 'Y') {
     158                 :          0 :                                         r = true;
     159                 :          0 :                                         break;
     160                 :            :                                 }
     161   [ #  #  #  # ]:          0 :                                 else if (line[0] == 'n' || line[0] == 'N') {
     162                 :          0 :                                         r = false;
     163                 :          0 :                                         break;
     164                 :            :                                 }
     165                 :          0 :                         }
     166                 :            :                         else {
     167         [ #  # ]:          0 :                                 if (STRIEQ(line, "yes\n")) {
     168                 :          0 :                                         r = true;
     169                 :          0 :                                         break;
     170                 :            :                                 }
     171         [ #  # ]:          0 :                                 else if (STRIEQ(line, "no\n")) {
     172                 :          0 :                                         r = false;
     173                 :          0 :                                         break;
     174                 :            :                                 }
     175                 :            :                         }
     176                 :          0 :                         printf("Please type 'Y[es]' or 'N[o]' to make a selection\n");
     177                 :          0 :                         printf("%s", out);
     178                 :          0 :                 }
     179                 :            :                 else {
     180         [ #  # ]:          0 :                         if (errno == EINTR) {
     181                 :          0 :                                 continue;
     182                 :            :                         } else {
     183         [ #  # ]:          0 :                                 if (default_yes) {
     184                 :          0 :                                         r = true;
     185                 :            :                                 /* Else, assume EOF as false */
     186                 :          0 :                                 } else {
     187                 :          0 :                                         r = false;
     188                 :            :                                 }
     189                 :          0 :                                 break;
     190                 :            :                         }
     191                 :            :                 }
     192                 :            :         }
     193                 :            : 
     194                 :          0 :         free(line);
     195                 :          0 :         free(out);
     196                 :            : 
     197                 :          0 :         return (r);
     198                 :         94 : }
     199                 :            : 
     200                 :            : bool
     201                 :         94 : query_yesno(bool deft, const char *msg, ...)
     202                 :            : {
     203                 :            :         va_list  ap;
     204                 :            :         bool r;
     205                 :            : 
     206                 :         94 :         va_start(ap, msg);
     207                 :         94 :         r = vquery_yesno(deft, msg, ap);
     208                 :         94 :         va_end(ap);
     209                 :            : 
     210                 :         94 :         return (r);
     211                 :            : }
     212                 :            : 
     213                 :            : int
     214                 :          0 : query_select(const char *msg, const char **opts, int ncnt, int deft)
     215                 :            : {
     216                 :            :         int i;
     217                 :          0 :         char *str = NULL;
     218                 :          0 :         char *endpntr = NULL;
     219                 :          0 :         size_t n = 0;
     220                 :            : 
     221                 :          0 :         printf("%s\n", msg);
     222         [ #  # ]:          0 :         for (i = 0; i < ncnt; i++) {
     223         [ #  # ]:          0 :                 if (i + 1 == deft)
     224                 :            :                 {
     225                 :          0 :                         printf("*[%d] %s\n",
     226                 :          0 :                                 i + 1, opts[i]);
     227                 :          0 :                 } else {
     228                 :          0 :                         printf(" [%d] %s\n",
     229                 :          0 :                                 i + 1, opts[i]);
     230                 :            :                 }
     231                 :          0 :         }
     232                 :            : 
     233                 :          0 :         i = deft;
     234         [ #  # ]:          0 :         while (getline(&str, &n, stdin) == -1) {
     235         [ #  # ]:          0 :                 if (errno == EINTR)
     236                 :          0 :                         continue;
     237                 :            :                 else
     238                 :          0 :                         goto cleanup;
     239                 :            :         }
     240                 :          0 :         i = (int) strtoul(str, &endpntr, 10);
     241                 :            : 
     242   [ #  #  #  # ]:          0 :         if (endpntr == NULL || *endpntr == '\0') {
     243                 :          0 :                 i = deft;
     244   [ #  #  #  # ]:          0 :         } else if (*endpntr == '\n' || *endpntr == '\r') {
     245   [ #  #  #  # ]:          0 :                 if (i > ncnt || i < 1)
     246                 :          0 :                         i = deft;
     247                 :          0 :         } else
     248                 :          0 :                 i = -1;
     249                 :            : 
     250                 :            : cleanup:
     251                 :          0 :         free(str);
     252                 :          0 :         return (i);
     253                 :            : }
     254                 :            : 
     255                 :            : /* what the pkg needs to load in order to display the requested info */
     256                 :            : int
     257                 :         34 : info_flags(uint64_t opt, bool remote)
     258                 :            : {
     259                 :         34 :         int flags = PKG_LOAD_BASIC;
     260                 :            : 
     261         [ +  + ]:         34 :         if (opt & INFO_CATEGORIES)
     262                 :          6 :                 flags |= PKG_LOAD_CATEGORIES;
     263         [ +  + ]:         34 :         if (opt & INFO_LICENSES)
     264                 :          6 :                 flags |= PKG_LOAD_LICENSES;
     265         [ +  + ]:         34 :         if (opt & (INFO_OPTIONS|INFO_OPTION_DEFAULTS|INFO_OPTION_DESCRIPTIONS))
     266                 :          6 :                 flags |= PKG_LOAD_OPTIONS;
     267         [ +  + ]:         34 :         if (opt & INFO_SHLIBS_REQUIRED)
     268                 :          6 :                 flags |= PKG_LOAD_SHLIBS_REQUIRED;
     269         [ +  + ]:         34 :         if (opt & INFO_SHLIBS_PROVIDED)
     270                 :          6 :                 flags |= PKG_LOAD_SHLIBS_PROVIDED;
     271         [ +  + ]:         34 :         if (opt & INFO_PROVIDED)
     272                 :          6 :                 flags |= PKG_LOAD_PROVIDES;
     273         [ +  + ]:         34 :         if (opt & INFO_REQUIRED)
     274                 :          6 :                 flags |= PKG_LOAD_REQUIRES;
     275         [ +  + ]:         34 :         if (opt & INFO_ANNOTATIONS)
     276                 :         13 :                 flags |= PKG_LOAD_ANNOTATIONS;
     277         [ +  - ]:         34 :         if (opt & INFO_DEPS)
     278                 :          0 :                 flags |= PKG_LOAD_DEPS;
     279         [ +  - ]:         34 :         if (opt & INFO_RDEPS)
     280                 :          0 :                 flags |= PKG_LOAD_RDEPS;
     281         [ +  - ]:         34 :         if (opt & INFO_FILES)
     282                 :          0 :                 flags |= PKG_LOAD_FILES;
     283         [ +  - ]:         34 :         if (opt & INFO_DIRS)
     284                 :          0 :                 flags |= PKG_LOAD_DIRS;
     285         [ +  - ]:         34 :         if (opt & INFO_USERS)
     286                 :          0 :                 flags |= PKG_LOAD_USERS;
     287         [ +  - ]:         34 :         if (opt & INFO_GROUPS)
     288                 :          0 :                 flags |= PKG_LOAD_GROUPS;
     289         [ +  - ]:         34 :         if (opt & INFO_RAW) {
     290                 :          0 :                 flags |= PKG_LOAD_CATEGORIES      |
     291                 :            :                          PKG_LOAD_LICENSES        |
     292                 :            :                          PKG_LOAD_OPTIONS         |
     293                 :            :                          PKG_LOAD_SHLIBS_REQUIRED |
     294                 :            :                          PKG_LOAD_SHLIBS_PROVIDED |
     295                 :            :                          PKG_LOAD_PROVIDES        |
     296                 :            :                          PKG_LOAD_REQUIRES        |
     297                 :            :                          PKG_LOAD_ANNOTATIONS     |
     298                 :            :                          PKG_LOAD_DEPS;
     299         [ #  # ]:          0 :                 if (!remote) {
     300                 :          0 :                         flags |= PKG_LOAD_FILES  |
     301                 :            :                                 PKG_LOAD_DIRS    |
     302                 :            :                                 PKG_LOAD_USERS   |
     303                 :            :                                 PKG_LOAD_GROUPS  |
     304                 :            :                                 PKG_LOAD_SCRIPTS |
     305                 :            :                                 PKG_LOAD_LUA_SCRIPTS;
     306                 :          0 :                 }
     307                 :          0 :         }
     308                 :            : 
     309                 :         34 :         return flags;
     310                 :            : }
     311                 :            : 
     312                 :            : void
     313                 :         72 : print_info(struct pkg * const pkg, uint64_t options)
     314                 :            : {
     315                 :         72 :         bool print_tag = false;
     316                 :         72 :         bool show_locks = false;
     317                 :         72 :         bool is_group = false;
     318                 :         72 :         const char *repourl = NULL;
     319                 :            :         unsigned opt;
     320                 :         72 :         int cout = 0;           /* Number of characters output */
     321                 :            :         int info_num;           /* Number of different data items to print */
     322                 :         72 :         int outflags = PKG_MANIFEST_EMIT_LOCAL_METADATA;
     323                 :            : 
     324                 :         72 :         pkg_get(pkg, PKG_ATTR_REPOURL, &repourl);
     325                 :            : 
     326         [ +  + ]:         72 :         if (options & INFO_RAW) {
     327   [ -  +  +  -  :         29 :                 switch (options & (INFO_RAW_YAML|INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) {
                      - ]
     328                 :            :                 case INFO_RAW_YAML:
     329                 :          1 :                         outflags |= PKG_MANIFEST_EMIT_PRETTY;
     330                 :          1 :                         break;
     331                 :            :                 case INFO_RAW_UCL:
     332                 :         28 :                         outflags |= PKG_MANIFEST_EMIT_UCL;
     333                 :         28 :                         break;
     334                 :            :                 case INFO_RAW_JSON:
     335                 :          0 :                         outflags |= PKG_MANIFEST_EMIT_JSON;
     336                 :          0 :                         break;
     337                 :            :                 case INFO_RAW_JSON_COMPACT:
     338                 :          0 :                         break;
     339                 :            :                 default:
     340                 :          0 :                         outflags |= PKG_MANIFEST_EMIT_UCL;
     341                 :          0 :                 }
     342         [ +  - ]:         29 :                 if (pkg_type(pkg) == PKG_REMOTE)
     343                 :          0 :                         outflags |= PKG_MANIFEST_EMIT_COMPACT;
     344                 :            : 
     345                 :         29 :                 pkg_emit_manifest_file(pkg, stdout, outflags);
     346         [ +  - ]:         29 :                 if (outflags & PKG_MANIFEST_EMIT_COMPACT)
     347                 :          0 :                         printf("\n");
     348                 :         29 :                 return;
     349                 :            :         }
     350                 :            : 
     351                 :            :         /* Show locking status when requested to display it and the
     352                 :            :            package is locally installed */
     353   [ +  +  +  - ]:         43 :         if (pkg_type(pkg) == PKG_INSTALLED && (options & INFO_LOCKED) != 0)
     354                 :          0 :                 show_locks = true;
     355   [ +  -  -  + ]:         43 :         if (pkg_type(pkg) == PKG_GROUP_REMOTE || pkg_type(pkg) == PKG_GROUP_INSTALLED)
     356                 :          0 :                 is_group = true;
     357                 :            : 
     358         [ +  + ]:         43 :         if (!quiet) {
     359                 :            :                 /* Print a tag-line identifying the package -- either
     360                 :            :                    NAMEVER, ORIGIN or NAME (in that order of
     361                 :            :                    preference).  This may be the only output from this
     362                 :            :                    function */
     363                 :            : 
     364         [ +  + ]:         38 :                 if (options & INFO_TAG_NAMEVER) {
     365         [ -  + ]:         36 :                         if (is_group)
     366                 :          0 :                                 cout = pkg_printf("@%n", pkg);
     367                 :            :                         else
     368                 :         36 :                                 cout = pkg_printf("%n-%v", pkg, pkg);
     369                 :         36 :                 }
     370         [ +  - ]:          2 :                 else if (options & INFO_TAG_ORIGIN) {
     371         [ -  + ]:          2 :                         if (is_group)
     372                 :          0 :                                 return;
     373                 :          2 :                         cout = pkg_printf("%o", pkg);
     374                 :          2 :                 }
     375         [ #  # ]:          0 :                 else if (options & INFO_TAG_NAME) {
     376         [ #  # ]:          0 :                         if (is_group)
     377                 :          0 :                                 cout = pkg_printf("@%n", pkg);
     378                 :            :                         else
     379                 :          0 :                                 cout = pkg_printf("%n", pkg);
     380                 :          0 :                 }
     381                 :         38 :         }
     382                 :            : 
     383                 :            :         /* If we printed a tag, and there are no other items to print,
     384                 :            :            then just return now. If there's only one single-line item
     385                 :            :            to print, show it at column 32 on the same line. If there's
     386                 :            :            one multi-line item to print, start a new line. If there is
     387                 :            :            more than one item to print per pkg, use 'key : value'
     388                 :            :            style to show on a new line.  */
     389                 :            : 
     390                 :         43 :         info_num = 0;
     391         [ +  + ]:       1333 :         for (opt = 0x1U; opt <= INFO_LASTFIELD; opt <<= 1)
     392         [ +  + ]:       1389 :                 if ((opt & options) != 0)
     393                 :         99 :                         info_num++;
     394                 :            : 
     395   [ +  +  -  + ]:         43 :         if (info_num == 0 && cout > 0) {
     396         [ -  + ]:          4 :                 putchar('\n');
     397                 :          4 :                 return;
     398                 :            :         }
     399                 :            : 
     400         [ +  + ]:         39 :         if (info_num == 1) {
     401                 :            :                 /* Only one item to print */
     402                 :         36 :                 print_tag = false;
     403         [ +  + ]:         36 :                 if (!quiet) {
     404         [ +  + ]:         31 :                         if (options & INFO_MULTILINE)
     405                 :         13 :                                 printf(":\n");
     406                 :            :                         else {
     407         [ +  - ]:         18 :                                 if (cout < 31)
     408                 :         18 :                                         cout = 31 - cout;
     409                 :            :                                 else
     410                 :          0 :                                         cout = 1;
     411                 :         18 :                                 printf("%*s", cout, " ");
     412                 :            :                         }
     413                 :         31 :                 }
     414                 :         36 :         } else {
     415                 :            :                 /* Several items to print */
     416                 :          3 :                 print_tag = true;
     417         [ -  + ]:          3 :                 if (!quiet)
     418         [ -  + ]:          3 :                         putchar('\n');
     419                 :            :         }
     420                 :            : 
     421         [ +  + ]:       1209 :         for (opt = 0x1; opt <= INFO_LASTFIELD; opt <<= 1) {
     422         [ +  + ]:       1170 :                 if ((opt & options) == 0)
     423                 :       1071 :                         continue;
     424                 :            : 
     425   [ +  +  +  +  :         99 :                 switch (opt) {
          +  +  +  +  -  
          -  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  -  -  +  
                   -  - ]
     426                 :            :                 case INFO_NAME:
     427         [ -  + ]:          3 :                         if (print_tag)
     428                 :          3 :                                 printf("%-15s: ", "Name");
     429                 :          3 :                         pkg_printf("%n\n", pkg);
     430                 :          3 :                         break;
     431                 :            :                 case INFO_INSTALLED:
     432         [ +  - ]:          3 :                         if (pkg_type(pkg) == PKG_INSTALLED) {
     433         [ -  + ]:          3 :                                 if (print_tag) {
     434                 :          3 :                                         printf("%-15s: ", "Installed on");
     435                 :          3 :                                         pkg_printf("%t%{%c %Z%}\n", pkg);
     436                 :          3 :                                 }
     437         [ #  # ]:          3 :                         } else if (!print_tag)
     438         [ #  # ]:          0 :                                 putchar('\n');
     439                 :          3 :                         break;
     440                 :            :                 case INFO_VERSION:
     441         [ -  + ]:          3 :                         if (is_group)
     442                 :          0 :                                 break;
     443         [ -  + ]:          3 :                         if (print_tag)
     444                 :          3 :                                 printf("%-15s: ", "Version");
     445                 :          3 :                         pkg_printf("%v\n", pkg);
     446                 :          3 :                         break;
     447                 :            :                 case INFO_ORIGIN:
     448         [ -  + ]:          4 :                         if (is_group)
     449                 :          0 :                                 break;
     450         [ +  + ]:          4 :                         if (print_tag)
     451                 :          3 :                                 printf("%-15s: ", "Origin");
     452                 :          4 :                         pkg_printf("%o\n", pkg);
     453                 :          4 :                         break;
     454                 :            :                 case INFO_PREFIX:
     455         [ -  + ]:          3 :                         if (is_group)
     456                 :          0 :                                 break;
     457         [ -  + ]:          3 :                         if (print_tag)
     458                 :          3 :                                 printf("%-15s: ", "Prefix");
     459                 :          3 :                         pkg_printf("%p\n", pkg);
     460                 :          3 :                         break;
     461                 :            :                 case INFO_REPOSITORY:
     462         [ -  + ]:          3 :                         if (is_group)
     463                 :          0 :                                 break;
     464   [ -  +  #  # ]:          3 :                         if (pkg_type(pkg) == PKG_REMOTE &&
     465         [ #  # ]:          0 :                             repourl != NULL && repourl[0] != '\0') {
     466         [ #  # ]:          0 :                                 if (print_tag)
     467                 :          0 :                                         printf("%-15s: ", "Repository");
     468                 :          0 :                                 pkg_printf("%N [%S]\n", pkg, repourl);
     469         [ +  - ]:          3 :                         } else if (!print_tag)
     470         [ #  # ]:          0 :                                 putchar('\n');
     471                 :          3 :                         break;
     472                 :            :                 case INFO_CATEGORIES:
     473         [ -  + ]:          3 :                         if (is_group)
     474                 :          0 :                                 break;
     475         [ -  + ]:          3 :                         if (print_tag)
     476                 :          3 :                                 printf("%-15s: ", "Categories");
     477                 :          3 :                         pkg_printf("%C%{%Cn%| %}\n", pkg);
     478                 :          3 :                         break;
     479                 :            :                 case INFO_LICENSES:
     480         [ -  + ]:          3 :                         if (is_group)
     481                 :          0 :                                 break;
     482         [ -  + ]:          3 :                         if (print_tag)
     483                 :          3 :                                 printf("%-15s: ", "Licenses");
     484                 :          3 :                         pkg_printf("%L%{%Ln%| %l %}\n", pkg);
     485                 :          3 :                         break;
     486                 :            :                 case INFO_MAINTAINER:
     487         [ -  + ]:          3 :                         if (is_group)
     488                 :          0 :                                 break;
     489         [ -  + ]:          3 :                         if (print_tag)
     490                 :          3 :                                 printf("%-15s: ", "Maintainer");
     491                 :          3 :                         pkg_printf("%m\n", pkg);
     492                 :          3 :                         break;
     493                 :            :                 case INFO_WWW:
     494         [ -  + ]:          3 :                         if (is_group)
     495                 :          0 :                                 break;
     496         [ -  + ]:          3 :                         if (print_tag)
     497                 :          3 :                                 printf("%-15s: ", "WWW");
     498                 :          3 :                         pkg_printf("%w\n", pkg);
     499                 :          3 :                         break;
     500                 :            :                 case INFO_COMMENT:
     501         [ +  + ]:         21 :                         if (print_tag)
     502                 :          3 :                                 printf("%-15s: ", "Comment");
     503                 :         21 :                         pkg_printf("%c\n", pkg);
     504                 :         21 :                         break;
     505                 :            :                 case INFO_OPTIONS:
     506         [ +  - ]:          3 :                         if (pkg_list_count(pkg, PKG_OPTIONS) > 0) {
     507         [ #  # ]:          0 :                                 if (print_tag)
     508                 :          0 :                                         printf("%-15s:\n", "Options");
     509         [ #  # ]:          0 :                                 if (quiet)
     510                 :          0 :                                         pkg_printf("%O%{%-15On: %Ov\n%|%}", pkg);
     511                 :            :                                 else
     512                 :          0 :                                         pkg_printf("%O%{\t%-15On: %Ov\n%|%}", pkg);
     513                 :          0 :                         }
     514                 :          3 :                         break;
     515                 :            :                 case INFO_SHLIBS_REQUIRED:
     516         [ +  - ]:          3 :                         if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) {
     517         [ #  # ]:          0 :                                 if (print_tag)
     518                 :          0 :                                         printf("%-15s:\n", "Shared Libs required");
     519         [ #  # ]:          0 :                                 if (quiet)
     520                 :          0 :                                         pkg_printf("%B%{%Bn\n%|%}", pkg);
     521                 :            :                                 else
     522                 :          0 :                                         pkg_printf("%B%{\t%Bn\n%|%}", pkg);
     523                 :          0 :                         }
     524                 :          3 :                         break;
     525                 :            :                 case INFO_SHLIBS_PROVIDED:
     526         [ +  - ]:          3 :                         if (pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0) {
     527         [ #  # ]:          0 :                                 if (print_tag)
     528                 :          0 :                                         printf("%-15s:\n", "Shared Libs provided");
     529         [ #  # ]:          0 :                                 if (quiet)
     530                 :          0 :                                         pkg_printf("%b%{%bn\n%|%}", pkg);
     531                 :            :                                 else
     532                 :          0 :                                         pkg_printf("%b%{\t%bn\n%|%}", pkg);
     533                 :          0 :                         }
     534                 :          3 :                         break;
     535                 :            :                 case INFO_REQUIRED:
     536         [ +  - ]:          3 :                         if (pkg_list_count(pkg, PKG_REQUIRES) > 0) {
     537         [ #  # ]:          0 :                                 if (print_tag)
     538                 :          0 :                                         printf("%-15s:\n", "Requires");
     539         [ #  # ]:          0 :                                 if (quiet)
     540                 :          0 :                                         pkg_printf("%Y%{%Yn\n%|%}", pkg);
     541                 :            :                                 else
     542                 :          0 :                                         pkg_printf("%Y%{\t%Yn\n%|%}", pkg);
     543                 :          0 :                         }
     544                 :          3 :                         break;
     545                 :            :                 case INFO_PROVIDED:
     546         [ +  - ]:          3 :                         if (pkg_list_count(pkg, PKG_PROVIDES) > 0) {
     547         [ #  # ]:          0 :                                 if (print_tag)
     548                 :          0 :                                         printf("%-15s:\n", "Provides");
     549         [ #  # ]:          0 :                                 if (quiet)
     550                 :          0 :                                         pkg_printf("%y%{%yn\n%|%}", pkg);
     551                 :            :                                 else
     552                 :          0 :                                         pkg_printf("%y%{\t%yn\n%|%}", pkg);
     553                 :          0 :                         }
     554                 :          3 :                         break;
     555                 :            :                 case INFO_ANNOTATIONS:
     556         [ -  + ]:         10 :                         if (is_group)
     557                 :          0 :                                 break;
     558         [ +  + ]:         10 :                         if (print_tag)
     559                 :          3 :                                 printf("%-15s:\n", "Annotations");
     560         [ -  + ]:         10 :                         if (quiet)
     561                 :          0 :                                 pkg_printf("%A%{%-15An: %Av\n%|%}", pkg);
     562                 :            :                         else
     563                 :         10 :                                 pkg_printf("%A%{\t%-15An: %Av\n%|%}", pkg);
     564                 :         10 :                         break;
     565                 :            :                 case INFO_FLATSIZE:
     566         [ -  + ]:          3 :                         if (is_group)
     567                 :          0 :                                 break;
     568         [ -  + ]:          3 :                         if (print_tag)
     569                 :          3 :                                 printf("%-15s: ", "Flat size");
     570                 :          3 :                         pkg_printf("%#sB\n", pkg);
     571                 :          3 :                         break;
     572                 :            :                 case INFO_PKGSIZE: /* Remote pkgs only */
     573         [ -  + ]:          3 :                         if (pkg_type(pkg) == PKG_REMOTE) {
     574         [ #  # ]:          0 :                                 if (print_tag)
     575                 :          0 :                                         printf("%-15s: ", "Pkg size");
     576                 :          0 :                                 pkg_printf("%#xB\n", pkg);
     577         [ +  - ]:          3 :                         } else if (!print_tag)
     578         [ #  # ]:          0 :                                 putchar('\n');
     579                 :          3 :                         break;
     580                 :            :                 case INFO_DESCR:
     581         [ -  + ]:          3 :                         if (is_group)
     582                 :          0 :                                 break;
     583         [ -  + ]:          3 :                         if (print_tag)
     584                 :          3 :                                 printf("%-15s:\n", "Description");
     585                 :          3 :                         pkg_printf("%e\n", pkg);
     586                 :          3 :                         break;
     587                 :            :                 case INFO_MESSAGE:
     588         [ -  + ]:          6 :                         if (is_group)
     589                 :          0 :                                 break;
     590         [ +  - ]:          6 :                         if (print_tag)
     591                 :          0 :                                 printf("%-15s:\n", "Message");
     592         [ -  + ]:          6 :                         if (pkg_has_message(pkg))
     593                 :          6 :                                 pkg_printf("%M\n", pkg);
     594                 :          6 :                         break;
     595                 :            :                 case INFO_DEPS:
     596         [ #  # ]:          0 :                         if (pkg_list_count(pkg, PKG_DEPS) > 0) {
     597         [ #  # ]:          0 :                                 if (print_tag)
     598                 :          0 :                                         printf("%-15s:\n", "Depends on");
     599         [ #  # ]:          0 :                                 if (quiet) {
     600         [ #  # ]:          0 :                                         if (show_locks)
     601                 :          0 :                                                 pkg_printf("%d%{%dn-%dv%#dk\n%|%}", pkg);
     602                 :            :                                         else
     603                 :          0 :                                                 pkg_printf("%d%{%dn-%dv\n%|%}", pkg);
     604                 :          0 :                                 } else {
     605         [ #  # ]:          0 :                                         if (show_locks)
     606                 :          0 :                                                 pkg_printf("%d%{\t%dn-%dv%#dk\n%|%}", pkg);
     607                 :            :                                         else
     608                 :          0 :                                                 pkg_printf("%d%{\t%dn-%dv\n%|%}", pkg);
     609                 :            :                                 }
     610                 :          0 :                         }
     611                 :          0 :                         break;
     612                 :            :                 case INFO_RDEPS:
     613         [ #  # ]:          0 :                         if (pkg_list_count(pkg, PKG_RDEPS) > 0) {
     614         [ #  # ]:          0 :                                 if (print_tag)
     615                 :          0 :                                         printf("%-15s:\n", "Required by");
     616         [ #  # ]:          0 :                                 if (quiet) {
     617         [ #  # ]:          0 :                                         if (show_locks)
     618                 :          0 :                                                 pkg_printf("%r%{%rn-%rv%#rk\n%|%}", pkg);
     619                 :            :                                         else
     620                 :          0 :                                                 pkg_printf("%r%{%rn-%rv\n%|%}", pkg);
     621                 :          0 :                                 } else {
     622         [ #  # ]:          0 :                                         if (show_locks)
     623                 :          0 :                                                 pkg_printf("%r%{\t%rn-%rv%#rk\n%|%}", pkg);
     624                 :            :                                         else
     625                 :          0 :                                                 pkg_printf("%r%{\t%rn-%rv\n%|%}", pkg);
     626                 :            :                                 }
     627                 :          0 :                         }
     628                 :          0 :                         break;
     629                 :            :                 case INFO_FILES: /* Installed pkgs only */
     630   [ +  -  -  + ]:          4 :                         if (pkg_type(pkg) != PKG_REMOTE &&
     631                 :          4 :                             pkg_list_count(pkg, PKG_FILES) > 0) {
     632         [ +  - ]:          4 :                                 if (print_tag)
     633                 :          0 :                                         printf("%-15s:\n", "Files");
     634         [ +  - ]:          4 :                                 if (quiet)
     635                 :          4 :                                         pkg_printf("%F%{%Fn\n%|%}", pkg);
     636                 :            :                                 else
     637                 :          0 :                                         pkg_printf("%F%{\t%Fn\n%|%}", pkg);
     638                 :          4 :                         }
     639                 :          4 :                         break;
     640                 :            :                 case INFO_DIRS: /* Installed pkgs only */
     641   [ #  #  #  # ]:          0 :                         if (pkg_type(pkg) != PKG_REMOTE &&
     642                 :          0 :                             pkg_list_count(pkg, PKG_DIRS) > 0) {
     643         [ #  # ]:          0 :                                 if (print_tag)
     644                 :          0 :                                         printf("%-15s:\n", "Directories");
     645         [ #  # ]:          0 :                                 if (quiet)
     646                 :          0 :                                         pkg_printf("%D%{%Dn\n%|%}", pkg);
     647                 :            :                                 else
     648                 :          0 :                                         pkg_printf("%D%{\t%Dn\n%|%}", pkg);
     649                 :          0 :                         }
     650                 :          0 :                         break;
     651                 :            :                 case INFO_USERS: /* Installed pkgs only */
     652   [ #  #  #  # ]:          0 :                         if (pkg_type(pkg) != PKG_REMOTE &&
     653                 :          0 :                             pkg_list_count(pkg, PKG_USERS) > 0) {
     654         [ #  # ]:          0 :                                 if (print_tag)
     655                 :          0 :                                         printf("%-15s: ", "Users");
     656                 :          0 :                                 pkg_printf("%U%{%Un%| %}\n", pkg);
     657                 :          0 :                         }
     658                 :          0 :                         break;
     659                 :            :                 case INFO_GROUPS: /* Installed pkgs only */
     660   [ #  #  #  # ]:          0 :                         if (pkg_type(pkg) != PKG_REMOTE &&
     661                 :          0 :                             pkg_list_count(pkg, PKG_GROUPS) > 0) {
     662         [ #  # ]:          0 :                                 if (print_tag)
     663                 :          0 :                                         printf("%-15s: ", "Groups");
     664                 :          0 :                                 pkg_printf("%G%{%Gn%| %}\n", pkg);
     665                 :          0 :                         }
     666                 :          0 :                         break;
     667                 :            :                 case INFO_ARCH:
     668         [ -  + ]:          3 :                         if (is_group)
     669                 :          0 :                                 break;
     670         [ -  + ]:          3 :                         if (print_tag)
     671                 :          3 :                                 printf("%-15s: ", "Architecture");
     672                 :          3 :                         pkg_printf("%q\n", pkg);
     673                 :          3 :                         break;
     674                 :            :                 case INFO_REPOURL:
     675   [ #  #  #  # ]:          0 :                         if (pkg_type(pkg) == PKG_REMOTE &&
     676         [ #  # ]:          0 :                             repourl != NULL && repourl[0] != '\0') {
     677         [ #  # ]:          0 :                                 if (print_tag)
     678                 :          0 :                                         printf("%-15s: ", "Pkg URL");
     679         [ #  # ]:          0 :                                 if (repourl[strlen(repourl) -1] == '/')
     680                 :          0 :                                         pkg_printf("%S%R\n", repourl, pkg);
     681                 :            :                                 else
     682                 :          0 :                                         pkg_printf("%S/%R\n", repourl, pkg);
     683         [ #  # ]:          0 :                         } else if (!print_tag)
     684         [ #  # ]:          0 :                                 putchar('\n');
     685                 :          0 :                         break;
     686                 :            :                 case INFO_LOCKED:
     687         [ #  # ]:          0 :                         if (print_tag)
     688                 :          0 :                                 printf("%-15s: ", "Locked");
     689                 :          0 :                         pkg_printf("%?k\n", pkg);
     690                 :          0 :                         break;
     691                 :            :                 }
     692                 :         99 :         }
     693                 :         72 : }
     694                 :            : 
     695                 :            : enum pkg_display_type {
     696                 :            :         PKG_DISPLAY_LOCKED = 0,
     697                 :            :         PKG_DISPLAY_INSTALL,
     698                 :            :         PKG_DISPLAY_UPGRADE,
     699                 :            :         PKG_DISPLAY_DOWNGRADE,
     700                 :            :         PKG_DISPLAY_REINSTALL,
     701                 :            :         PKG_DISPLAY_DELETE,
     702                 :            :         PKG_DISPLAY_FETCH,
     703                 :            :         PKG_DISPLAY_GROUP_INSTALL,
     704                 :            :         PKG_DISPLAY_GROUP_UPGRADE,
     705                 :            :         PKG_DISPLAY_MAX
     706                 :            : };
     707                 :            : struct pkg_solved_display {
     708                 :            :         struct pkg *new, *old;
     709                 :            :         enum pkg_display_type display_type;
     710                 :            :         pkg_solved_t solved_type;
     711                 :            : };
     712                 :            : 
     713                 :            : typedef tll(struct pkg_solved_display *) pkg_solved_display_t;
     714                 :            : 
     715                 :            : static void
     716                 :        150 : set_jobs_summary_pkg(struct pkg_jobs *jobs, struct pkg *new_pkg,
     717                 :            :     struct pkg *old_pkg, pkg_solved_t type, int64_t *oldsize,
     718                 :            :     int64_t *newsize, int64_t *dlsize, pkg_solved_display_t *disp,
     719                 :            :     struct jobs_sum_number *sum)
     720                 :            : {
     721                 :        150 :         const char *repopath = NULL, *destdir;
     722                 :            :         char path[MAXPATHLEN];
     723                 :            :         int ret;
     724                 :            :         struct stat st;
     725                 :            :         int64_t flatsize, oldflatsize, pkgsize;
     726                 :            :         struct pkg_solved_display *it;
     727                 :            : 
     728                 :        150 :         flatsize = oldflatsize = pkgsize = 0;
     729                 :            : 
     730                 :        150 :         pkg_get(new_pkg, PKG_ATTR_FLATSIZE, &flatsize);
     731                 :        150 :         pkg_get(new_pkg, PKG_ATTR_PKGSIZE, &pkgsize);
     732                 :        150 :         pkg_get(new_pkg, PKG_ATTR_REPOPATH, &repopath);
     733         [ +  + ]:        150 :         if (old_pkg != NULL)
     734                 :         44 :                 pkg_get(old_pkg, PKG_ATTR_FLATSIZE, &oldflatsize);
     735                 :            : 
     736                 :        150 :         it = malloc(sizeof (*it));
     737         [ +  - ]:        150 :         if (it == NULL) {
     738                 :          0 :                 fprintf(stderr, "malloc failed for "
     739                 :          0 :                                 "pkg_solved_display: %s", strerror (errno));
     740                 :          0 :                 return;
     741                 :            :         }
     742                 :        150 :         it->new = new_pkg;
     743                 :        150 :         it->old = old_pkg;
     744                 :        150 :         it->solved_type = type;
     745                 :        150 :         it->display_type = PKG_DISPLAY_MAX;
     746                 :            : 
     747   [ +  +  +  - ]:        150 :         if (old_pkg != NULL && pkg_is_locked(old_pkg)) {
     748                 :          0 :                 it->display_type = PKG_DISPLAY_LOCKED;
     749   [ #  #  #  #  :          0 :                 tll_push_back(disp[it->display_type], it);
          #  #  #  #  #  
                      # ]
     750                 :          0 :                 return;
     751                 :            :         }
     752                 :            : 
     753                 :        150 :         destdir = pkg_jobs_destdir(jobs);
     754                 :            : 
     755   [ +  +  -  -  :        150 :         switch (type) {
                -  +  + ]
     756                 :            :         case PKG_SOLVED_INSTALL:
     757                 :            :         case PKG_SOLVED_UPGRADE:
     758         [ -  + ]:        107 :                 if (destdir == NULL)
     759                 :        107 :                         ret = pkg_repo_cached_name(new_pkg, path, sizeof(path));
     760         [ #  # ]:          0 :                 else if (repopath != NULL) {
     761                 :          0 :                         snprintf(path, sizeof(path), "%s/%s", destdir, repopath);
     762                 :          0 :                         ret = EPKG_OK;
     763                 :          0 :                 } else
     764                 :          0 :                         break;
     765                 :            : 
     766   [ +  +  +  -  :        107 :                 if ((ret == EPKG_OK || ret == EPKG_FATAL) && (stat(path, &st) == -1 || pkgsize != st.st_size)) {
             +  +  -  + ]
     767                 :            :                         /* file looks corrupted (wrong size),
     768                 :            :                                            assume a checksum mismatch will
     769                 :            :                                            occur later and the file will be
     770                 :            :                                            fetched from remote again */
     771                 :         13 :                         *dlsize += pkgsize;
     772                 :         13 :                         nbtodl += 1;
     773                 :         13 :                 }
     774                 :            : 
     775         [ -  + ]:        107 :                 if (pkg_type(new_pkg) == PKG_GROUP_REMOTE) {
     776         [ #  # ]:          0 :                         if (old_pkg == NULL) {
     777                 :          0 :                                 it->display_type = PKG_DISPLAY_GROUP_INSTALL;
     778                 :          0 :                                 sum->group_install++;
     779                 :          0 :                         } else {
     780                 :          0 :                                 it->display_type = PKG_DISPLAY_GROUP_UPGRADE;
     781                 :          0 :                                 sum->group_upgrade++;
     782                 :            :                         }
     783                 :          0 :                 } else {
     784         [ +  + ]:        107 :                         if (old_pkg != NULL) {
     785   [ +  -  -  + ]:         44 :                                 switch (pkg_version_change_between(new_pkg, old_pkg)) {
     786                 :            :                                 case PKG_DOWNGRADE:
     787                 :          0 :                                         it->display_type = PKG_DISPLAY_DOWNGRADE;
     788                 :          0 :                                         sum->downgrade++;
     789                 :          0 :                                         break;
     790                 :            :                                 case PKG_REINSTALL:
     791                 :         12 :                                         it->display_type = PKG_DISPLAY_REINSTALL;
     792                 :         12 :                                         sum->reinstall++;
     793                 :         12 :                                         break;
     794                 :            :                                 case PKG_UPGRADE:
     795                 :         32 :                                         it->display_type = PKG_DISPLAY_UPGRADE;
     796                 :         32 :                                         sum->upgrade++;
     797                 :         32 :                                         break;
     798                 :            :                                 }
     799                 :         44 :                                 *oldsize += oldflatsize;
     800                 :         44 :                                 *newsize += flatsize;
     801                 :         44 :                         } else {
     802                 :         63 :                                 it->display_type = PKG_DISPLAY_INSTALL;
     803                 :         63 :                                 sum->install++;
     804                 :         63 :                                 *newsize += flatsize;
     805                 :            :                         }
     806                 :            :                 }
     807                 :        107 :                 break;
     808                 :            :         case PKG_SOLVED_DELETE:
     809                 :         36 :                 *oldsize += flatsize;
     810                 :         36 :                 it->display_type = PKG_DISPLAY_DELETE;
     811                 :         36 :                 sum->delete++;
     812                 :         36 :                 break;
     813                 :            :         case PKG_SOLVED_UPGRADE_INSTALL:
     814                 :            :         case PKG_SOLVED_UPGRADE_REMOVE:
     815                 :            :                 /* Ignore split-upgrade packages for display */
     816                 :          0 :                 free(it);
     817                 :          0 :                 return;
     818                 :            :                 break;
     819                 :            : 
     820                 :            :         case PKG_SOLVED_FETCH:
     821                 :          7 :                 *newsize += pkgsize;
     822                 :          7 :                 it->display_type = PKG_DISPLAY_FETCH;
     823         [ -  + ]:          7 :                 if (destdir == NULL)
     824                 :          7 :                         pkg_repo_cached_name(new_pkg, path, sizeof(path));
     825                 :            :                 else
     826                 :          0 :                         snprintf(path, sizeof(path), "%s/%s", destdir, repopath);
     827                 :            : 
     828         [ +  + ]:          7 :                 if (stat(path, &st) != -1) {
     829                 :          4 :                         *oldsize += st.st_size;
     830                 :            : 
     831         [ -  + ]:          4 :                         if (pkgsize != st.st_size)
     832                 :          0 :                                 *dlsize += pkgsize;
     833                 :            :                         else {
     834                 :          4 :                                 free(it);
     835                 :          4 :                                 return;
     836                 :            :                         }
     837                 :          0 :                 }
     838                 :            :                 else
     839                 :          3 :                         *dlsize += pkgsize;
     840                 :          3 :                 sum->fetch++;
     841                 :            : 
     842                 :          3 :                 break;
     843                 :            :         }
     844   [ +  +  +  +  :        146 :         tll_push_back(disp[it->display_type], it);
          -  +  -  +  +  
                      + ]
     845                 :        150 : }
     846                 :            : 
     847                 :            : static void
     848                 :        146 : display_summary_item(struct pkg_solved_display *it, int64_t dlsize)
     849                 :            : {
     850                 :        146 :         const char *why = NULL;
     851                 :        146 :         int64_t pkgsize = 0;
     852                 :            :         char size[8], tlsize[8];
     853                 :            :         const char *type;
     854                 :            : 
     855                 :        146 :         pkg_get(it->new, PKG_ATTR_PKGSIZE, &pkgsize);
     856                 :            : 
     857   [ -  -  +  +  :        146 :         switch (it->display_type) {
          +  -  +  +  -  
                      - ]
     858                 :            :         case PKG_DISPLAY_LOCKED:
     859                 :          0 :                 pkg_printf("\tPackage %n-%v is locked ", it->old, it->old);
     860   [ #  #  #  #  :          0 :                 switch (it->solved_type) {
                #  #  # ]
     861                 :            :                 case PKG_SOLVED_INSTALL:
     862                 :            :                 case PKG_SOLVED_UPGRADE:
     863                 :            :                 case PKG_SOLVED_UPGRADE_INSTALL:
     864                 :            :                         /* If it's a new install, then it
     865                 :            :                          * cannot have been locked yet. */
     866   [ #  #  #  # ]:          0 :                         switch (pkg_version_change_between(it->old, it->new)) {
     867                 :            :                         case PKG_DOWNGRADE:
     868                 :          0 :                                 type = "downgraded";
     869                 :          0 :                                 break;
     870                 :            :                         case PKG_REINSTALL:
     871                 :          0 :                                 type = "reinstalled";
     872                 :          0 :                                 break;
     873                 :            :                         case PKG_UPGRADE:
     874                 :          0 :                                 type = "upgraded";
     875                 :          0 :                                 break;
     876                 :            :                         default: /* appease compiler warnings */
     877                 :          0 :                                 type = "upgraded";
     878                 :          0 :                                 break;
     879                 :            :                         }
     880                 :          0 :                         pkg_printf("and may not be %S to version %v\n", type,
     881                 :          0 :                             it->new);
     882                 :          0 :                         break;
     883                 :            :                 case PKG_SOLVED_DELETE:
     884                 :            :                 case PKG_SOLVED_UPGRADE_REMOVE:
     885                 :          0 :                         printf("and may not be deinstalled\n");
     886                 :          0 :                         return;
     887                 :            :                         break;
     888                 :            :                 case PKG_SOLVED_FETCH:
     889                 :          0 :                         printf("but a new package can still be fetched\n");
     890                 :          0 :                         break;
     891                 :            :                 }
     892                 :          0 :                 break;
     893                 :            :         case PKG_DISPLAY_DELETE:
     894                 :         36 :                 pkg_get(it->new, PKG_ATTR_REASON, &why);
     895                 :         36 :                 pkg_printf("\t%n: %v", it->new, it->new);
     896         [ +  - ]:         36 :                 if (why != NULL)
     897                 :          0 :                         printf(" (%s)", why);
     898         [ -  + ]:         36 :                 putchar('\n');
     899                 :         36 :                 break;
     900                 :            :         case PKG_DISPLAY_INSTALL:
     901                 :         63 :                 pkg_printf("\t%n: %v", it->new, it->new);
     902         [ +  + ]:         63 :                 if (pkg_repos_total_count() > 1)
     903                 :         15 :                         pkg_printf(" [%N]", it->new);
     904         [ -  + ]:         63 :                 putchar('\n');
     905                 :         63 :                 break;
     906                 :            :         case PKG_DISPLAY_UPGRADE:
     907                 :         32 :                 pkg_printf("\t%n: %v -> %v", it->new, it->old, it->new);
     908         [ +  + ]:         32 :                 if (pkg_repos_total_count() > 1)
     909                 :          5 :                         pkg_printf(" [%N]", it->new);
     910         [ -  + ]:         32 :                 putchar('\n');
     911                 :         32 :                 break;
     912                 :            :         case PKG_DISPLAY_DOWNGRADE:
     913                 :          0 :                 pkg_printf("\t%n: %v -> %v", it->new, it->old, it->new);
     914         [ #  # ]:          0 :                 if (pkg_repos_total_count() > 1)
     915                 :          0 :                         pkg_printf(" [%N]", it->new);
     916         [ #  # ]:          0 :                 putchar('\n');
     917                 :          0 :                 break;
     918                 :            :         case PKG_DISPLAY_REINSTALL:
     919                 :         12 :                 pkg_get(it->new, PKG_ATTR_REASON, &why);
     920                 :         12 :                 pkg_printf("\t%n-%v", it->new, it->new);
     921         [ +  + ]:         12 :                 if (pkg_repos_total_count() > 1)
     922                 :          3 :                         pkg_printf(" [%N]", it->new);
     923         [ +  + ]:         12 :                 if (why != NULL)
     924                 :          9 :                         printf(" (%s)", why);
     925         [ -  + ]:         12 :                 putchar('\n');
     926                 :         12 :                 break;
     927                 :            :         case PKG_DISPLAY_FETCH:
     928                 :          3 :                 humanize_number(size, sizeof(size), pkgsize, "B",
     929                 :            :                     HN_AUTOSCALE, HN_IEC_PREFIXES);
     930                 :          3 :                 humanize_number(tlsize, sizeof(size), dlsize, "B",
     931                 :            :                     HN_AUTOSCALE, HN_IEC_PREFIXES);
     932                 :            : 
     933                 :          3 :                 pkg_printf("\t%n: %v ", it->new, it->new);
     934                 :          6 :                 printf("(%s: %.2f%% of the %s to download)\n", size,
     935                 :          3 :                     ((double)100 * pkgsize) / (double)dlsize, tlsize);
     936                 :          3 :                 break;
     937                 :            :         case PKG_DISPLAY_GROUP_UPGRADE:
     938                 :          0 :                 pkg_printf("\t%n", it->new, it->new);
     939         [ #  # ]:          0 :                 if (pkg_repos_total_count() > 1)
     940                 :          0 :                         pkg_printf(" [%N]", it->new);
     941         [ #  # ]:          0 :                 putchar('\n');
     942                 :          0 :                 break;
     943                 :            :         case PKG_DISPLAY_GROUP_INSTALL:
     944                 :          0 :                 pkg_printf("\t@%n", it->new, it->new);
     945         [ #  # ]:          0 :                 if (pkg_repos_total_count() > 1)
     946                 :          0 :                         pkg_printf(" [%N]", it->new);
     947         [ #  # ]:          0 :                 putchar('\n');
     948                 :          0 :                 break;
     949                 :            :         default:
     950                 :          0 :                 break;
     951                 :            :         }
     952                 :        146 : }
     953                 :            : 
     954                 :            : 
     955                 :            : static const char* pkg_display_messages[PKG_DISPLAY_MAX + 1] = {
     956                 :            :         [PKG_DISPLAY_LOCKED] = "Installed packages LOCKED",
     957                 :            :         [PKG_DISPLAY_DELETE] = "Installed packages to be REMOVED",
     958                 :            :         [PKG_DISPLAY_INSTALL] = "New packages to be INSTALLED",
     959                 :            :         [PKG_DISPLAY_GROUP_UPGRADE] = "New groups to be UPGRADED",
     960                 :            :         [PKG_DISPLAY_DOWNGRADE] = "Installed packages to be DOWNGRADED",
     961                 :            :         [PKG_DISPLAY_REINSTALL] = "Installed packages to be REINSTALLED",
     962                 :            :         [PKG_DISPLAY_FETCH] = "New packages to be FETCHED",
     963                 :            :         [PKG_DISPLAY_GROUP_INSTALL] = "New groups to be INSTALLED",
     964                 :            :         [PKG_DISPLAY_UPGRADE] = "Installed packages to be UPGRADED",
     965                 :            :         [PKG_DISPLAY_MAX] = NULL
     966                 :            : };
     967                 :            : 
     968                 :            : static int
     969                 :         58 : namecmp(const void *a, const void *b)
     970                 :            : {
     971                 :         58 :         const struct pkg_solved_display *sda = *(const struct pkg_solved_display **) a;
     972                 :         58 :         const struct pkg_solved_display *sdb = *(const struct pkg_solved_display **) b;
     973                 :            : 
     974                 :         58 :         return (pkg_namecmp(sda->new, sdb->new));
     975                 :            : }
     976                 :            : 
     977                 :            : int
     978                 :         86 : print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
     979                 :            : {
     980                 :            :         struct pkg *new_pkg, *old_pkg;
     981                 :         86 :         void *iter = NULL;
     982                 :            :         char size[8];
     983                 :            :         va_list ap;
     984                 :         86 :         int type, displayed = 0;
     985                 :            :         int64_t dlsize, oldsize, newsize;
     986                 :            :         pkg_solved_display_t disp[PKG_DISPLAY_MAX];
     987                 :            :         struct pkg_solved_display **displays;
     988                 :         86 :         bool first = true;
     989                 :            :         size_t bytes_change, limbytes;
     990                 :            :         struct jobs_sum_number sum;
     991                 :            : 
     992                 :         86 :         dlsize = oldsize = newsize = 0;
     993                 :         86 :         type = pkg_jobs_type(jobs);
     994                 :         86 :         memset(disp, 0, sizeof(*disp) * PKG_DISPLAY_MAX);
     995                 :         86 :         memset(&sum, 0, sizeof(sum));
     996                 :            : 
     997                 :         86 :         nbtodl = 0;
     998         [ +  + ]:        236 :         while (pkg_jobs_iter(jobs, &iter, &new_pkg, &old_pkg, &type)) {
     999                 :        300 :                 set_jobs_summary_pkg(jobs, new_pkg, old_pkg, type, &oldsize,
    1000                 :        150 :                 &newsize, &dlsize, disp, &sum);
    1001                 :            :         }
    1002                 :            : 
    1003         [ +  + ]:        860 :         for (type = 0; type < PKG_DISPLAY_MAX; type ++) {
    1004         [ +  + ]:        774 :                 if (tll_length(disp[type]) != 0) {
    1005                 :            :                         /* Space between each section. */
    1006         [ +  + ]:        105 :                         if (!first)
    1007         [ -  + ]:         20 :                                 putchar('\n');
    1008                 :            :                         else
    1009                 :         85 :                                 first = false;
    1010         [ +  + ]:        105 :                         if (msg != NULL) {
    1011                 :         85 :                                 va_start(ap, msg);
    1012                 :         85 :                                 vprintf(msg, ap);
    1013                 :         85 :                                 va_end(ap);
    1014                 :         85 :                                 fflush(stdout);
    1015                 :         85 :                                 msg = NULL;
    1016                 :         85 :                         }
    1017                 :        105 :                         printf("%s:\n", pkg_display_messages[type]);
    1018                 :        105 :                         displays = xcalloc(tll_length(disp[type]), sizeof(*displays));
    1019                 :        105 :                         size_t i = 0;
    1020   [ +  -  +  +  :        251 :                         tll_foreach(disp[type], d) {
                   +  + ]
    1021                 :        146 :                                 displays[i++] = d->item;
    1022                 :        146 :                         }
    1023                 :        105 :                         qsort(displays, i, sizeof(displays[0]), namecmp);
    1024         [ +  + ]:        251 :                         for (i = 0; i < tll_length(disp[type]); i++) {
    1025                 :        146 :                                 display_summary_item(displays[i], dlsize);
    1026                 :        146 :                                 displayed ++;
    1027                 :        146 :                         }
    1028   [ +  -  +  +  :        251 :                         tll_free_and_free(disp[type], free);
                   +  + ]
    1029                 :        105 :                         free(displays);
    1030                 :        105 :                 }
    1031                 :        774 :         }
    1032                 :            : 
    1033                 :         86 :         limbytes = pkg_object_int(pkg_config_get("WARN_SIZE_LIMIT"));
    1034                 :         86 :         bytes_change = (size_t)llabs(newsize - oldsize);
    1035                 :            : 
    1036         [ -  + ]:         86 :         putchar('\n');
    1037         [ +  + ]:         86 :         if (sum.delete > 0)
    1038                 :         29 :                 printf("Number of packages to be removed: %d\n", sum.delete);
    1039         [ +  + ]:         86 :         if (sum.install > 0)
    1040                 :         37 :                 printf("Number of packages to be installed: %d\n", sum.install);
    1041         [ +  + ]:         86 :         if (sum.upgrade > 0)
    1042                 :         28 :                 printf("Number of packages to be upgraded: %d\n", sum.upgrade);
    1043         [ +  + ]:         86 :         if (sum.reinstall > 0)
    1044                 :          8 :                 printf("Number of packages to be reinstalled: %d\n",
    1045                 :          8 :                     sum.reinstall);
    1046         [ +  - ]:         86 :         if (sum.downgrade > 0)
    1047                 :          0 :                 printf("Number of packages to be downgraded: %d\n",
    1048                 :          0 :                     sum.downgrade);
    1049         [ +  + ]:         86 :         if (sum.fetch > 0)
    1050                 :          3 :                 printf("Number of packages to be fetched: %d\n", sum.fetch);
    1051         [ +  - ]:         86 :         if (sum.group_install > 0)
    1052                 :          0 :                 printf("Number of groups to be installed: %d\n", sum.group_install);
    1053         [ +  - ]:         86 :         if (sum.group_upgrade > 0)
    1054                 :          0 :                 printf("Number of groups to be upgraded: %d\n", sum.group_upgrade);
    1055                 :            :         /* Add an extra line before the size output. */
    1056   [ +  -  +  + ]:         86 :         if (bytes_change > limbytes || dlsize)
    1057         [ +  - ]:          4 :                 putchar('\n');
    1058                 :            : 
    1059         [ +  - ]:         86 :         if (bytes_change > limbytes) {
    1060         [ #  # ]:          0 :                 if (oldsize > newsize) {
    1061                 :          0 :                         humanize_number(size, sizeof(size), oldsize - newsize, "B",
    1062                 :            :                             HN_AUTOSCALE, HN_IEC_PREFIXES);
    1063                 :          0 :                         printf("The operation will free %s.\n", size);
    1064         [ #  # ]:          0 :                 } else if (newsize > oldsize) {
    1065                 :          0 :                         humanize_number(size, sizeof(size), newsize - oldsize, "B",
    1066                 :            :                             HN_AUTOSCALE, HN_IEC_PREFIXES);
    1067                 :          0 :                         printf("The process will require %s more space.\n", size);
    1068                 :          0 :                 }
    1069                 :          0 :         }
    1070                 :            : 
    1071         [ +  + ]:         86 :         if (dlsize > 0) {
    1072                 :          4 :                 humanize_number(size, sizeof(size), dlsize, "B",
    1073                 :            :                     HN_AUTOSCALE, HN_IEC_PREFIXES);
    1074                 :          4 :                 printf("%s to be downloaded.\n", size);
    1075                 :          4 :         }
    1076                 :            : 
    1077                 :         86 :         return (displayed);
    1078                 :            : }
    1079                 :            : 
    1080                 :            : int
    1081                 :          2 : print_pkg(struct pkg *p, void *ctx)
    1082                 :            : {
    1083                 :          2 :         int *counter = ctx;
    1084                 :            : 
    1085                 :          2 :         pkg_printf("\t%n\n", p);
    1086                 :          2 :         (*counter)++;
    1087                 :            : 
    1088                 :          2 :         return 0;
    1089                 :            : }
    1090                 :            : 
    1091                 :            : void
    1092                 :          8 : print_repository(struct pkg_repo *repo, bool pad)
    1093                 :            : {
    1094                 :            :         const char      *mirror, *sig;
    1095                 :            : 
    1096   [ -  +  -  + ]:          8 :         switch (pkg_repo_mirror_type(repo)) {
    1097                 :            :                 case SRV:
    1098                 :          2 :                         mirror = "SRV";
    1099                 :          2 :                         break;
    1100                 :            :                 case HTTP:
    1101                 :          0 :                         mirror = "HTTP";
    1102                 :          0 :                         break;
    1103                 :            :                 case NOMIRROR:
    1104                 :          6 :                         mirror = "NONE";
    1105                 :          6 :                         break;
    1106                 :            :                 default:
    1107                 :          0 :                         mirror = "-unknown-";
    1108                 :          0 :                         break;
    1109                 :            :         }
    1110   [ +  -  -  + ]:          8 :         switch (pkg_repo_signature_type(repo)) {
    1111                 :            :                 case SIG_PUBKEY:
    1112                 :          0 :                         sig = "PUBKEY";
    1113                 :          0 :                         break;
    1114                 :            :                 case SIG_FINGERPRINT:
    1115                 :          2 :                         sig = "FINGERPRINTS";
    1116                 :          2 :                         break;
    1117                 :            :                 case SIG_NONE:
    1118                 :          6 :                         sig = "NONE";
    1119                 :          6 :                         break;
    1120                 :            :                 default:
    1121                 :          0 :                         sig = "-unknown-";
    1122                 :          0 :                         break;
    1123                 :            :         }
    1124                 :            : 
    1125                 :          8 :         printf("%s%s: { \n    %-16s: \"%s\",\n    %-16s: %s,\n"
    1126                 :            :                         "    %-16s: %u",
    1127                 :          8 :                         pad ? "  " : "",
    1128                 :          8 :                         pkg_repo_name(repo),
    1129                 :          8 :                         "url", pkg_repo_url(repo),
    1130                 :          8 :                         "enabled", pkg_repo_enabled(repo) ? "yes" : "no",
    1131                 :          8 :                         "priority", pkg_repo_priority(repo));
    1132                 :            : 
    1133         [ +  + ]:          8 :         if (pkg_repo_mirror_type(repo) != NOMIRROR)
    1134                 :          2 :                 printf(",\n    %-16s: \"%s\"",
    1135                 :          2 :                                 "mirror_type", mirror);
    1136         [ +  + ]:          8 :         if (pkg_repo_signature_type(repo) != SIG_NONE)
    1137                 :          2 :                 printf(",\n    %-16s: \"%s\"",
    1138                 :          2 :                                 "signature_type", sig);
    1139         [ +  + ]:          8 :         if (pkg_repo_fingerprints(repo) != NULL)
    1140                 :          2 :                 printf(",\n    %-16s: \"%s\"",
    1141                 :          2 :                                 "fingerprints", pkg_repo_fingerprints(repo));
    1142         [ +  - ]:          8 :         if (pkg_repo_key(repo) != NULL)
    1143                 :          0 :                 printf(",\n    %-16s: \"%s\"",
    1144                 :          0 :                                 "pubkey", pkg_repo_key(repo));
    1145         [ +  - ]:          8 :         if (pkg_repo_ip_version(repo) != 0)
    1146                 :          0 :                 printf(",\n    %-16s: %u",
    1147                 :          0 :                                 "ip_version", pkg_repo_ip_version(repo));
    1148                 :          8 :         printf("\n  }\n");
    1149                 :          8 : }

Generated by: LCOV version 1.15