LCOV - code coverage report
Current view: top level - src - event.c (source / functions) Hit Total Coverage
Test: rapport Lines: 277 548 50.5 %
Date: 2021-12-10 16:22:55 Functions: 7 11 63.6 %
Branches: 78 173 45.1 %

           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 <kvec.h>
      58                 :            : 
      59                 :            : #include <bsd_compat.h>
      60                 :            : 
      61                 :            : #include "pkg.h"
      62                 :            : #include "pkgcli.h"
      63                 :            : 
      64                 :            : #define STALL_TIME 5
      65                 :            : 
      66                 :            : xstring *messages = NULL;
      67                 :            : xstring *conflicts = NULL;
      68                 :            : 
      69                 :            : struct cleanup {
      70                 :            :         void *data;
      71                 :            :         void (*cb)(void *);
      72                 :            : };
      73                 :            : 
      74                 :            : static char *progress_message = NULL;
      75                 :            : static xstring *msg_buf = NULL;
      76                 :            : static int last_progress_percent = -1;
      77                 :            : static bool progress_started = false;
      78                 :            : static bool progress_interrupted = false;
      79                 :            : static bool progress_debit = false;
      80                 :            : static int64_t last_tick = 0;
      81                 :            : static int64_t stalled;
      82                 :            : static int64_t bytes_per_second;
      83                 :            : static time_t last_update;
      84                 :            : static time_t begin = 0;
      85                 :            : static int add_deps_depth;
      86                 :            : static kvec_t(struct cleanup *) cleanup_list;
      87                 :            : static bool signal_handler_installed = false;
      88                 :            : 
      89                 :            : /* units for format_size */
      90                 :            : static const char *unit_SI[] = { " ", "k", "M", "G", "T", };
      91                 :            : 
      92                 :            : static void draw_progressbar(int64_t current, int64_t total);
      93                 :            : 
      94                 :            : static void
      95                 :          0 : cleanup_handler(int dummy __unused)
      96                 :            : {
      97                 :            :         struct cleanup *ev;
      98                 :            :         size_t i;
      99                 :            : 
     100         [ #  # ]:          0 :         if (kv_size(cleanup_list) == 0)
     101                 :          0 :                 return;
     102                 :          0 :         warnx("\nsignal received, cleaning up");
     103         [ #  # ]:          0 :         for (i = 0; i < kv_size(cleanup_list); i++) {
     104                 :          0 :                 ev = kv_A(cleanup_list, i);
     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                 :       1763 : job_status_begin(xstring *msg)
     138                 :            : {
     139                 :            :         int n;
     140                 :            : 
     141                 :       1763 :         xstring_reset(msg);
     142                 :            : #ifdef HAVE_LIBJAIL
     143                 :            :         static char hostname[MAXHOSTNAMELEN] = "";
     144                 :            :         static int jailed = -1;
     145                 :            :         size_t intlen;
     146                 :            : 
     147                 :       1763 :         if (jailed == -1) {
     148                 :        894 :                 intlen = sizeof(jailed);
     149                 :       1788 :                 if (sysctlbyname("security.jail.jailed", &jailed, &intlen,
     150                 :        894 :                     NULL, 0) == -1)
     151                 :          0 :                         jailed = 0;
     152                 :        894 :         }
     153                 :            : 
     154                 :       1788 :         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                 :         47 :         if (add_deps_depth) {
     164                 :         47 :                 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                 :         47 :                 fprintf(msg->fp, "`-- ");
     173                 :         47 :         }
     174                 :            : 
     175                 :       1743 :         if ((nbtodl > 0 || nbactions > 0) && nbdone > 0)
     176         [ +  + ]:        691 :                 fprintf(msg->fp, "[%d/%d] ", nbdone, (nbtodl) ? nbtodl : nbactions);
     177                 :       1362 :         if (nbtodl > 0 && nbtodl == nbdone) {
     178                 :         20 :                 nbtodl = 0;
     179                 :         20 :                 nbdone = 0;
     180                 :         20 :         }
     181                 :       1763 : }
     182                 :            : 
     183                 :            : static int
     184                 :         20 : event_sandboxed_call(pkg_sandbox_cb func, int fd, void *ud)
     185                 :            : {
     186                 :            :         pid_t pid;
     187                 :            :         int status, ret;
     188                 :            :         struct rlimit rl_zero;
     189                 :            : 
     190                 :         20 :         ret = -1;
     191                 :         20 :         pid = fork();
     192                 :            : 
     193      [ -  -  + ]:         20 :         switch(pid) {
     194                 :            :         case -1:
     195                 :          0 :                 warn("fork failed");
     196                 :          0 :                 return (EPKG_FATAL);
     197                 :            :                 break;
     198                 :            :         case 0:
     199                 :          0 :                 break;
     200                 :            :         default:
     201                 :            :                 /* Parent process */
     202                 :         20 :                 while (waitpid(pid, &status, 0) == -1) {
     203         [ #  # ]:          0 :                         if (errno != EINTR) {
     204                 :          0 :                                 warn("Sandboxed process pid=%d", (int)pid);
     205                 :          0 :                                 ret = -1;
     206                 :          0 :                                 break;
     207                 :            :                         }
     208                 :            :                 }
     209                 :            : 
     210                 :         20 :                 if (WIFEXITED(status)) {
     211                 :         20 :                         ret = WEXITSTATUS(status);
     212                 :         20 :                 }
     213                 :         20 :                 if (WIFSIGNALED(status)) {
     214                 :            :                         /* Process got some terminating signal, hence stop the loop */
     215                 :          0 :                         fprintf(stderr, "Sandboxed process pid=%d terminated abnormally by signal: %d\n",
     216                 :          0 :                                         (int)pid, WTERMSIG(status));
     217                 :          0 :                         ret = -1;
     218                 :          0 :                 }
     219                 :         20 :                 return (ret);
     220                 :            :         }
     221                 :            : 
     222                 :          0 :         rl_zero.rlim_cur = rl_zero.rlim_max = 0;
     223         [ #  # ]:          0 :         if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
     224                 :          0 :                 err(EXIT_FAILURE, "Unable to setrlimit(RLIMIT_NPROC)");
     225                 :            : 
     226                 :            :         /* Here comes child process */
     227                 :            : #ifdef HAVE_CAPSICUM
     228                 :            : #ifndef PKG_COVERAGE
     229                 :            :         if (cap_enter() < 0 && errno != ENOSYS) {
     230                 :            :                 warn("cap_enter() failed");
     231                 :            :                 _exit(EXIT_FAILURE);
     232                 :            :         }
     233                 :            : #endif
     234                 :            : #endif
     235                 :            : 
     236                 :          0 :         ret = func(fd, ud);
     237                 :            : 
     238                 :          0 :         _exit(ret);
     239                 :         20 : }
     240                 :            : 
     241                 :            : static int
     242                 :        244 : event_sandboxed_get_string(pkg_sandbox_cb func, char **result, int64_t *len,
     243                 :            :                 void *ud)
     244                 :            : {
     245                 :            :         pid_t pid;
     246                 :            :         struct rlimit rl_zero;
     247                 :        244 :         int     status, ret = EPKG_OK;
     248                 :        244 :         int pair[2], r, allocated_len = 0, off = 0;
     249                 :        244 :         char *buf = NULL;
     250                 :            : 
     251         [ -  + ]:        244 :         if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
     252                 :          0 :                 warn("socketpair failed");
     253                 :          0 :                 return (EPKG_FATAL);
     254                 :            :         }
     255                 :            : 
     256                 :        244 :         pid = fork();
     257                 :            : 
     258      [ -  -  + ]:        244 :         switch(pid) {
     259                 :            :         case -1:
     260                 :          0 :                 warn("fork failed");
     261                 :          0 :                 return (EPKG_FATAL);
     262                 :            :                 break;
     263                 :            :         case 0:
     264                 :          0 :                 break;
     265                 :            :         default:
     266                 :            :                 /* Parent process */
     267                 :        244 :                 close(pair[0]);
     268                 :            :                 /*
     269                 :            :                  * We use blocking IO here as if the child is terminated we would have
     270                 :            :                  * EINTR here
     271                 :            :                  */
     272                 :        244 :                 buf = malloc(BUFSIZ);
     273         [ -  + ]:        244 :                 if (buf == NULL) {
     274                 :          0 :                         warn("malloc failed");
     275                 :          0 :                         return (EPKG_FATAL);
     276                 :            :                 }
     277                 :        244 :                 allocated_len = BUFSIZ;
     278                 :        244 :                 do {
     279                 :        244 :                         if (off >= allocated_len) {
     280                 :          0 :                                 allocated_len *= 2;
     281                 :          0 :                                 buf = realloc(buf, allocated_len);
     282         [ #  # ]:          0 :                                 if (buf == NULL) {
     283                 :          0 :                                         warn("realloc failed");
     284                 :          0 :                                         return (EPKG_FATAL);
     285                 :            :                                 }
     286                 :          0 :                         }
     287                 :            : 
     288                 :          0 :                         r = read(pair[1], buf + off, allocated_len - off);
     289                 :          0 :                         if (r == -1 && errno != EINTR) {
     290                 :          0 :                                 free(buf);
     291                 :          0 :                                 warn("read failed");
     292                 :          0 :                                 return (EPKG_FATAL);
     293                 :            :                         }
     294                 :         23 :                         else if (r > 0) {
     295                 :         23 :                                 off += r;
     296                 :         23 :                         }
     297                 :        267 :                 } while (r > 0);
     298                 :            : 
     299                 :            :                 /* Fill the result buffer */
     300                 :        244 :                 *len = off;
     301                 :        244 :                 *result = buf;
     302                 :        244 :                 if (*result == NULL) {
     303                 :          0 :                         warn("malloc failed");
     304                 :          0 :                         kill(pid, SIGTERM);
     305                 :          0 :                         ret = EPKG_FATAL;
     306                 :          0 :                 }
     307                 :        244 :                 while (waitpid(pid, &status, 0) == -1) {
     308         [ #  # ]:          0 :                         if (errno != EINTR) {
     309                 :          0 :                                 warn("Sandboxed process pid=%d", (int)pid);
     310                 :          0 :                                 ret = -1;
     311                 :          0 :                                 break;
     312                 :            :                         }
     313                 :            :                 }
     314                 :            : 
     315                 :        244 :                 if (WIFEXITED(status)) {
     316                 :        244 :                         ret = WEXITSTATUS(status);
     317                 :        244 :                 }
     318                 :        244 :                 if (WIFSIGNALED(status)) {
     319                 :            :                         /* Process got some terminating signal, hence stop the loop */
     320                 :          0 :                         fprintf(stderr, "Sandboxed process pid=%d terminated abnormally by signal: %d\n",
     321                 :          0 :                                         (int)pid, WTERMSIG(status));
     322                 :          0 :                         ret = -1;
     323                 :          0 :                 }
     324                 :        244 :                 return (ret);
     325                 :            :         }
     326                 :            : 
     327                 :            :         /* Here comes child process */
     328                 :          0 :         close(pair[1]);
     329                 :            : 
     330                 :          0 :         drop_privileges();
     331                 :            : 
     332                 :          0 :         rl_zero.rlim_cur = rl_zero.rlim_max = 0;
     333         [ #  # ]:          0 :         if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
     334                 :          0 :                 err(EXIT_FAILURE, "Unable to setrlimit(RLIMIT_NPROC)");
     335                 :            : 
     336                 :            : #ifdef HAVE_CAPSICUM
     337                 :            : #ifndef PKG_COVERAGE
     338                 :            :         if (cap_enter() < 0 && errno != ENOSYS) {
     339                 :            :                 warn("cap_enter() failed");
     340                 :            :                 return (EPKG_FATAL);
     341                 :            :         }
     342                 :            : #endif
     343                 :            : #endif
     344                 :            : 
     345                 :          0 :         ret = func(pair[0], ud);
     346                 :            : 
     347                 :          0 :         close(pair[0]);
     348                 :            : 
     349                 :          0 :         _exit(ret);
     350                 :        244 : }
     351                 :            : 
     352                 :            : void
     353                 :       5137 : progressbar_start(const char *pmsg)
     354                 :            : {
     355                 :       5137 :         free(progress_message);
     356                 :       5137 :         progress_message = NULL;
     357                 :            : 
     358         [ +  + ]:       5137 :         if (quiet)
     359                 :       3307 :                 return;
     360         [ +  + ]:       1830 :         if (pmsg != NULL)
     361                 :       1083 :                 progress_message = strdup(pmsg);
     362                 :            :         else {
     363                 :        747 :                 fflush(msg_buf->fp);
     364                 :        747 :                 progress_message = strdup(msg_buf->buf);
     365                 :            :         }
     366                 :       1830 :         last_progress_percent = -1;
     367                 :       1830 :         last_tick = 0;
     368                 :       1830 :         begin = last_update = time(NULL);
     369                 :       1830 :         bytes_per_second = 0;
     370                 :       1830 :         stalled = 0;
     371                 :            : 
     372                 :       1830 :         progress_started = true;
     373                 :       1830 :         progress_interrupted = false;
     374         [ +  - ]:       1830 :         if (!isatty(STDOUT_FILENO))
     375                 :       1830 :                 printf("%s: ", progress_message);
     376                 :            :         else
     377                 :          0 :                 printf("%s:   0%%", progress_message);
     378                 :       5137 : }
     379                 :            : 
     380                 :            : void
     381                 :       8842 : progressbar_tick(int64_t current, int64_t total)
     382                 :            : {
     383                 :            :         int percent;
     384                 :            : 
     385                 :       8842 :         if (!quiet && progress_started) {
     386         [ -  + ]:       4204 :                 if (isatty(STDOUT_FILENO))
     387                 :          0 :                         draw_progressbar(current, total);
     388                 :            :                 else {
     389         [ +  + ]:       4204 :                         if (progress_interrupted) {
     390                 :          8 :                                 printf("%s...", progress_message);
     391                 :       4204 :                         } else if (!getenv("NO_TICK")){
     392         [ #  # ]:          0 :                                 percent = (total != 0) ? (current * 100. / total) : 100;
     393                 :          0 :                                 if (last_progress_percent / 10 < percent / 10) {
     394                 :          0 :                                         last_progress_percent = percent;
     395                 :          0 :                                         printf(".");
     396                 :          0 :                                         fflush(stdout);
     397                 :          0 :                                 }
     398                 :          0 :                         }
     399                 :       4204 :                         if (current >= total)
     400                 :       1830 :                                 progressbar_stop();
     401                 :            :                 }
     402                 :       4204 :         }
     403                 :       8842 :         progress_interrupted = false;
     404                 :       8842 : }
     405                 :            : 
     406                 :            : void
     407                 :       1830 : progressbar_stop(void)
     408                 :            : {
     409                 :       1830 :         if (progress_started) {
     410                 :       1830 :                 if (!isatty(STDOUT_FILENO))
     411                 :       1830 :                         printf(" done");
     412         [ +  - ]:       1830 :                 putchar('\n');
     413                 :       1830 :         }
     414                 :       1830 :         last_progress_percent = -1;
     415                 :       1830 :         progress_started = false;
     416                 :       1830 :         progress_interrupted = false;
     417                 :       1830 : }
     418                 :            : 
     419                 :            : static void
     420                 :          0 : draw_progressbar(int64_t current, int64_t total)
     421                 :            : {
     422                 :            :         int percent;
     423                 :            :         int64_t transferred;
     424                 :          0 :         time_t elapsed = 0, now = 0;
     425                 :            :         char buf[8];
     426                 :            :         int64_t bytes_left;
     427                 :            :         int cur_speed;
     428                 :            :         int hours, minutes, seconds;
     429                 :            :         float age_factor;
     430                 :            : 
     431         [ #  # ]:          0 :         if (!progress_started) {
     432                 :          0 :                 progressbar_stop();
     433                 :          0 :                 return;
     434                 :            :         }
     435                 :            : 
     436                 :          0 :         if (progress_debit) {
     437                 :          0 :                 now = time(NULL);
     438         [ #  # ]:          0 :                 elapsed = (now >= last_update) ? now - last_update : 0;
     439                 :          0 :         }
     440                 :            : 
     441         [ #  # ]:          0 :         percent = (total != 0) ? (current * 100. / total) : 100;
     442                 :            : 
     443                 :            :         /**
     444                 :            :          * Wait for interval for debit bars to keep calc per second.
     445                 :            :          * If not debit, show on every % change, or if ticking after
     446                 :            :          * an interruption (which removed our progressbar output).
     447                 :            :          */
     448                 :          0 :         if (current >= total || (progress_debit && elapsed >= 1) ||
     449                 :          0 :             (!progress_debit &&
     450                 :          0 :             (percent != last_progress_percent || progress_interrupted))) {
     451                 :          0 :                 last_progress_percent = percent;
     452                 :            : 
     453                 :          0 :                 printf("\r%s: %3d%%", progress_message, percent);
     454                 :          0 :                 if (progress_debit) {
     455                 :          0 :                         transferred = current - last_tick;
     456                 :          0 :                         last_tick = current;
     457                 :          0 :                         bytes_left = total - current;
     458                 :          0 :                         if (bytes_left <= 0) {
     459                 :          0 :                                 elapsed = now - begin;
     460                 :            :                                 /* Always show at least 1 second at end. */
     461                 :          0 :                                 if (elapsed == 0)
     462                 :          0 :                                         elapsed = 1;
     463                 :            :                                 /* Calculate true total speed when done */
     464                 :          0 :                                 transferred = total;
     465                 :          0 :                                 bytes_per_second = 0;
     466                 :          0 :                         }
     467                 :            : 
     468         [ #  # ]:          0 :                         if (elapsed != 0)
     469                 :          0 :                                 cur_speed = (transferred / elapsed);
     470                 :            :                         else
     471                 :          0 :                                 cur_speed = transferred;
     472                 :            : 
     473                 :            : #define AGE_FACTOR_SLOW_START 3
     474         [ #  # ]:          0 :                         if (now - begin <= AGE_FACTOR_SLOW_START)
     475                 :          0 :                                 age_factor = 0.4;
     476                 :            :                         else
     477                 :          0 :                                 age_factor = 0.9;
     478                 :            : 
     479         [ #  # ]:          0 :                         if (bytes_per_second != 0) {
     480                 :          0 :                                 bytes_per_second =
     481                 :          0 :                                     (bytes_per_second * age_factor) +
     482                 :          0 :                                     (cur_speed * (1.0 - age_factor));
     483                 :          0 :                         } else
     484                 :          0 :                                 bytes_per_second = cur_speed;
     485                 :            : 
     486                 :          0 :                         humanize_number(buf, sizeof(buf),
     487                 :          0 :                             current,"B", HN_AUTOSCALE, HN_IEC_PREFIXES);
     488                 :          0 :                         printf(" %*s", (int)sizeof(buf), buf);
     489                 :            : 
     490         [ #  # ]:          0 :                         if (bytes_left > 0)
     491                 :          0 :                                 format_rate_SI(buf, sizeof(buf), transferred);
     492                 :            :                         else /* Show overall speed when done */
     493                 :          0 :                                 format_rate_SI(buf, sizeof(buf),
     494                 :          0 :                                     bytes_per_second);
     495                 :          0 :                         printf(" %s/s ", buf);
     496                 :            : 
     497         [ #  # ]:          0 :                         if (!transferred)
     498                 :          0 :                                 stalled += elapsed;
     499                 :            :                         else
     500                 :          0 :                                 stalled = 0;
     501                 :            : 
     502         [ #  # ]:          0 :                         if (stalled >= STALL_TIME)
     503                 :          0 :                                 printf(" - stalled -");
     504                 :          0 :                         else if (bytes_per_second == 0 && bytes_left > 0)
     505                 :          0 :                                 printf("   --:-- ETA");
     506                 :            :                         else {
     507         [ #  # ]:          0 :                                 if (bytes_left > 0)
     508                 :          0 :                                         seconds = bytes_left / bytes_per_second;
     509                 :            :                                 else
     510                 :          0 :                                         seconds = elapsed;
     511                 :            : 
     512                 :          0 :                                 hours = seconds / 3600;
     513                 :          0 :                                 seconds -= hours * 3600;
     514                 :          0 :                                 minutes = seconds / 60;
     515                 :          0 :                                 seconds -= minutes * 60;
     516                 :            : 
     517         [ #  # ]:          0 :                                 if (hours != 0)
     518                 :          0 :                                         printf("%02d:%02d:%02d", hours,
     519                 :          0 :                                             minutes, seconds);
     520                 :            :                                 else
     521                 :          0 :                                         printf("   %02d:%02d", minutes, seconds);
     522                 :            : 
     523         [ #  # ]:          0 :                                 if (bytes_left > 0)
     524                 :          0 :                                         printf(" ETA");
     525                 :            :                                 else
     526                 :          0 :                                         printf("    ");
     527                 :            :                         }
     528                 :          0 :                         last_update = now;
     529                 :          0 :                 }
     530                 :          0 :                 fflush(stdout);
     531                 :          0 :         }
     532                 :          0 :         if (current >= total)
     533                 :          0 :                 progressbar_stop();
     534                 :          0 : }
     535                 :            : 
     536                 :            : int
     537                 :      25918 : event_callback(void *data, struct pkg_event *ev)
     538                 :            : {
     539                 :      25918 :         struct pkg *pkg = NULL, *pkg_new, *pkg_old;
     540                 :            :         struct cleanup *evtmp;
     541                 :      25918 :         int *debug = data;
     542                 :            :         size_t i;
     543                 :            :         struct pkg_event_conflict *cur_conflict;
     544                 :            :         const char *filename, *reponame;
     545                 :            : 
     546                 :      25918 :         if (msg_buf == NULL) {
     547                 :       2633 :                 msg_buf = xstring_new();
     548                 :       2633 :         }
     549                 :            : 
     550                 :            :         /*
     551                 :            :          * If a progressbar has been interrupted by another event, then
     552                 :            :          * we need to add a newline to prevent bad formatting.
     553                 :            :          */
     554                 :       4212 :         if (progress_started && ev->type != PKG_EVENT_PROGRESS_TICK &&
     555                 :          8 :             !progress_interrupted) {
     556         [ +  - ]:          8 :                 putchar('\n');
     557                 :          8 :                 progress_interrupted = true;
     558                 :          8 :         }
     559                 :            : 
     560   [ -  +  +  -  :      23800 :         switch(ev->type) {
          -  -  +  +  +  
          +  +  +  +  +  
          +  +  -  +  +  
          +  +  +  +  -  
          -  -  -  +  -  
          -  +  -  -  -  
          -  -  +  +  -  
          -  +  +  +  +  
          -  -  +  +  +  
                +  +  - ]
     561                 :            :         case PKG_EVENT_ERRNO:
     562                 :          0 :                 warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg,
     563                 :          0 :                     strerror(ev->e_errno.no));
     564                 :          0 :                 break;
     565                 :            :         case PKG_EVENT_ERROR:
     566                 :        218 :                 warnx("%s", ev->e_pkg_error.msg);
     567                 :        218 :                 break;
     568                 :            :         case PKG_EVENT_NOTICE:
     569                 :         20 :                 if (!quiet)
     570                 :         16 :                         printf("%s\n", ev->e_pkg_notice.msg);
     571                 :         20 :                 break;
     572                 :            :         case PKG_EVENT_DEVELOPER_MODE:
     573                 :          0 :                 warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg);
     574                 :          0 :                 break;
     575                 :            :         case PKG_EVENT_UPDATE_ADD:
     576                 :          0 :                 if (quiet || !isatty(STDOUT_FILENO))
     577                 :          0 :                         break;
     578                 :          0 :                 printf("\rPushing new entries %d/%d", ev->e_upd_add.done, ev->e_upd_add.total);
     579                 :          0 :                 if (ev->e_upd_add.total == ev->e_upd_add.done)
     580                 :          0 :                         printf("\n");
     581                 :          0 :                 break;
     582                 :            :         case PKG_EVENT_UPDATE_REMOVE:
     583                 :          0 :                 if (quiet || !isatty(STDOUT_FILENO))
     584                 :          0 :                         break;
     585                 :          0 :                 printf("\rRemoving entries %d/%d", ev->e_upd_remove.done, ev->e_upd_remove.total);
     586                 :          0 :                 if (ev->e_upd_remove.total == ev->e_upd_remove.done)
     587                 :          0 :                         printf("\n");
     588                 :          0 :                 break;
     589                 :            :         case PKG_EVENT_FETCH_BEGIN:
     590                 :        496 :                 if (nbtodl > 0)
     591                 :          4 :                         nbdone++;
     592         [ +  + ]:        496 :                 if (quiet)
     593                 :         78 :                         break;
     594                 :        418 :                 filename = strrchr(ev->e_fetching.url, '/');
     595         [ +  - ]:        418 :                 if (filename != NULL) {
     596                 :        418 :                         filename++;
     597                 :        418 :                 } else {
     598                 :            :                         /*
     599                 :            :                          * We failed at being smart, so display
     600                 :            :                          * the entire url.
     601                 :            :                          */
     602                 :          0 :                         filename = ev->e_fetching.url;
     603                 :            :                 }
     604                 :        418 :                 job_status_begin(msg_buf);
     605                 :        418 :                 progress_debit = true;
     606                 :        418 :                 fprintf(msg_buf->fp, "Fetching %s", filename);
     607                 :        418 :                 break;
     608                 :            :         case PKG_EVENT_FETCH_FINISHED:
     609                 :        496 :                 progress_debit = false;
     610                 :        496 :                 break;
     611                 :            :         case PKG_EVENT_INSTALL_BEGIN:
     612         [ +  + ]:        984 :                 if (quiet)
     613                 :        224 :                         break;
     614                 :        760 :                 job_status_begin(msg_buf);
     615                 :            : 
     616                 :        760 :                 pkg = ev->e_install_begin.pkg;
     617                 :       1520 :                 pkg_fprintf(msg_buf->fp, "Installing %n-%v...\n", pkg,
     618                 :        760 :                     pkg);
     619                 :        760 :                 fflush(msg_buf->fp);
     620                 :        760 :                 printf("%s", msg_buf->buf);
     621                 :        760 :                 break;
     622                 :            :         case PKG_EVENT_INSTALL_FINISHED:
     623         [ +  + ]:        937 :                 if (quiet)
     624                 :        224 :                         break;
     625                 :        713 :                 break;
     626                 :            :         case PKG_EVENT_EXTRACT_BEGIN:
     627         [ +  + ]:        440 :                 if (quiet)
     628                 :        184 :                         break;
     629                 :            :                 else {
     630                 :        256 :                         job_status_begin(msg_buf);
     631                 :        256 :                         pkg = ev->e_install_begin.pkg;
     632                 :        256 :                         pkg_fprintf(msg_buf->fp, "Extracting %n-%v", pkg, pkg);
     633                 :        256 :                         fflush(msg_buf->fp);
     634                 :            :                 }
     635                 :        256 :                 break;
     636                 :            :         case PKG_EVENT_EXTRACT_FINISHED:
     637                 :        440 :                 break;
     638                 :            :         case PKG_EVENT_ADD_DEPS_BEGIN:
     639                 :        203 :                 ++add_deps_depth;
     640                 :        203 :                 break;
     641                 :            :         case PKG_EVENT_ADD_DEPS_FINISHED:
     642                 :        203 :                 --add_deps_depth;
     643                 :        203 :                 break;
     644                 :            :         case PKG_EVENT_INTEGRITYCHECK_BEGIN:
     645         [ +  + ]:        637 :                 if (quiet)
     646                 :        263 :                         break;
     647                 :        374 :                 printf("Checking integrity...");
     648                 :        374 :                 break;
     649                 :            :         case PKG_EVENT_INTEGRITYCHECK_FINISHED:
     650         [ +  + ]:        637 :                 if (quiet)
     651                 :        263 :                         break;
     652                 :        374 :                 printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting);
     653                 :        374 :                 if (conflicts != NULL) {
     654                 :         36 :                         fflush(conflicts->fp);
     655                 :         36 :                         printf("%s", conflicts->buf);
     656                 :         36 :                         xstring_free(conflicts);
     657                 :         36 :                         conflicts = NULL;
     658                 :         36 :                 }
     659                 :        374 :                 break;
     660                 :            :         case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
     661         [ #  # ]:          0 :                 if (*debug == 0)
     662                 :          0 :                         break;
     663                 :          0 :                 printf("\nConflict found on path %s between %s and ",
     664                 :          0 :                     ev->e_integrity_conflict.pkg_path,
     665                 :          0 :                     ev->e_integrity_conflict.pkg_uid);
     666                 :          0 :                 cur_conflict = ev->e_integrity_conflict.conflicts;
     667         [ #  # ]:          0 :                 while (cur_conflict) {
     668         [ #  # ]:          0 :                         if (cur_conflict->next)
     669                 :          0 :                                 printf("%s, ", cur_conflict->uid);
     670                 :            :                         else
     671                 :          0 :                                 printf("%s", cur_conflict->uid);
     672                 :            : 
     673                 :          0 :                         cur_conflict = cur_conflict->next;
     674                 :            :                 }
     675                 :          0 :                 printf("\n");
     676                 :          0 :                 break;
     677                 :            :         case PKG_EVENT_DEINSTALL_BEGIN:
     678         [ +  + ]:        172 :                 if (quiet)
     679                 :         24 :                         break;
     680                 :            : 
     681                 :        148 :                 job_status_begin(msg_buf);
     682                 :            : 
     683                 :        148 :                 pkg = ev->e_install_begin.pkg;
     684                 :        148 :                 pkg_fprintf(msg_buf->fp, "Deinstalling %n-%v...\n", pkg, pkg);
     685                 :        148 :                 fflush(msg_buf->fp);
     686                 :        148 :                 printf("%s", msg_buf->buf);
     687                 :        148 :                 break;
     688                 :            :         case PKG_EVENT_DEINSTALL_FINISHED:
     689         [ +  + ]:        172 :                 if (quiet)
     690                 :         24 :                         break;
     691                 :        148 :                 break;
     692                 :            :         case PKG_EVENT_DELETE_FILES_BEGIN:
     693         [ +  + ]:         93 :                 if (quiet)
     694                 :         20 :                         break;
     695                 :            :                 else {
     696                 :         73 :                         job_status_begin(msg_buf);
     697                 :         73 :                         pkg = ev->e_install_begin.pkg;
     698                 :        146 :                         pkg_fprintf(msg_buf->fp, "Deleting files for %n-%v",
     699                 :         73 :                             pkg, pkg);
     700                 :            :                 }
     701                 :         73 :                 break;
     702                 :            :         case PKG_EVENT_DELETE_FILES_FINISHED:
     703                 :         93 :                 break;
     704                 :            :         case PKG_EVENT_UPGRADE_BEGIN:
     705         [ +  + ]:        132 :                 if (quiet)
     706                 :         24 :                         break;
     707                 :        108 :                 pkg_new = ev->e_upgrade_begin.n;
     708                 :        108 :                 pkg_old = ev->e_upgrade_begin.o;
     709                 :            : 
     710                 :        108 :                 job_status_begin(msg_buf);
     711                 :            : 
     712      [ -  +  + ]:        108 :                 switch (pkg_version_change_between(pkg_new, pkg_old)) {
     713                 :            :                 case PKG_DOWNGRADE:
     714                 :          0 :                         pkg_fprintf(msg_buf->fp, "Downgrading %n from %v to %v...\n",
     715                 :          0 :                             pkg_new, pkg_old, pkg_new);
     716                 :          0 :                         break;
     717                 :            :                 case PKG_REINSTALL:
     718                 :         50 :                         pkg_fprintf(msg_buf->fp, "Reinstalling %n-%v...\n",
     719                 :         25 :                     pkg_old, pkg_old);
     720                 :         25 :                         break;
     721                 :            :                 case PKG_UPGRADE:
     722                 :        166 :                         pkg_fprintf(msg_buf->fp, "Upgrading %n from %v to %v...\n",
     723                 :         83 :                             pkg_new, pkg_old, pkg_new);
     724                 :         83 :                         break;
     725                 :            :                 }
     726                 :        108 :                 fflush(msg_buf->fp);
     727                 :        108 :                 printf("%s", msg_buf->buf);
     728                 :        108 :                 break;
     729                 :            :         case PKG_EVENT_UPGRADE_FINISHED:
     730         [ +  + ]:        132 :                 if (quiet)
     731                 :         24 :                         break;
     732                 :        108 :                 break;
     733                 :            :         case PKG_EVENT_LOCKED:
     734                 :          0 :                 pkg = ev->e_locked.pkg;
     735                 :          0 :                 pkg_printf("\n%n-%v is locked and may not be modified\n", pkg, pkg);
     736                 :          0 :                 break;
     737                 :            :         case PKG_EVENT_REQUIRED:
     738                 :          0 :                 pkg = ev->e_required.pkg;
     739                 :          0 :                 pkg_printf("\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg);
     740         [ #  # ]:          0 :                 if (ev->e_required.force == 1)
     741                 :          0 :                         fprintf(stderr, ", deleting anyway\n");
     742                 :            :                 else
     743                 :          0 :                         fprintf(stderr, "\n");
     744                 :          0 :                 break;
     745                 :            :         case PKG_EVENT_ALREADY_INSTALLED:
     746         [ #  # ]:          0 :                 if (quiet)
     747                 :          0 :                         break;
     748                 :          0 :                 pkg = ev->e_already_installed.pkg;
     749                 :          0 :                 pkg_printf("the most recent version of %n-%v is already installed\n",
     750                 :          0 :                                 pkg, pkg);
     751                 :          0 :                 break;
     752                 :            :         case PKG_EVENT_NOT_FOUND:
     753                 :          0 :                 printf("Package '%s' was not found in "
     754                 :          0 :                     "the repositories\n", ev->e_not_found.pkg_name);
     755                 :          0 :                 break;
     756                 :            :         case PKG_EVENT_MISSING_DEP:
     757                 :         65 :                 warnx("Missing dependency '%s'",
     758                 :         65 :                     pkg_dep_name(ev->e_missing_dep.dep));
     759                 :         65 :                 break;
     760                 :            :         case PKG_EVENT_NOREMOTEDB:
     761                 :          0 :                 fprintf(stderr, "Unable to open remote database \"%s\". "
     762                 :          0 :                     "Try running '%s update' first.\n", ev->e_remotedb.repo,
     763                 :          0 :                     getprogname());
     764                 :          0 :                 break;
     765                 :            :         case PKG_EVENT_NOLOCALDB:
     766                 :          0 :                 fprintf(stderr, "Local package database nonexistent!\n");
     767                 :          0 :                 break;
     768                 :            :         case PKG_EVENT_NEWPKGVERSION:
     769                 :         13 :                 newpkgversion = true;
     770                 :         13 :                 printf("New version of pkg detected; it needs to be "
     771                 :            :                     "installed first.\n");
     772                 :         13 :                 break;
     773                 :            :         case PKG_EVENT_FILE_MISMATCH:
     774                 :          0 :                 pkg = ev->e_file_mismatch.pkg;
     775                 :          0 :                 pkg_fprintf(stderr, "%n-%v: checksum mismatch for %Fn\n", pkg,
     776                 :          0 :                     pkg, ev->e_file_mismatch.file);
     777                 :          0 :                 break;
     778                 :            :         case PKG_EVENT_FILE_MISSING:
     779                 :          0 :                 pkg = ev->e_file_missing.pkg;
     780                 :          0 :                 pkg_fprintf(stderr, "%n-%v: missing file %Fn\n", pkg, pkg,
     781                 :          0 :                     ev->e_file_missing.file);
     782                 :          0 :                 break;
     783                 :            :         case PKG_EVENT_PLUGIN_ERRNO:
     784                 :          0 :                 warnx("%s: %s(%s): %s",
     785                 :          0 :                     pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
     786                 :          0 :                     ev->e_plugin_errno.func, ev->e_plugin_errno.arg,
     787                 :          0 :                     strerror(ev->e_plugin_errno.no));
     788                 :          0 :                 break;
     789                 :            :         case PKG_EVENT_PLUGIN_ERROR:
     790                 :          0 :                 warnx("%s: %s",
     791                 :          0 :                     pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
     792                 :          0 :                     ev->e_plugin_error.msg);
     793                 :          0 :                 break;
     794                 :            :         case PKG_EVENT_PLUGIN_INFO:
     795         [ #  # ]:          0 :                 if (quiet)
     796                 :          0 :                         break;
     797                 :          0 :                 printf("%s: %s\n",
     798                 :          0 :                     pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
     799                 :          0 :                     ev->e_plugin_info.msg);
     800                 :          0 :                 break;
     801                 :            :         case PKG_EVENT_INCREMENTAL_UPDATE:
     802                 :        244 :                 if (!quiet)
     803                 :        205 :                         printf("%s repository update completed. %d packages processed.\n",
     804                 :        205 :                             ev->e_incremental_update.reponame,
     805                 :        205 :                             ev->e_incremental_update.processed);
     806                 :        244 :                 break;
     807                 :            :         case PKG_EVENT_DEBUG:
     808                 :        176 :                 fprintf(stderr, "DBG(%d)[%d]> %s\n", ev->e_debug.level,
     809                 :         88 :                         (int)getpid(), ev->e_debug.msg);
     810                 :         88 :                 break;
     811                 :            :         case PKG_EVENT_QUERY_YESNO:
     812         [ #  # ]:          0 :                 return ( ev->e_query_yesno.deft ?
     813                 :          0 :                         query_yesno(true, ev->e_query_yesno.msg, "[Y/n]") :
     814                 :          0 :                         query_yesno(false, ev->e_query_yesno.msg, "[y/N]") );
     815                 :            :                 break;
     816                 :            :         case PKG_EVENT_QUERY_SELECT:
     817                 :          0 :                 return query_select(ev->e_query_select.msg, ev->e_query_select.items,
     818                 :          0 :                         ev->e_query_select.ncnt, ev->e_query_select.deft);
     819                 :            :                 break;
     820                 :            :         case PKG_EVENT_SANDBOX_CALL:
     821                 :         40 :                 return ( event_sandboxed_call(ev->e_sandbox_call.call,
     822                 :         20 :                                 ev->e_sandbox_call.fd,
     823                 :         20 :                                 ev->e_sandbox_call.userdata) );
     824                 :            :                 break;
     825                 :            :         case PKG_EVENT_SANDBOX_GET_STRING:
     826                 :        488 :                 return ( event_sandboxed_get_string(ev->e_sandbox_call_str.call,
     827                 :        244 :                                 ev->e_sandbox_call_str.result,
     828                 :        244 :                                 ev->e_sandbox_call_str.len,
     829                 :        244 :                                 ev->e_sandbox_call_str.userdata) );
     830                 :            :                 break;
     831                 :            :         case PKG_EVENT_PROGRESS_START:
     832                 :       5137 :                 progressbar_start(ev->e_progress_start.msg);
     833                 :       5137 :                 break;
     834                 :            :         case PKG_EVENT_PROGRESS_TICK:
     835                 :      17684 :                 progressbar_tick(ev->e_progress_tick.current,
     836                 :       8842 :                     ev->e_progress_tick.total);
     837                 :       8842 :                 break;
     838                 :            :         case PKG_EVENT_BACKUP:
     839                 :          0 :                 fprintf(msg_buf->fp, "Backing up");
     840                 :          0 :                 break;
     841                 :            :         case PKG_EVENT_RESTORE:
     842                 :          0 :                 fprintf(msg_buf->fp, "Restoring");
     843                 :          0 :                 break;
     844                 :            :         case PKG_EVENT_NEW_ACTION:
     845                 :        906 :                 nbdone++;
     846                 :        906 :                 break;
     847                 :            :         case PKG_EVENT_MESSAGE:
     848                 :        112 :                 if (messages == NULL)
     849                 :        108 :                         messages = xstring_new();
     850                 :        112 :                 fprintf(messages->fp, "%s", ev->e_pkg_message.msg);
     851                 :        112 :                 break;
     852                 :            :         case PKG_EVENT_CLEANUP_CALLBACK_REGISTER:
     853                 :        696 :                 if (!signal_handler_installed) {
     854                 :        503 :                         kv_init(cleanup_list);
     855                 :        503 :                         signal(SIGINT, cleanup_handler);
     856                 :        503 :                         signal_handler_installed = true;
     857                 :        503 :                 }
     858                 :        696 :                 evtmp = malloc(sizeof(struct cleanup));
     859                 :        696 :                 evtmp->cb = ev->e_cleanup_callback.cleanup_cb;
     860                 :        696 :                 evtmp->data = ev->e_cleanup_callback.data;
     861         [ -  + ]:        696 :                 kv_push(struct cleanup *, cleanup_list, evtmp);
     862                 :        696 :                 break;
     863                 :            :         case PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER:
     864         [ +  + ]:        868 :                 if (!signal_handler_installed)
     865                 :        172 :                         break;
     866                 :        696 :                 for (i = 0; i < kv_size(cleanup_list); i++) {
     867                 :        696 :                         evtmp = kv_A(cleanup_list, i);
     868                 :        696 :                         if (evtmp->cb == ev->e_cleanup_callback.cleanup_cb &&
     869                 :        696 :                             evtmp->data == ev->e_cleanup_callback.data) {
     870                 :        696 :                                 kv_del(struct cleanup *, cleanup_list, i);
     871                 :        696 :                                 break;
     872                 :            :                         }
     873                 :          0 :                 }
     874                 :        696 :                 break;
     875                 :            :         case PKG_EVENT_CONFLICTS:
     876                 :         60 :                 if (conflicts == NULL) {
     877                 :         36 :                         conflicts = xstring_new();
     878                 :         36 :                 }
     879                 :        128 :                 pkg_fprintf(conflicts->fp, "  - %n-%v",
     880                 :         64 :                     ev->e_conflicts.p1, ev->e_conflicts.p1);
     881                 :         64 :                 if (pkg_repos_total_count() > 1) {
     882                 :          8 :                         pkg_get(ev->e_conflicts.p1, PKG_REPONAME, &reponame);
     883                 :         16 :                         fprintf(conflicts->fp, " [%s]",
     884         [ -  + ]:          8 :                             reponame == NULL ? "installed" : reponame);
     885                 :          8 :                 }
     886                 :         16 :                 pkg_fprintf(conflicts->fp, " conflicts with %n-%v",
     887                 :          8 :                     ev->e_conflicts.p2, ev->e_conflicts.p2);
     888                 :          8 :                 if (pkg_repos_total_count() > 1) {
     889                 :          8 :                         pkg_get(ev->e_conflicts.p2, PKG_REPONAME, &reponame);
     890                 :         16 :                         fprintf(conflicts->fp, " [%s]",
     891         [ +  + ]:          8 :                             reponame == NULL ? "installed" : reponame);
     892                 :          8 :                 }
     893                 :        120 :                 fprintf(conflicts->fp, " on %s\n",
     894                 :         60 :                     ev->e_conflicts.path);
     895                 :         60 :                 break;
     896                 :            :         case PKG_EVENT_TRIGGER:
     897                 :          0 :                 if (!quiet) {
     898         [ #  # ]:          0 :                         if (ev->e_trigger.cleanup)
     899                 :          0 :                                 printf("==> Cleaning up trigger: %s\n", ev->e_trigger.name);
     900                 :            :                         else
     901                 :          0 :                                 printf("==> Running trigger: %s\n", ev->e_trigger.name);
     902                 :          0 :                 }
     903                 :            :         default:
     904                 :       2118 :                 break;
     905                 :            :         }
     906                 :            : 
     907                 :      25654 :         return 0;
     908                 :      25918 : }

Generated by: LCOV version 1.15