LCOV - code coverage report
Current view: top level - src - utils.c (source / functions) Hit Total Coverage
Test: rapport Lines: 314 630 49.8 %
Date: 2021-12-10 16:22:55 Functions: 10 13 76.9 %
Branches: 209 489 42.7 %

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

Generated by: LCOV version 1.15