LCOV - code coverage report
Current view: top level - src - event.c (source / functions) Hit Total Coverage
Test: plop Lines: 245 458 53.5 %
Date: 2024-12-30 07:09:03 Functions: 5 9 55.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 144 305 47.2 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2014 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
       5                 :            :  * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
       6                 :            :  * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       7                 :            :  * Copyright (c) 2015 Matthew Seaman <matthew@FreeBSD.org>
       8                 :            :  * All rights reserved.
       9                 :            :  *
      10                 :            :  * Redistribution and use in source and binary forms, with or without
      11                 :            :  * modification, are permitted provided that the following conditions
      12                 :            :  * are met:
      13                 :            :  * 1. Redistributions of source code must retain the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer
      15                 :            :  *    in this position and unchanged.
      16                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      17                 :            :  *    notice, this list of conditions and the following disclaimer in the
      18                 :            :  *    documentation and/or other materials provided with the distribution.
      19                 :            :  *
      20                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      21                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      22                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      23                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      24                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      25                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      29                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30                 :            :  */
      31                 :            : 
      32                 :            : #ifdef HAVE_CONFIG_H
      33                 :            : #include "pkg_config.h"
      34                 :            : #endif
      35                 :            : 
      36                 :            : #include <sys/resource.h>
      37                 :            : #include <sys/types.h>
      38                 :            : #ifdef HAVE_LIBJAIL
      39                 :            : #include <sys/sysctl.h>
      40                 :            : #endif
      41                 :            : #include <sys/wait.h>
      42                 :            : #include <sys/socket.h>
      43                 :            : 
      44                 :            : #ifdef HAVE_CAPSICUM
      45                 :            : #include <sys/capsicum.h>
      46                 :            : #endif
      47                 :            : 
      48                 :            : #include <err.h>
      49                 :            : #include <string.h>
      50                 :            : #include <unistd.h>
      51                 :            : #include <errno.h>
      52                 :            : #include <time.h>
      53                 :            : #include <signal.h>
      54                 :            : #ifdef HAVE_LIBUTIL_H
      55                 :            : #include <libutil.h>
      56                 :            : #endif
      57                 :            : #include <tllist.h>
      58                 :            : 
      59                 :            : #include <bsd_compat.h>
      60                 :            : 
      61                 :            : #include "pkg.h"
      62                 :            : #include "pkgcli.h"
      63                 :            : #include "xmalloc.h"
      64                 :            : 
      65                 :            : #define STALL_TIME 5
      66                 :            : 
      67                 :            : xstring *messages = NULL;
      68                 :            : xstring *conflicts = NULL;
      69                 :            : 
      70                 :            : struct cleanup {
      71                 :            :         void *data;
      72                 :            :         void (*cb)(void *);
      73                 :            : };
      74                 :            : 
      75                 :            : static char *progress_message = NULL;
      76                 :            : static xstring *msg_buf = NULL;
      77                 :            : static int last_progress_percent = -1;
      78                 :            : static bool progress_started = false;
      79                 :            : static bool progress_interrupted = false;
      80                 :            : static bool progress_debit = false;
      81                 :            : static int64_t last_tick = 0;
      82                 :            : static int64_t stalled;
      83                 :            : static int64_t bytes_per_second;
      84                 :            : static time_t last_update;
      85                 :            : static time_t begin = 0;
      86                 :            : static int add_deps_depth;
      87                 :            : static tll(struct cleanup *) cleanup_list = tll_init();
      88                 :            : static bool signal_handler_installed = false;
      89                 :            : 
      90                 :            : /* units for format_size */
      91                 :            : static const char *unit_SI[] = { " ", "k", "M", "G", "T", };
      92                 :            : 
      93                 :            : static void draw_progressbar(int64_t current, int64_t total);
      94                 :            : 
      95                 :            : static void
      96                 :          0 : cleanup_handler(int dummy __unused)
      97                 :            : {
      98                 :            :         struct cleanup *ev;
      99                 :            : 
     100         [ #  # ]:          0 :         if (tll_length(cleanup_list) == 0)
     101                 :          0 :                 return;
     102                 :          0 :         warnx("\nsignal received, cleaning up");
     103   [ #  #  #  #  :          0 :         tll_foreach(cleanup_list, it) {
                   #  # ]
     104                 :          0 :                 ev = it->item;
     105                 :          0 :                 ev->cb(ev->data);
     106                 :          0 :         }
     107                 :          0 :         exit(1);
     108                 :            : }
     109                 :            : 
     110                 :            : static void
     111                 :          0 : format_rate_SI(char *buf, int size, off_t bytes)
     112                 :            : {
     113                 :            :         int i;
     114                 :            : 
     115                 :          0 :         bytes *= 100;
     116   [ #  #  #  #  :          0 :         for (i = 0; bytes >= 100*1000 && unit_SI[i][0] != 'T'; i++)
                   #  # ]
     117                 :          0 :                 bytes = (bytes + 500) / 1000;
     118         [ #  # ]:          0 :         if (i == 0) {
     119                 :          0 :                 i++;
     120                 :          0 :                 bytes = (bytes + 500) / 1000;
     121                 :          0 :         }
     122                 :          0 :         snprintf(buf, size, "%3lld.%1lld%sB",
     123                 :          0 :             (long long) (bytes + 5) / 100,
     124                 :          0 :             (long long) (bytes + 5) / 10 % 10,
     125                 :          0 :             unit_SI[i]);
     126                 :          0 : }
     127                 :            : 
     128                 :            : void
     129                 :          0 : job_status_end(xstring *msg)
     130                 :            : {
     131                 :          0 :         fflush(msg->fp);
     132                 :          0 :         printf("%s\n", msg->buf);
     133                 :          0 :         xstring_reset(msg);
     134                 :          0 : }
     135                 :            : 
     136                 :            : void
     137                 :        425 : job_status_begin(xstring *msg)
     138                 :            : {
     139                 :            :         int n;
     140                 :            : 
     141                 :        425 :         xstring_reset(msg);
     142                 :            : #ifdef HAVE_LIBJAIL
     143                 :            :         static char hostname[MAXHOSTNAMELEN] = "";
     144                 :            :         static int jailed = -1;
     145                 :            :         size_t intlen;
     146                 :            : 
     147         [ +  + ]:        425 :         if (jailed == -1) {
     148                 :        198 :                 intlen = sizeof(jailed);
     149   [ +  -  +  - ]:        396 :                 if (sysctlbyname("security.jail.jailed", &jailed, &intlen,
     150                 :        198 :                     NULL, 0) == -1)
     151                 :          0 :                         jailed = 0;
     152                 :        198 :         }
     153                 :            : 
     154         [ +  - ]:        425 :         if (jailed == 1) {
     155         [ #  # ]:          0 :                 if (hostname[0] == '\0')
     156                 :          0 :                         gethostname(hostname, sizeof(hostname));
     157                 :            : 
     158                 :          0 :                 fprintf(msg->fp, "[%s] ", hostname);
     159                 :          0 :         }
     160                 :            : #endif
     161                 :            : 
     162                 :            :         /* Only used for pkg-add right now. */
     163         [ +  + ]:        425 :         if (add_deps_depth) {
     164         [ +  - ]:          5 :                 if (add_deps_depth > 1) {
     165         [ #  # ]:          0 :                         for (n = 0; n < (2 * add_deps_depth); ++n) {
     166   [ #  #  #  # ]:          0 :                                 if (n % 4 == 0 && n < (2 * add_deps_depth))
     167                 :          0 :                                         fprintf(msg->fp, "|");
     168                 :            :                                 else
     169                 :          0 :                                         fprintf(msg->fp, " ");
     170                 :          0 :                         }
     171                 :          0 :                 }
     172                 :          5 :                 fprintf(msg->fp, "`-- ");
     173                 :          5 :         }
     174                 :            : 
     175   [ +  +  +  +  :        425 :         if ((nbtodl > 0 || nbactions > 0) && nbdone > 0)
                   +  + ]
     176         [ +  + ]:        189 :                 fprintf(msg->fp, "[%d/%d] ", nbdone, (nbtodl) ? nbtodl : nbactions);
     177   [ +  +  -  + ]:        425 :         if (nbtodl > 0 && nbtodl == nbdone) {
     178                 :         13 :                 nbtodl = 0;
     179                 :         13 :                 nbdone = 0;
     180                 :         13 :         }
     181                 :        425 : }
     182                 :            : 
     183                 :            : void
     184                 :       1374 : progressbar_start(const char *pmsg)
     185                 :            : {
     186         [ +  + ]:       1374 :         if (progress_message) {
     187                 :        308 :                 free(progress_message);
     188                 :        308 :                 progress_message = NULL;
     189                 :        308 :         }
     190                 :            : 
     191         [ +  + ]:       1374 :         if (quiet)
     192                 :        883 :                 return;
     193         [ +  + ]:        491 :         if (pmsg != NULL)
     194                 :        285 :                 progress_message = xstrdup(pmsg);
     195                 :            :         else {
     196                 :        206 :                 fflush(msg_buf->fp);
     197                 :        206 :                 progress_message = xstrdup(msg_buf->buf);
     198                 :            :         }
     199                 :        491 :         last_progress_percent = -1;
     200                 :        491 :         last_tick = 0;
     201                 :        491 :         begin = last_update = time(NULL);
     202                 :        491 :         bytes_per_second = 0;
     203                 :        491 :         stalled = 0;
     204                 :            : 
     205                 :        491 :         progress_started = true;
     206                 :        491 :         progress_interrupted = false;
     207         [ -  + ]:        491 :         if (!isatty(STDOUT_FILENO))
     208                 :        491 :                 printf("%s: ", progress_message);
     209                 :            :         else
     210                 :          0 :                 printf("%s:   0%%", progress_message);
     211                 :       1374 : }
     212                 :            : 
     213                 :            : void
     214                 :       2246 : progressbar_tick(int64_t current, int64_t total)
     215                 :            : {
     216                 :            :         int percent;
     217                 :            : 
     218   [ +  +  +  + ]:       2246 :         if (!quiet && progress_started) {
     219         [ -  + ]:       1043 :                 if (isatty(STDOUT_FILENO))
     220                 :          0 :                         draw_progressbar(current, total);
     221                 :            :                 else {
     222         [ +  + ]:       1043 :                         if (progress_interrupted) {
     223                 :          6 :                                 printf("%s...", progress_message);
     224         [ +  - ]:       1043 :                         } else if (!getenv("NO_TICK")){
     225         [ #  # ]:          0 :                                 percent = (total != 0) ? (current * 100. / total) : 100;
     226         [ #  # ]:          0 :                                 if (last_progress_percent / 10 < percent / 10) {
     227                 :          0 :                                         last_progress_percent = percent;
     228         [ #  # ]:          0 :                                         putchar('.');
     229                 :          0 :                                         fflush(stdout);
     230                 :          0 :                                 }
     231                 :          0 :                         }
     232         [ +  + ]:       1043 :                         if (current >= total)
     233                 :        488 :                                 progressbar_stop();
     234                 :            :                 }
     235                 :       1043 :         }
     236                 :       2246 :         progress_interrupted = false;
     237                 :       2246 : }
     238                 :            : 
     239                 :            : void
     240                 :        488 : progressbar_stop(void)
     241                 :            : {
     242         [ -  + ]:        488 :         if (progress_started) {
     243         [ -  + ]:        488 :                 if (!isatty(STDOUT_FILENO))
     244                 :        488 :                         printf(" done");
     245         [ +  + ]:        488 :                 putchar('\n');
     246                 :        488 :         }
     247                 :        488 :         last_progress_percent = -1;
     248                 :        488 :         progress_started = false;
     249                 :        488 :         progress_interrupted = false;
     250                 :        488 : }
     251                 :            : 
     252                 :            : static void
     253                 :          0 : draw_progressbar(int64_t current, int64_t total)
     254                 :            : {
     255                 :            :         int percent;
     256                 :            :         int64_t transferred;
     257                 :          0 :         time_t elapsed = 0, now = 0;
     258                 :            :         char buf[8];
     259                 :            :         int64_t bytes_left;
     260                 :            :         int cur_speed;
     261                 :            :         int hours, minutes, seconds;
     262                 :            :         float age_factor;
     263                 :            : 
     264         [ #  # ]:          0 :         if (!progress_started) {
     265                 :          0 :                 progressbar_stop();
     266                 :          0 :                 return;
     267                 :            :         }
     268                 :            : 
     269         [ #  # ]:          0 :         if (progress_debit) {
     270                 :          0 :                 now = time(NULL);
     271         [ #  # ]:          0 :                 elapsed = (now >= last_update) ? now - last_update : 0;
     272                 :          0 :         }
     273                 :            : 
     274         [ #  # ]:          0 :         percent = (total != 0) ? (current * 100. / total) : 100;
     275                 :            : 
     276                 :            :         /**
     277                 :            :          * Wait for interval for debit bars to keep calc per second.
     278                 :            :          * If not debit, show on every % change, or if ticking after
     279                 :            :          * an interruption (which removed our progressbar output).
     280                 :            :          */
     281   [ #  #  #  #  :          0 :         if (current >= total || (progress_debit && elapsed >= 1) ||
             #  #  #  # ]
     282         [ #  # ]:          0 :             (!progress_debit &&
     283         [ #  # ]:          0 :             (percent != last_progress_percent || progress_interrupted))) {
     284                 :          0 :                 last_progress_percent = percent;
     285                 :            : 
     286                 :          0 :                 printf("\r%s: %3d%%", progress_message, percent);
     287         [ #  # ]:          0 :                 if (progress_debit) {
     288                 :          0 :                         transferred = current - last_tick;
     289                 :          0 :                         last_tick = current;
     290                 :          0 :                         bytes_left = total - current;
     291         [ #  # ]:          0 :                         if (bytes_left <= 0) {
     292                 :          0 :                                 elapsed = now - begin;
     293                 :            :                                 /* Always show at least 1 second at end. */
     294         [ #  # ]:          0 :                                 if (elapsed == 0)
     295                 :          0 :                                         elapsed = 1;
     296                 :            :                                 /* Calculate true total speed when done */
     297                 :          0 :                                 transferred = total;
     298                 :          0 :                                 bytes_per_second = 0;
     299                 :          0 :                         }
     300                 :            : 
     301         [ #  # ]:          0 :                         if (elapsed != 0)
     302                 :          0 :                                 cur_speed = (transferred / elapsed);
     303                 :            :                         else
     304                 :          0 :                                 cur_speed = transferred;
     305                 :            : 
     306                 :            : #define AGE_FACTOR_SLOW_START 3
     307         [ #  # ]:          0 :                         if (now - begin <= AGE_FACTOR_SLOW_START)
     308                 :          0 :                                 age_factor = 0.4;
     309                 :            :                         else
     310                 :          0 :                                 age_factor = 0.9;
     311                 :            : 
     312         [ #  # ]:          0 :                         if (bytes_per_second != 0) {
     313                 :          0 :                                 bytes_per_second =
     314                 :          0 :                                     (bytes_per_second * age_factor) +
     315                 :          0 :                                     (cur_speed * (1.0 - age_factor));
     316                 :          0 :                         } else
     317                 :          0 :                                 bytes_per_second = cur_speed;
     318                 :            : 
     319                 :          0 :                         humanize_number(buf, sizeof(buf),
     320                 :          0 :                             current,"B", HN_AUTOSCALE, HN_IEC_PREFIXES);
     321                 :          0 :                         printf(" %*s", (int)sizeof(buf), buf);
     322                 :            : 
     323         [ #  # ]:          0 :                         if (bytes_left > 0)
     324                 :          0 :                                 format_rate_SI(buf, sizeof(buf), transferred);
     325                 :            :                         else /* Show overall speed when done */
     326                 :          0 :                                 format_rate_SI(buf, sizeof(buf),
     327                 :          0 :                                     bytes_per_second);
     328                 :          0 :                         printf(" %s/s ", buf);
     329                 :            : 
     330         [ #  # ]:          0 :                         if (!transferred)
     331                 :          0 :                                 stalled += elapsed;
     332                 :            :                         else
     333                 :          0 :                                 stalled = 0;
     334                 :            : 
     335         [ #  # ]:          0 :                         if (stalled >= STALL_TIME)
     336                 :          0 :                                 printf(" - stalled -");
     337   [ #  #  #  # ]:          0 :                         else if (bytes_per_second == 0 && bytes_left > 0)
     338                 :          0 :                                 printf("   --:-- ETA");
     339                 :            :                         else {
     340         [ #  # ]:          0 :                                 if (bytes_left > 0)
     341                 :          0 :                                         seconds = bytes_left / bytes_per_second;
     342                 :            :                                 else
     343                 :          0 :                                         seconds = elapsed;
     344                 :            : 
     345                 :          0 :                                 hours = seconds / 3600;
     346                 :          0 :                                 seconds -= hours * 3600;
     347                 :          0 :                                 minutes = seconds / 60;
     348                 :          0 :                                 seconds -= minutes * 60;
     349                 :            : 
     350         [ #  # ]:          0 :                                 if (hours != 0)
     351                 :          0 :                                         printf("%02d:%02d:%02d", hours,
     352                 :          0 :                                             minutes, seconds);
     353                 :            :                                 else
     354                 :          0 :                                         printf("   %02d:%02d", minutes, seconds);
     355                 :            : 
     356         [ #  # ]:          0 :                                 if (bytes_left > 0)
     357                 :          0 :                                         printf(" ETA");
     358                 :            :                                 else
     359                 :          0 :                                         printf("    ");
     360                 :            :                         }
     361                 :          0 :                         last_update = now;
     362                 :          0 :                 }
     363                 :          0 :                 fflush(stdout);
     364                 :          0 :         }
     365         [ #  # ]:          0 :         if (current >= total)
     366                 :          0 :                 progressbar_stop();
     367                 :          0 : }
     368                 :            : 
     369                 :            : int
     370                 :       6695 : event_callback(void *data, struct pkg_event *ev)
     371                 :            : {
     372                 :       6695 :         struct pkg *pkg = NULL, *pkg_new, *pkg_old;
     373                 :            :         struct cleanup *evtmp;
     374                 :       6695 :         int *debug = data;
     375                 :            :         struct pkg_event_conflict *cur_conflict;
     376                 :       6695 :         const char *filename, *reponame = NULL;
     377                 :            : 
     378         [ +  + ]:       6695 :         if (msg_buf == NULL) {
     379                 :        673 :                 msg_buf = xstring_new();
     380                 :        673 :         }
     381                 :            : 
     382                 :            :         /*
     383                 :            :          * If a progressbar has been interrupted by another event, then
     384                 :            :          * we need to add a newline to prevent bad formatting.
     385                 :            :          */
     386   [ +  +  +  +  :       6695 :         if (progress_started && ev->type != PKG_EVENT_PROGRESS_TICK &&
                   +  + ]
     387                 :         33 :             !progress_interrupted) {
     388         [ -  + ]:          9 :                 putchar('\n');
     389                 :          9 :                 progress_interrupted = true;
     390                 :          9 :         }
     391                 :            : 
     392   [ -  +  +  -  :       6695 :         switch(ev->type) {
          +  +  +  +  +  
          -  -  +  -  -  
          +  -  -  -  -  
          +  +  -  +  +  
          +  +  -  +  +  
          +  -  -  +  +  
          +  +  +  +  -  
          +  +  +  +  +  
          -  -  -  -  -  
             +  +  +  + ]
     393                 :            :         case PKG_EVENT_ERRNO:
     394                 :          0 :                 warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg,
     395                 :          0 :                     strerror(ev->e_errno.no));
     396                 :          0 :                 break;
     397                 :            :         case PKG_EVENT_ERROR:
     398                 :        104 :                 warnx("%s", ev->e_pkg_error.msg);
     399                 :        104 :                 break;
     400                 :            :         case PKG_EVENT_NOTICE:
     401         [ +  + ]:         23 :                 if (!quiet)
     402                 :         22 :                         printf("%s\n", ev->e_pkg_notice.msg);
     403                 :         23 :                 break;
     404                 :            :         case PKG_EVENT_DEVELOPER_MODE:
     405                 :          0 :                 warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg);
     406                 :          0 :                 break;
     407                 :            :         case PKG_EVENT_UPDATE_ADD:
     408   [ #  #  #  # ]:          0 :                 if (quiet || !isatty(STDOUT_FILENO))
     409                 :          0 :                         break;
     410                 :          0 :                 printf("\rPushing new entries %d/%d", ev->e_upd_add.done, ev->e_upd_add.total);
     411         [ #  # ]:          0 :                 if (ev->e_upd_add.total == ev->e_upd_add.done)
     412         [ #  # ]:          0 :                         putchar('\n');
     413                 :          0 :                 break;
     414                 :            :         case PKG_EVENT_UPDATE_REMOVE:
     415   [ #  #  #  # ]:          0 :                 if (quiet || !isatty(STDOUT_FILENO))
     416                 :          0 :                         break;
     417                 :          0 :                 printf("\rRemoving entries %d/%d", ev->e_upd_remove.done, ev->e_upd_remove.total);
     418         [ #  # ]:          0 :                 if (ev->e_upd_remove.total == ev->e_upd_remove.done)
     419         [ #  # ]:          0 :                         putchar('\n');
     420                 :          0 :                 break;
     421                 :            :         case PKG_EVENT_FETCH_BEGIN:
     422         [ +  + ]:        150 :                 if (nbtodl > 0)
     423                 :          1 :                         nbdone++;
     424         [ +  + ]:        150 :                 if (quiet)
     425                 :         22 :                         break;
     426                 :        128 :                 filename = strrchr(ev->e_fetching.url, '/');
     427         [ +  - ]:        128 :                 if (filename != NULL) {
     428                 :        128 :                         filename++;
     429                 :        128 :                 } else {
     430                 :            :                         /*
     431                 :            :                          * We failed at being smart, so display
     432                 :            :                          * the entire url.
     433                 :            :                          */
     434                 :          0 :                         filename = ev->e_fetching.url;
     435                 :            :                 }
     436                 :        128 :                 job_status_begin(msg_buf);
     437                 :        128 :                 progress_debit = true;
     438                 :        128 :                 fprintf(msg_buf->fp, "Fetching %s", filename);
     439                 :        128 :                 break;
     440                 :            :         case PKG_EVENT_FETCH_FINISHED:
     441                 :        150 :                 progress_debit = false;
     442                 :        150 :                 break;
     443                 :            :         case PKG_EVENT_INSTALL_BEGIN:
     444         [ +  + ]:        215 :                 if (quiet)
     445                 :         58 :                         break;
     446                 :        157 :                 job_status_begin(msg_buf);
     447                 :            : 
     448                 :        157 :                 pkg = ev->e_install_begin.pkg;
     449                 :        314 :                 pkg_fprintf(msg_buf->fp, "Installing %n-%v...\n", pkg,
     450                 :        157 :                     pkg);
     451                 :        157 :                 fflush(msg_buf->fp);
     452                 :        157 :                 printf("%s", msg_buf->buf);
     453                 :        157 :                 break;
     454                 :            :         case PKG_EVENT_INSTALL_FINISHED:
     455         [ +  + ]:        210 :                 if (quiet)
     456                 :         58 :                         break;
     457                 :        152 :                 break;
     458                 :            :         case PKG_EVENT_EXTRACT_BEGIN:
     459         [ +  + ]:        110 :                 if (quiet)
     460                 :         50 :                         break;
     461                 :            :                 else {
     462                 :         60 :                         job_status_begin(msg_buf);
     463                 :         60 :                         pkg = ev->e_install_begin.pkg;
     464                 :         60 :                         pkg_fprintf(msg_buf->fp, "Extracting %n-%v", pkg, pkg);
     465                 :         60 :                         fflush(msg_buf->fp);
     466                 :            :                 }
     467                 :         60 :                 break;
     468                 :            :         case PKG_EVENT_EXTRACT_FINISHED:
     469                 :        110 :                 break;
     470                 :            :         case PKG_EVENT_ADD_DEPS_BEGIN:
     471                 :         17 :                 ++add_deps_depth;
     472                 :         17 :                 break;
     473                 :            :         case PKG_EVENT_ADD_DEPS_FINISHED:
     474                 :         17 :                 --add_deps_depth;
     475                 :         17 :                 break;
     476                 :            :         case PKG_EVENT_INTEGRITYCHECK_BEGIN:
     477         [ +  + ]:        171 :                 if (quiet)
     478                 :         71 :                         break;
     479                 :        100 :                 printf("Checking integrity...");
     480                 :        100 :                 break;
     481                 :            :         case PKG_EVENT_INTEGRITYCHECK_FINISHED:
     482         [ +  + ]:        171 :                 if (quiet)
     483                 :         71 :                         break;
     484                 :        100 :                 printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting);
     485         [ +  + ]:        100 :                 if (conflicts != NULL) {
     486                 :         11 :                         fflush(conflicts->fp);
     487                 :         11 :                         printf("%s", conflicts->buf);
     488                 :         11 :                         xstring_free(conflicts);
     489                 :         11 :                         conflicts = NULL;
     490                 :         11 :                 }
     491                 :        100 :                 break;
     492                 :            :         case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
     493         [ #  # ]:          0 :                 if (*debug == 0)
     494                 :          0 :                         break;
     495                 :          0 :                 printf("\nConflict found on path %s between %s and ",
     496                 :          0 :                     ev->e_integrity_conflict.pkg_path,
     497                 :          0 :                     ev->e_integrity_conflict.pkg_uid);
     498                 :          0 :                 cur_conflict = ev->e_integrity_conflict.conflicts;
     499         [ #  # ]:          0 :                 while (cur_conflict) {
     500         [ #  # ]:          0 :                         if (cur_conflict->next)
     501                 :          0 :                                 printf("%s, ", cur_conflict->uid);
     502                 :            :                         else
     503                 :          0 :                                 printf("%s", cur_conflict->uid);
     504                 :            : 
     505                 :          0 :                         cur_conflict = cur_conflict->next;
     506                 :            :                 }
     507                 :          0 :                 printf("\n");
     508                 :          0 :                 break;
     509                 :            :         case PKG_EVENT_DEINSTALL_BEGIN:
     510         [ +  + ]:         44 :                 if (quiet)
     511                 :          7 :                         break;
     512                 :            : 
     513                 :         37 :                 job_status_begin(msg_buf);
     514                 :            : 
     515                 :         37 :                 pkg = ev->e_install_begin.pkg;
     516                 :         37 :                 pkg_fprintf(msg_buf->fp, "Deinstalling %n-%v...\n", pkg, pkg);
     517                 :         37 :                 fflush(msg_buf->fp);
     518                 :         37 :                 printf("%s", msg_buf->buf);
     519                 :         37 :                 break;
     520                 :            :         case PKG_EVENT_DEINSTALL_FINISHED:
     521         [ +  + ]:         35 :                 if (quiet)
     522                 :          6 :                         break;
     523                 :         29 :                 break;
     524                 :            :         case PKG_EVENT_DELETE_FILES_BEGIN:
     525         [ +  + ]:         24 :                 if (quiet)
     526                 :          6 :                         break;
     527                 :            :                 else {
     528                 :         18 :                         job_status_begin(msg_buf);
     529                 :         18 :                         pkg = ev->e_install_begin.pkg;
     530                 :         36 :                         pkg_fprintf(msg_buf->fp, "Deleting files for %n-%v",
     531                 :         18 :                             pkg, pkg);
     532                 :            :                 }
     533                 :         18 :                 break;
     534                 :            :         case PKG_EVENT_DELETE_FILES_FINISHED:
     535                 :         24 :                 break;
     536                 :            :         case PKG_EVENT_UPGRADE_BEGIN:
     537         [ +  + ]:         33 :                 if (quiet)
     538                 :          8 :                         break;
     539                 :         25 :                 pkg_new = ev->e_upgrade_begin.n;
     540                 :         25 :                 pkg_old = ev->e_upgrade_begin.o;
     541                 :            : 
     542                 :         25 :                 job_status_begin(msg_buf);
     543                 :            : 
     544   [ +  -  -  + ]:         25 :                 switch (pkg_version_change_between(pkg_new, pkg_old)) {
     545                 :            :                 case PKG_DOWNGRADE:
     546                 :          0 :                         pkg_fprintf(msg_buf->fp, "Downgrading %n from %v to %v...\n",
     547                 :          0 :                             pkg_new, pkg_old, pkg_new);
     548                 :          0 :                         break;
     549                 :            :                 case PKG_REINSTALL:
     550                 :          8 :                         pkg_fprintf(msg_buf->fp, "Reinstalling %n-%v...\n",
     551                 :          4 :                     pkg_old, pkg_old);
     552                 :          4 :                         break;
     553                 :            :                 case PKG_UPGRADE:
     554                 :         42 :                         pkg_fprintf(msg_buf->fp, "Upgrading %n from %v to %v...\n",
     555                 :         21 :                             pkg_new, pkg_old, pkg_new);
     556                 :         21 :                         break;
     557                 :            :                 }
     558                 :         25 :                 fflush(msg_buf->fp);
     559                 :         25 :                 printf("%s", msg_buf->buf);
     560                 :         25 :                 break;
     561                 :            :         case PKG_EVENT_UPGRADE_FINISHED:
     562         [ +  + ]:         33 :                 if (quiet)
     563                 :          8 :                         break;
     564                 :         25 :                 break;
     565                 :            :         case PKG_EVENT_LOCKED:
     566                 :          0 :                 pkg = ev->e_locked.pkg;
     567                 :          0 :                 pkg_printf("\n%n-%v is locked and may not be modified\n", pkg, pkg);
     568                 :          0 :                 break;
     569                 :            :         case PKG_EVENT_REQUIRED:
     570                 :          0 :                 pkg = ev->e_required.pkg;
     571                 :          0 :                 pkg_printf("\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg);
     572         [ #  # ]:          0 :                 if (ev->e_required.force == 1)
     573                 :          0 :                         fprintf(stderr, ", deleting anyway\n");
     574                 :            :                 else
     575                 :          0 :                         fprintf(stderr, "\n");
     576                 :          0 :                 break;
     577                 :            :         case PKG_EVENT_ALREADY_INSTALLED:
     578         [ #  # ]:          0 :                 if (quiet)
     579                 :          0 :                         break;
     580                 :          0 :                 pkg = ev->e_already_installed.pkg;
     581                 :          0 :                 pkg_printf("the most recent version of %n-%v is already installed\n",
     582                 :          0 :                                 pkg, pkg);
     583                 :          0 :                 break;
     584                 :            :         case PKG_EVENT_NOT_FOUND:
     585                 :          0 :                 printf("Package '%s' was not found in "
     586                 :          0 :                     "the repositories\n", ev->e_not_found.pkg_name);
     587                 :          0 :                 break;
     588                 :            :         case PKG_EVENT_MISSING_DEP:
     589                 :          5 :                 warnx("Missing dependency '%s'",
     590                 :          5 :                     pkg_dep_name(ev->e_missing_dep.dep));
     591                 :          5 :                 break;
     592                 :            :         case PKG_EVENT_NOREMOTEDB:
     593                 :          0 :                 fprintf(stderr, "Unable to open remote database \"%s\". "
     594                 :          0 :                     "Try running '%s update' first.\n", ev->e_remotedb.repo,
     595                 :          0 :                     getprogname());
     596                 :          0 :                 break;
     597                 :            :         case PKG_EVENT_NOLOCALDB:
     598                 :          0 :                 fprintf(stderr, "Local package database nonexistent!\n");
     599                 :          0 :                 break;
     600                 :            :         case PKG_EVENT_NEWPKGVERSION:
     601                 :          2 :                 newpkgversion = true;
     602                 :          2 :                 printf("New version of pkg detected; it needs to be "
     603                 :            :                     "installed first.\n");
     604                 :          2 :                 break;
     605                 :            :         case PKG_EVENT_FILE_MISMATCH:
     606                 :          0 :                 pkg = ev->e_file_mismatch.pkg;
     607                 :          0 :                 pkg_fprintf(stderr, "%n-%v: checksum mismatch for %Fn\n", pkg,
     608                 :          0 :                     pkg, ev->e_file_mismatch.file);
     609                 :          0 :                 break;
     610                 :            :         case PKG_EVENT_FILE_MISSING:
     611                 :          0 :                 pkg = ev->e_file_missing.pkg;
     612                 :          0 :                 pkg_fprintf(stderr, "%n-%v: missing file %Fn\n", pkg, pkg,
     613                 :          0 :                     ev->e_file_missing.file);
     614                 :          0 :                 break;
     615                 :            :         case PKG_EVENT_PLUGIN_ERRNO:
     616                 :          0 :                 warnx("%s: %s(%s): %s",
     617                 :          0 :                     pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
     618                 :          0 :                     ev->e_plugin_errno.func, ev->e_plugin_errno.arg,
     619                 :          0 :                     strerror(ev->e_plugin_errno.no));
     620                 :          0 :                 break;
     621                 :            :         case PKG_EVENT_PLUGIN_ERROR:
     622                 :          0 :                 warnx("%s: %s",
     623                 :          0 :                     pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
     624                 :          0 :                     ev->e_plugin_error.msg);
     625                 :          0 :                 break;
     626                 :            :         case PKG_EVENT_PLUGIN_INFO:
     627         [ #  # ]:          0 :                 if (quiet)
     628                 :          0 :                         break;
     629                 :          0 :                 printf("%s: %s\n",
     630                 :          0 :                     pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
     631                 :          0 :                     ev->e_plugin_info.msg);
     632                 :          0 :                 break;
     633                 :            :         case PKG_EVENT_INCREMENTAL_UPDATE:
     634         [ +  + ]:         72 :                 if (!quiet)
     635                 :         61 :                         printf("%s repository update completed. %d packages processed.\n",
     636                 :         61 :                             ev->e_incremental_update.reponame,
     637                 :         61 :                             ev->e_incremental_update.processed);
     638                 :         72 :                 break;
     639                 :            :         case PKG_EVENT_DEBUG:
     640                 :         98 :                 fprintf(stderr, "DBG(%d)[%d]> %s\n", ev->e_debug.level,
     641                 :         49 :                         (int)getpid(), ev->e_debug.msg);
     642                 :         49 :                 break;
     643                 :            :         case PKG_EVENT_QUERY_YESNO:
     644         [ #  # ]:          0 :                 return ( ev->e_query_yesno.deft ?
     645                 :          0 :                         query_yesno(true, ev->e_query_yesno.msg, "[Y/n]") :
     646                 :          0 :                         query_yesno(false, ev->e_query_yesno.msg, "[y/N]") );
     647                 :            :                 break;
     648                 :            :         case PKG_EVENT_QUERY_SELECT:
     649                 :          0 :                 return query_select(ev->e_query_select.msg, ev->e_query_select.items,
     650                 :          0 :                         ev->e_query_select.ncnt, ev->e_query_select.deft);
     651                 :            :                 break;
     652                 :            :         case PKG_EVENT_SANDBOX_CALL:
     653                 :         16 :                 return ( pkg_handle_sandboxed_call(ev->e_sandbox_call.call,
     654                 :          8 :                                 ev->e_sandbox_call.fd,
     655                 :          8 :                                 ev->e_sandbox_call.userdata) );
     656                 :            :                 break;
     657                 :            :         case PKG_EVENT_SANDBOX_GET_STRING:
     658                 :        144 :                 return ( pkg_handle_sandboxed_get_string(ev->e_sandbox_call_str.call,
     659                 :         72 :                                 ev->e_sandbox_call_str.result,
     660                 :         72 :                                 ev->e_sandbox_call_str.len,
     661                 :         72 :                                 ev->e_sandbox_call_str.userdata) );
     662                 :            :                 break;
     663                 :            :         case PKG_EVENT_PROGRESS_START:
     664                 :       1374 :                 progressbar_start(ev->e_progress_start.msg);
     665                 :       1374 :                 break;
     666                 :            :         case PKG_EVENT_PROGRESS_TICK:
     667                 :       4492 :                 progressbar_tick(ev->e_progress_tick.current,
     668                 :       2246 :                     ev->e_progress_tick.total);
     669                 :       2246 :                 break;
     670                 :            :         case PKG_EVENT_BACKUP:
     671                 :          0 :                 fprintf(msg_buf->fp, "Backing up");
     672                 :          0 :                 break;
     673                 :            :         case PKG_EVENT_RESTORE:
     674                 :          0 :                 fprintf(msg_buf->fp, "Restoring");
     675                 :          0 :                 break;
     676                 :            :         case PKG_EVENT_NEW_ACTION:
     677                 :        207 :                 nbdone++;
     678                 :        207 :                 break;
     679                 :            :         case PKG_EVENT_MESSAGE:
     680         [ +  + ]:         28 :                 if (messages == NULL)
     681                 :         27 :                         messages = xstring_new();
     682                 :         28 :                 fprintf(messages->fp, "%s", ev->e_pkg_message.msg);
     683                 :         28 :                 break;
     684                 :            :         case PKG_EVENT_CLEANUP_CALLBACK_REGISTER:
     685         [ +  + ]:        185 :                 if (!signal_handler_installed) {
     686                 :        130 :                         signal(SIGINT, cleanup_handler);
     687                 :        130 :                         signal_handler_installed = true;
     688                 :        130 :                 }
     689                 :        185 :                 evtmp = xmalloc(sizeof(struct cleanup));
     690                 :        185 :                 evtmp->cb = ev->e_cleanup_callback.cleanup_cb;
     691                 :        185 :                 evtmp->data = ev->e_cleanup_callback.data;
     692   [ -  +  +  -  :        185 :                 tll_push_back(cleanup_list, evtmp);
          #  #  -  +  -  
                      + ]
     693                 :        185 :                 break;
     694                 :            :         case PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER:
     695         [ +  + ]:        247 :                 if (!signal_handler_installed)
     696                 :         62 :                         break;
     697   [ +  -  -  +  :        185 :                 tll_foreach(cleanup_list, it) {
                   #  # ]
     698                 :        185 :                         evtmp = it->item;
     699   [ +  -  -  + ]:        185 :                         if (evtmp->cb == ev->e_cleanup_callback.cleanup_cb &&
     700                 :        185 :                             evtmp->data == ev->e_cleanup_callback.data) {
     701   [ +  -  -  +  :        185 :                                 tll_remove_and_free(cleanup_list, it, free);
                   -  + ]
     702                 :        185 :                                 break;
     703                 :            :                         }
     704                 :          0 :                 }
     705                 :        185 :                 break;
     706                 :            :         case PKG_EVENT_CONFLICTS:
     707         [ +  + ]:         23 :                 if (conflicts == NULL) {
     708                 :         13 :                         conflicts = xstring_new();
     709                 :         13 :                 }
     710                 :         46 :                 pkg_fprintf(conflicts->fp, "  - %n-%v",
     711                 :         23 :                     ev->e_conflicts.p1, ev->e_conflicts.p1);
     712         [ +  + ]:         23 :                 if (pkg_repos_total_count() > 1) {
     713                 :          4 :                         pkg_get(ev->e_conflicts.p1, PKG_ATTR_REPONAME, &reponame);
     714                 :          8 :                         fprintf(conflicts->fp, " [%s]",
     715         [ +  - ]:          4 :                             reponame == NULL ? "installed" : reponame);
     716                 :          4 :                 }
     717                 :         46 :                 pkg_fprintf(conflicts->fp, " conflicts with %n-%v",
     718                 :         23 :                     ev->e_conflicts.p2, ev->e_conflicts.p2);
     719         [ +  + ]:         23 :                 if (pkg_repos_total_count() > 1) {
     720                 :          4 :                         pkg_get(ev->e_conflicts.p2, PKG_ATTR_REPONAME, &reponame);
     721                 :          8 :                         fprintf(conflicts->fp, " [%s]",
     722         [ +  + ]:          4 :                             reponame == NULL ? "installed" : reponame);
     723                 :          4 :                 }
     724                 :         46 :                 fprintf(conflicts->fp, " on %s\n",
     725                 :         23 :                     ev->e_conflicts.path);
     726                 :         23 :                 break;
     727                 :            :         case PKG_EVENT_TRIGGER:
     728         [ +  + ]:        537 :                 if (!quiet) {
     729         [ -  + ]:          1 :                         if (ev->e_trigger.cleanup)
     730                 :          0 :                                 printf("==> Cleaning up trigger: %s\n", ev->e_trigger.name);
     731                 :            :                         else
     732                 :          1 :                                 printf("==> Running trigger: %s\n", ev->e_trigger.name);
     733                 :          1 :                 }
     734                 :            :         default:
     735                 :        536 :                 break;
     736                 :            :         }
     737                 :            : 
     738                 :       6615 :         return 0;
     739                 :       6695 : }

Generated by: LCOV version 1.15