LCOV - code coverage report
Current view: top level - libpkg - pkg.c (source / functions) Hit Total Coverage
Test: rapport Lines: 663 1087 61.0 %
Date: 2021-12-10 16:22:55 Functions: 56 74 75.7 %
Branches: 424 981 43.2 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2016 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
       5                 :            :  * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
       6                 :            :  * Copyright (c) 2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       7                 :            :  * All rights reserved.
       8                 :            :  *
       9                 :            :  * Redistribution and use in source and binary forms, with or without
      10                 :            :  * modification, are permitted provided that the following conditions
      11                 :            :  * are met:
      12                 :            :  * 1. Redistributions of source code must retain the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer
      14                 :            :  *    in this position and unchanged.
      15                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      16                 :            :  *    notice, this list of conditions and the following disclaimer in the
      17                 :            :  *    documentation and/or other materials provided with the distribution.
      18                 :            :  *
      19                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      20                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      21                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      22                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      23                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      24                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      25                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      26                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      27                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      28                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29                 :            :  */
      30                 :            : 
      31                 :            : #include <archive.h>
      32                 :            : #include <archive_entry.h>
      33                 :            : #include <assert.h>
      34                 :            : #include <errno.h>
      35                 :            : #include <fcntl.h>
      36                 :            : #include <string.h>
      37                 :            : 
      38                 :            : #include "pkg.h"
      39                 :            : #include "private/event.h"
      40                 :            : #include "private/pkg.h"
      41                 :            : #include "private/pkgdb.h"
      42                 :            : #include "private/utils.h"
      43                 :            : 
      44                 :            : int
      45                 :       6949 : pkg_new(struct pkg **pkg, pkg_t type)
      46                 :            : {
      47                 :       6949 :         *pkg = xcalloc(1, sizeof(struct pkg));
      48                 :       6949 :         (*pkg)->type = type;
      49                 :       6949 :         (*pkg)->rootfd = -1;
      50                 :            : 
      51                 :       6949 :         return (EPKG_OK);
      52                 :            : }
      53                 :            : 
      54                 :            : static void
      55                 :        544 : pkg_message_free(struct pkg_message *m)
      56                 :            : {
      57                 :        544 :         free(m->str);
      58                 :        544 :         free(m->maximum_version);
      59                 :        544 :         free(m->minimum_version);
      60                 :        544 :         free(m);
      61                 :        544 : }
      62                 :            : 
      63                 :            : void
      64                 :      10576 : pkg_free(struct pkg *pkg)
      65                 :            : {
      66         [ +  + ]:      10576 :         if (pkg == NULL)
      67                 :       4295 :                 return;
      68                 :            : 
      69                 :       6281 :         free(pkg->name);
      70                 :       6281 :         free(pkg->origin);
      71                 :       6281 :         free(pkg->old_version);
      72                 :       6281 :         free(pkg->version);
      73                 :       6281 :         free(pkg->maintainer);
      74                 :       6281 :         free(pkg->www);
      75                 :       6281 :         free(pkg->arch);
      76                 :       6281 :         free(pkg->abi);
      77                 :       6281 :         free(pkg->uid);
      78                 :       6281 :         free(pkg->digest);
      79                 :       6281 :         free(pkg->old_digest);
      80                 :       6281 :         free(pkg->prefix);
      81                 :       6281 :         free(pkg->comment);
      82                 :       6281 :         free(pkg->desc);
      83                 :       6281 :         free(pkg->sum);
      84                 :       6281 :         free(pkg->repopath);
      85                 :       6281 :         free(pkg->repourl);
      86                 :       6281 :         free(pkg->reason);
      87                 :       6281 :         free(pkg->dep_formula);
      88                 :            : 
      89         [ +  + ]:      62810 :         for (int i = 0; i < PKG_NUM_SCRIPTS; i++)
      90                 :      56529 :                 xstring_free(pkg->scripts[i]);
      91                 :            : 
      92                 :       6281 :         pkg_list_free(pkg, PKG_DEPS);
      93                 :       6281 :         pkg_list_free(pkg, PKG_RDEPS);
      94                 :       6281 :         pkg_list_free(pkg, PKG_FILES);
      95                 :       6281 :         pkg_list_free(pkg, PKG_DIRS);
      96                 :       6281 :         pkg_list_free(pkg, PKG_OPTIONS);
      97                 :       6281 :         pkg_list_free(pkg, PKG_USERS);
      98                 :       6281 :         pkg_list_free(pkg, PKG_GROUPS);
      99                 :       6281 :         pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);
     100                 :       6281 :         pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);
     101                 :       6281 :         pkg_list_free(pkg, PKG_PROVIDES);
     102                 :       6281 :         pkg_list_free(pkg, PKG_REQUIRES);
     103                 :       6281 :         pkg_list_free(pkg, PKG_CATEGORIES);
     104                 :       6281 :         pkg_list_free(pkg, PKG_LICENSES);
     105                 :            : 
     106   [ +  +  +  +  :       6825 :         DL_FREE(pkg->message, pkg_message_free);
          +  -  +  +  -  
                +  #  # ]
     107   [ +  +  +  +  :      10979 :         DL_FREE(pkg->annotations, pkg_kv_free);
          +  -  +  +  -  
                +  #  # ]
     108                 :            : 
     109         [ +  + ]:       6281 :         if (pkg->rootfd != -1)
     110                 :       1019 :                 close(pkg->rootfd);
     111                 :            : 
     112                 :       6281 :         free(pkg);
     113                 :      10576 : }
     114                 :            : 
     115                 :            : pkg_t
     116                 :        239 : pkg_type(const struct pkg * restrict pkg)
     117                 :            : {
     118         [ +  - ]:        239 :         assert(pkg != NULL);
     119                 :            : 
     120                 :        239 :         return (pkg->type);
     121                 :            : }
     122                 :            : 
     123                 :            : int
     124                 :       3169 : pkg_is_valid(const struct pkg * restrict pkg)
     125                 :            : {
     126         [ +  - ]:       3169 :         if (pkg == NULL) {
     127                 :          0 :                 pkg_emit_error("Invalid package: not allocated");
     128                 :          0 :                 return (EPKG_FATAL);
     129                 :            :         }
     130                 :            : 
     131         [ +  + ]:       3169 :         if (pkg->origin == NULL) {
     132                 :         39 :                 pkg_emit_error("Invalid package: object has missing property origin");
     133                 :         39 :                 return (EPKG_FATAL);
     134                 :            :         }
     135                 :            : 
     136         [ +  + ]:       3130 :         if (pkg->name == NULL) {
     137                 :         39 :                 pkg_emit_error("Invalid package: object has missing property name");
     138                 :         39 :                 return (EPKG_FATAL);
     139                 :            :         }
     140                 :            : 
     141         [ +  + ]:       3091 :         if (pkg->comment == NULL) {
     142                 :         39 :                 pkg_emit_error("Invalid package: object has missing property comment");
     143                 :         39 :                 return (EPKG_FATAL);
     144                 :            :         }
     145                 :            : 
     146         [ +  + ]:       3052 :         if (pkg->version == NULL) {
     147                 :         39 :                 pkg_emit_error("Invalid package: object has missing property version");
     148                 :         39 :                 return (EPKG_FATAL);
     149                 :            :         }
     150                 :            : 
     151         [ +  + ]:       3013 :         if (pkg->desc == NULL) {
     152                 :         39 :                 pkg_emit_error("Invalid package: object has missing property desc");
     153                 :         39 :                 return (EPKG_FATAL);
     154                 :            :         }
     155                 :            : 
     156         [ +  + ]:       2974 :         if (pkg->maintainer == NULL) {
     157                 :         39 :                 pkg_emit_error("Invalid package: object has missing property maintainer");
     158                 :         39 :                 return (EPKG_FATAL);
     159                 :            :         }
     160                 :            : 
     161         [ +  + ]:       2935 :         if (pkg->www == NULL) {
     162                 :         39 :                 pkg_emit_error("Invalid package: object has missing property www");
     163                 :         39 :                 return (EPKG_FATAL);
     164                 :            :         }
     165                 :            : 
     166         [ +  + ]:       2896 :         if (pkg->prefix == NULL) {
     167                 :         39 :                 pkg_emit_error("Invalid package: object has missing property prefix");
     168                 :         39 :                 return (EPKG_FATAL);
     169                 :            :         }
     170                 :            : 
     171                 :       2857 :         return (EPKG_OK);
     172                 :       3169 : }
     173                 :            : 
     174                 :            : static int
     175                 :       1859 : pkg_vget(const struct pkg * restrict pkg, va_list ap)
     176                 :            : {
     177                 :            :         int attr;
     178                 :            : 
     179   [ +  +  +  + ]:       5459 :         while ((attr = va_arg(ap, int)) > 0) {
     180                 :            : 
     181   [ +  -  -  + ]:       3600 :                 if (attr >= PKG_NUM_FIELDS || attr <= 0) {
     182                 :          0 :                         pkg_emit_error("Bad argument on pkg_get %d", attr);
     183                 :          0 :                         return (EPKG_FATAL);
     184                 :            :                 }
     185                 :            : 
     186   [ -  -  +  +  :       3600 :                 switch (attr) {
          -  -  -  -  -  
          -  -  -  -  +  
          +  -  +  +  -  
          +  +  +  +  -  
          +  -  -  -  +  
             -  -  -  + ]
     187                 :            :                 case PKG_ORIGIN:
     188         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->origin;
     189                 :          0 :                         break;
     190                 :            :                 case PKG_NAME:
     191         [ +  - ]:          4 :                         *va_arg(ap, const char **) = pkg->name;
     192                 :          4 :                         break;
     193                 :            :                 case PKG_VERSION:
     194         [ +  - ]:        288 :                         *va_arg(ap, const char **) = pkg->version;
     195                 :        288 :                         break;
     196                 :            :                 case PKG_COMMENT:
     197         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->comment;
     198                 :          0 :                         break;
     199                 :            :                 case PKG_DESC:
     200         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->desc;
     201                 :          0 :                         break;
     202                 :            :                 case PKG_MTREE:
     203         [ #  # ]:          0 :                         *va_arg(ap, const char **) = NULL;
     204                 :          0 :                         break;
     205                 :            :                 case PKG_MESSAGE:
     206   [ #  #  #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->message ? pkg->message->str : NULL;
     207                 :          0 :                         break;
     208                 :            :                 case PKG_ARCH:
     209         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->arch;
     210                 :          0 :                         break;
     211                 :            :                 case PKG_ABI:
     212         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->abi;
     213                 :          0 :                         break;
     214                 :            :                 case PKG_WWW:
     215         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->www;
     216                 :          0 :                         break;
     217                 :            :                 case PKG_MAINTAINER:
     218         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->maintainer;
     219                 :          0 :                         break;
     220                 :            :                 case PKG_PREFIX:
     221         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->prefix;
     222                 :          0 :                         break;
     223                 :            :                 case PKG_REPOPATH:
     224         [ -  + ]:        521 :                         *va_arg(ap, const char **) = pkg->repopath;
     225                 :        521 :                         break;
     226                 :            :                 case PKG_CKSUM:
     227         [ +  - ]:          8 :                         *va_arg(ap, const char **) = pkg->sum;
     228                 :          8 :                         break;
     229                 :            :                 case PKG_OLD_VERSION:
     230         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->old_version;
     231                 :          0 :                         break;
     232                 :            :                 case PKG_REPONAME:
     233         [ +  - ]:         16 :                         *va_arg(ap, const char **) = pkg->reponame;
     234                 :         16 :                         break;
     235                 :            :                 case PKG_REPOURL:
     236         [ +  - ]:        181 :                         *va_arg(ap, const char **) = pkg->repourl;
     237                 :        181 :                         break;
     238                 :            :                 case PKG_DIGEST:
     239         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->digest;
     240                 :          0 :                         break;
     241                 :            :                 case PKG_REASON:
     242         [ +  - ]:        210 :                         *va_arg(ap, const char **) = pkg->reason;
     243                 :        210 :                         break;
     244                 :            :                 case PKG_FLATSIZE:
     245         [ +  - ]:        858 :                         *va_arg(ap, int64_t *) = pkg->flatsize;
     246                 :        858 :                         break;
     247                 :            :                 case PKG_OLD_FLATSIZE:
     248         [ -  + ]:        181 :                         *va_arg(ap, int64_t *) = pkg->old_flatsize;
     249                 :        181 :                         break;
     250                 :            :                 case PKG_PKGSIZE:
     251         [ +  + ]:       1223 :                         *va_arg(ap, int64_t *) = pkg->pkgsize;
     252                 :       1223 :                         break;
     253                 :            :                 case PKG_LICENSE_LOGIC:
     254         [ #  # ]:          0 :                         *va_arg(ap, lic_t *) = pkg->licenselogic;
     255                 :          0 :                         break;
     256                 :            :                 case PKG_AUTOMATIC:
     257         [ +  - ]:         46 :                         *va_arg(ap, bool *) = pkg->automatic;
     258                 :         46 :                         break;
     259                 :            :                 case PKG_LOCKED:
     260         [ #  # ]:          0 :                         *va_arg(ap, bool *) = pkg->locked;
     261                 :          0 :                         break;
     262                 :            :                 case PKG_ROWID:
     263         [ #  # ]:          0 :                         *va_arg(ap, int64_t *) = pkg->id;
     264                 :          0 :                         break;
     265                 :            :                 case PKG_TIME:
     266         [ #  # ]:          0 :                         *va_arg(ap, int64_t *) = pkg->timestamp;
     267                 :          0 :                         break;
     268                 :            :                 case PKG_ANNOTATIONS:
     269         [ +  - ]:         40 :                         *va_arg(ap, const struct pkg_kv **) = pkg->annotations;
     270                 :         40 :                         break;
     271                 :            :                 case PKG_UNIQUEID:
     272         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->uid;
     273                 :          0 :                         break;
     274                 :            :                 case PKG_OLD_DIGEST:
     275         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->old_digest;
     276                 :          0 :                         break;
     277                 :            :                 case PKG_DEP_FORMULA:
     278         [ #  # ]:          0 :                         *va_arg(ap, const char **) = pkg->dep_formula;
     279                 :          0 :                         break;
     280                 :            :                 case PKG_VITAL:
     281         [ +  - ]:         24 :                         *va_arg(ap, bool *) = pkg->vital;
     282                 :         24 :                         break;
     283                 :            :                 }
     284                 :            :         }
     285                 :            : 
     286                 :       1859 :         return (EPKG_OK);
     287                 :       1859 : }
     288                 :            : 
     289                 :            : int
     290                 :       1859 : pkg_get2(const struct pkg * restrict pkg, ...)
     291                 :            : {
     292                 :       1859 :         int ret = EPKG_OK;
     293                 :            :         va_list ap;
     294                 :            : 
     295         [ +  - ]:       1859 :         assert(pkg != NULL);
     296                 :            : 
     297                 :       1859 :         va_start(ap, pkg);
     298                 :       1859 :         ret = pkg_vget(pkg, ap);
     299                 :       1859 :         va_end(ap);
     300                 :            : 
     301                 :       1859 :         return (ret);
     302                 :            : }
     303                 :            : 
     304                 :            : static int
     305                 :        388 : pkg_vset(struct pkg *pkg, va_list ap)
     306                 :            : {
     307                 :            :         int attr;
     308                 :            :         const char *buf;
     309                 :            :         ucl_object_t *obj;
     310                 :            :         struct pkg_message *msg;
     311                 :            : 
     312   [ +  -  +  + ]:        776 :         while ((attr = va_arg(ap, int)) > 0) {
     313   [ +  -  -  + ]:        388 :                 if (attr >= PKG_NUM_FIELDS || attr <= 0) {
     314                 :          0 :                         pkg_emit_error("Bad argument on pkg_set %d", attr);
     315                 :          0 :                         return (EPKG_FATAL);
     316                 :            :                 }
     317                 :            : 
     318   [ -  +  +  +  :        388 :                 switch (attr) {
          +  +  -  -  -  
          -  +  +  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
                      - ]
     319                 :            :                 case PKG_NAME:
     320                 :         39 :                         free(pkg->name);
     321         [ +  - ]:         39 :                         pkg->name = xstrdup(va_arg(ap, const char *));
     322                 :         39 :                         free(pkg->uid);
     323                 :         39 :                         pkg->uid = xstrdup(pkg->name);
     324                 :         39 :                         break;
     325                 :            :                 case PKG_ORIGIN:
     326                 :         39 :                         free(pkg->origin);
     327         [ +  - ]:         39 :                         pkg->origin = xstrdup(va_arg(ap, const char *));
     328                 :         39 :                         break;
     329                 :            :                 case PKG_VERSION:
     330                 :         39 :                         free(pkg->version);
     331         [ +  - ]:         39 :                         pkg->version = xstrdup(va_arg(ap, const char *));
     332                 :         39 :                         break;
     333                 :            :                 case PKG_COMMENT:
     334                 :         39 :                         free(pkg->comment);
     335         [ +  - ]:         39 :                         pkg->comment = xstrdup(va_arg(ap, const char *));
     336                 :         39 :                         break;
     337                 :            :                 case PKG_DESC:
     338                 :         39 :                         free(pkg->desc);
     339         [ +  - ]:         39 :                         pkg->desc = xstrdup(va_arg(ap, const char *));
     340                 :         39 :                         break;
     341                 :            :                 case PKG_MTREE:
     342         [ #  # ]:          0 :                         (void)va_arg(ap, const char *);
     343                 :          0 :                         break;
     344                 :            :                 case PKG_MESSAGE:
     345         [ #  # ]:          0 :                         LL_FOREACH(pkg->message, msg) {
     346                 :          0 :                                 pkg_message_free(msg);
     347                 :          0 :                         }
     348         [ #  # ]:          0 :                         buf = va_arg(ap, const char *);
     349         [ #  # ]:          0 :                         if (*buf == '[') {
     350                 :          0 :                                 pkg_message_from_str(pkg, buf, strlen(buf));
     351                 :          0 :                         } else {
     352                 :          0 :                                 obj = ucl_object_fromstring_common(buf, strlen(buf),
     353                 :            :                                     UCL_STRING_RAW|UCL_STRING_TRIM);
     354                 :          0 :                                 pkg_message_from_ucl(pkg, obj);
     355                 :          0 :                                 ucl_object_unref(obj);
     356                 :            :                         }
     357                 :          0 :                         break;
     358                 :            :                 case PKG_ARCH:
     359                 :          0 :                         free(pkg->arch);
     360         [ #  # ]:          0 :                         pkg->arch = xstrdup(va_arg(ap, const char *));
     361                 :          0 :                         break;
     362                 :            :                 case PKG_ABI:
     363                 :          0 :                         free(pkg->abi);
     364         [ #  # ]:          0 :                         pkg->abi = xstrdup(va_arg(ap, const char *));
     365                 :          0 :                         break;
     366                 :            :                 case PKG_MAINTAINER:
     367                 :         39 :                         free(pkg->maintainer);
     368         [ +  - ]:         39 :                         pkg->maintainer = xstrdup(va_arg(ap, const char *));
     369                 :         39 :                         break;
     370                 :            :                 case PKG_WWW:
     371                 :         39 :                         free(pkg->www);
     372         [ +  - ]:         39 :                         pkg->www = xstrdup(va_arg(ap, const char *));
     373                 :         39 :                         break;
     374                 :            :                 case PKG_PREFIX:
     375                 :         76 :                         free(pkg->prefix);
     376         [ +  - ]:         76 :                         pkg->prefix = xstrdup(va_arg(ap, const char *));
     377                 :         76 :                         break;
     378                 :            :                 case PKG_REPOPATH:
     379                 :          0 :                         free(pkg->repopath);
     380         [ #  # ]:          0 :                         pkg->repopath = xstrdup(va_arg(ap, const char *));
     381                 :          0 :                         break;
     382                 :            :                 case PKG_CKSUM:
     383                 :          0 :                         free(pkg->sum);
     384         [ #  # ]:          0 :                         pkg->sum = xstrdup(va_arg(ap, const char *));
     385                 :          0 :                         break;
     386                 :            :                 case PKG_OLD_VERSION:
     387                 :          0 :                         free(pkg->old_version);
     388         [ #  # ]:          0 :                         pkg->old_version = xstrdup(va_arg(ap, const char *));
     389                 :          0 :                         break;
     390                 :            :                 case PKG_REPONAME:
     391                 :          0 :                         free(pkg->reponame);
     392         [ #  # ]:          0 :                         pkg->reponame = xstrdup(va_arg(ap, const char *));
     393                 :          0 :                         break;
     394                 :            :                 case PKG_REPOURL:
     395                 :          0 :                         free(pkg->repourl);
     396         [ #  # ]:          0 :                         pkg->repourl = xstrdup(va_arg(ap, const char *));
     397                 :          0 :                         break;
     398                 :            :                 case PKG_DIGEST:
     399                 :          0 :                         free(pkg->digest);
     400         [ #  # ]:          0 :                         pkg->digest = xstrdup(va_arg(ap, const char *));
     401                 :          0 :                         break;
     402                 :            :                 case PKG_REASON:
     403                 :          0 :                         free(pkg->reason);
     404         [ #  # ]:          0 :                         pkg->reason = xstrdup(va_arg(ap, const char *));
     405                 :          0 :                         break;
     406                 :            :                 case PKG_FLATSIZE:
     407         [ #  # ]:          0 :                         pkg->flatsize = va_arg(ap, int64_t);
     408                 :          0 :                         break;
     409                 :            :                 case PKG_OLD_FLATSIZE:
     410         [ #  # ]:          0 :                         pkg->old_flatsize = va_arg(ap, int64_t);
     411                 :          0 :                         break;
     412                 :            :                 case PKG_PKGSIZE:
     413         [ #  # ]:          0 :                         pkg->pkgsize = va_arg(ap, int64_t);
     414                 :          0 :                         break;
     415                 :            :                 case PKG_LICENSE_LOGIC:
     416         [ #  # ]:          0 :                         pkg->licenselogic = (lic_t)va_arg(ap, int);
     417                 :          0 :                         break;
     418                 :            :                 case PKG_AUTOMATIC:
     419         [ +  - ]:         39 :                         pkg->automatic = (bool)va_arg(ap, int);
     420                 :         39 :                         break;
     421                 :            :                 case PKG_ROWID:
     422         [ #  # ]:          0 :                         pkg->id = va_arg(ap, int64_t);
     423                 :          0 :                         break;
     424                 :            :                 case PKG_LOCKED:
     425         [ #  # ]:          0 :                         pkg->locked = (bool)va_arg(ap, int);
     426                 :          0 :                         break;
     427                 :            :                 case PKG_TIME:
     428         [ #  # ]:          0 :                         pkg->timestamp = va_arg(ap, int64_t);
     429                 :          0 :                         break;
     430                 :            :                 case PKG_DEP_FORMULA:
     431                 :          0 :                         free(pkg->dep_formula);
     432         [ #  # ]:          0 :                         pkg->dep_formula = xstrdup(va_arg(ap, const char *));
     433                 :          0 :                         break;
     434                 :            :                 case PKG_VITAL:
     435         [ #  # ]:          0 :                         pkg->vital = (bool)va_arg(ap, int);
     436                 :          0 :                         break;
     437                 :            :                 }
     438                 :            :         }
     439                 :            : 
     440                 :        388 :         return (EPKG_OK);
     441                 :        388 : }
     442                 :            : 
     443                 :            : int
     444                 :        388 : pkg_set2(struct pkg *pkg, ...)
     445                 :            : {
     446                 :        388 :         int ret = EPKG_OK;
     447                 :            :         va_list ap;
     448                 :            : 
     449         [ +  - ]:        388 :         assert(pkg != NULL);
     450                 :            : 
     451                 :        388 :         va_start(ap, pkg);
     452                 :        388 :         ret = pkg_vset(pkg, ap);
     453                 :        388 :         va_end(ap);
     454                 :            : 
     455                 :        388 :         return (ret);
     456                 :            : }
     457                 :            : 
     458                 :            : int
     459                 :          0 : pkg_set_from_fileat(int fd, struct pkg *pkg, pkg_attr attr, const char *path,
     460                 :            :     bool trimcr)
     461                 :            : {
     462                 :          0 :         char *buf = NULL;
     463                 :            :         char *cp;
     464                 :          0 :         off_t size = 0;
     465                 :          0 :         int ret = EPKG_OK;
     466                 :            : 
     467         [ #  # ]:          0 :         assert(pkg != NULL);
     468         [ #  # ]:          0 :         assert(path != NULL);
     469                 :            : 
     470         [ #  # ]:          0 :         if ((ret = file_to_bufferat(fd, path, &buf, &size)) !=  EPKG_OK)
     471                 :          0 :                 return (ret);
     472                 :            : 
     473         [ #  # ]:          0 :         if (trimcr) {
     474                 :          0 :                 cp = buf + strlen(buf) - 1;
     475   [ #  #  #  # ]:          0 :                 while (cp > buf && *cp == '\n') {
     476                 :          0 :                         *cp = 0;
     477                 :          0 :                         cp--;
     478                 :            :                 }
     479                 :          0 :         }
     480                 :            : 
     481                 :          0 :         ret = pkg_set(pkg, attr, buf);
     482                 :            : 
     483                 :          0 :         free(buf);
     484                 :            : 
     485                 :          0 :         return (ret);
     486                 :          0 : }
     487                 :            : 
     488                 :            : #define pkg_each(name, type, field)             \
     489                 :            : int                                             \
     490                 :            : pkg_##name(const struct pkg *p, type **t) {     \
     491                 :            :         assert(p != NULL);                      \
     492                 :            :         if ((*t) == NULL)                       \
     493                 :            :                 (*t) = p->field;             \
     494                 :            :         else                                    \
     495                 :            :                 (*t) = (*t)->next;           \
     496                 :            :         if ((*t) == NULL)                       \
     497                 :            :                 return (EPKG_END);              \
     498                 :            :         return (EPKG_OK);                       \
     499                 :            : }
     500                 :            : 
     501   [ +  -  +  +  :       4328 : pkg_each(dirs, struct pkg_dir, dirs);
                   +  + ]
     502   [ +  -  +  +  :      14258 : pkg_each(files, struct pkg_file, files);
                   +  + ]
     503   [ +  -  +  +  :       8405 : pkg_each(deps, struct pkg_dep, depends);
                   +  + ]
     504   [ +  -  +  +  :       2031 : pkg_each(rdeps, struct pkg_dep, rdepends);
                   +  + ]
     505   [ +  -  +  +  :       5408 : pkg_each(options, struct pkg_option, options);
                   +  + ]
     506   [ +  -  +  +  :       3977 : pkg_each(conflicts, struct pkg_conflict, conflicts);
                   +  + ]
     507   [ +  -  +  +  :       2947 : pkg_each(config_files, struct pkg_config_file, config_files);
                   +  + ]
     508                 :            : 
     509                 :            : #define pkg_each_string_hash(name)                   \
     510                 :            : int                                                  \
     511                 :            : pkg_##name(const struct pkg *pkg, char **c) {        \
     512                 :            :         if ((*c) == NULL)                            \
     513                 :            :                 pkghash_loopinit(pkg->name);         \
     514                 :            :         pkghash_entry *e = pkghash_inext(pkg->name); \
     515                 :            :         if (e == NULL) {                             \
     516                 :            :                 (*c) = NULL;                         \
     517                 :            :                 return (EPKG_END);                   \
     518                 :            :         }                                            \
     519                 :            :         (*c) = e->key;                               \
     520                 :            :         return (EPKG_OK);                            \
     521                 :            : }
     522                 :            : 
     523   [ #  #  #  # ]:          0 : pkg_each_string_hash(categories);
     524   [ #  #  #  # ]:          0 : pkg_each_string_hash(licenses);
     525   [ #  #  #  # ]:          0 : pkg_each_string_hash(requires);
     526   [ #  #  #  # ]:          0 : pkg_each_string_hash(provides);
     527   [ #  #  #  # ]:          0 : pkg_each_string_hash(shlibs_required);
     528   [ #  #  #  # ]:          0 : pkg_each_string_hash(shlibs_provided);
     529   [ #  #  #  # ]:          0 : pkg_each_string_hash(users);
     530   [ #  #  #  # ]:          0 : pkg_each_string_hash(groups);
     531                 :            : 
     532                 :            : int
     533                 :          0 : pkg_adduser(struct pkg *pkg, const char *name)
     534                 :            : {
     535         [ #  # ]:          0 :         assert(pkg != NULL);
     536         [ #  # ]:          0 :         assert(name != NULL && name[0] != '\0');
     537                 :            : 
     538         [ #  # ]:          0 :         if (pkghash_get(pkg->users, name) != NULL) {
     539         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     540                 :          0 :                         pkg_emit_error("duplicate user listing: %s, fatal (developer mode)", name);
     541                 :          0 :                         return (EPKG_FATAL);
     542                 :            :                 } else {
     543                 :          0 :                         pkg_emit_error("duplicate user listing: %s, ignoring", name);
     544                 :          0 :                         return (EPKG_OK);
     545                 :            :                 }
     546                 :            :         }
     547                 :            : 
     548   [ #  #  #  # ]:          0 :         pkghash_safe_add(pkg->users, name, NULL, NULL);
     549                 :            : 
     550                 :          0 :         return (EPKG_OK);
     551                 :          0 : }
     552                 :            : 
     553                 :            : int
     554                 :          0 : pkg_addgroup(struct pkg *pkg, const char *name)
     555                 :            : {
     556         [ #  # ]:          0 :         assert(pkg != NULL);
     557         [ #  # ]:          0 :         assert(name != NULL && name[0] != '\0');
     558                 :            : 
     559         [ #  # ]:          0 :         if (pkghash_get(pkg->groups, name) != NULL) {
     560         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     561                 :          0 :                         pkg_emit_error("duplicate group listing: %s, fatal (developer mode)", name);
     562                 :          0 :                         return (EPKG_FATAL);
     563                 :            :                 } else {
     564                 :          0 :                         pkg_emit_error("duplicate group listing: %s, ignoring", name);
     565                 :          0 :                         return (EPKG_OK);
     566                 :            :                 }
     567                 :            :         }
     568                 :            : 
     569   [ #  #  #  # ]:          0 :         pkghash_safe_add(pkg->groups, name, NULL, NULL);
     570                 :            : 
     571                 :          0 :         return (EPKG_OK);
     572                 :          0 : }
     573                 :            : 
     574                 :            : int
     575                 :       1723 : pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *version, bool locked)
     576                 :            : {
     577         [ -  + ]:       1723 :         if (pkg_adddep_chain(NULL, pkg, name, origin, version, locked) == NULL) {
     578                 :          0 :                 return (EPKG_FATAL);
     579                 :            :         }
     580                 :            : 
     581                 :       1723 :         return (EPKG_OK);
     582                 :       1723 : }
     583                 :            : 
     584                 :            : struct pkg_dep *
     585                 :       1723 : pkg_adddep_chain(struct pkg_dep *chain,
     586                 :            :                 struct pkg *pkg,
     587                 :            :                 const char *name,
     588                 :            :                 const char *origin,
     589                 :            :                 const char *version, bool locked)
     590                 :            : {
     591                 :       1723 :         struct pkg_dep *d = NULL;
     592                 :            : 
     593         [ +  - ]:       1723 :         assert(pkg != NULL);
     594         [ +  - ]:       1723 :         assert(name != NULL && name[0] != '\0');
     595         [ +  - ]:       1723 :         assert(origin != NULL && origin[0] != '\0');
     596                 :            : 
     597                 :       1723 :         pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s", origin, name);
     598         [ -  + ]:       1723 :         if (pkghash_get(pkg->depshash, name) != NULL) {
     599                 :          0 :                 pkg_emit_error("%s: duplicate dependency listing: %s",
     600                 :          0 :                     pkg->name, name);
     601                 :          0 :                 return (NULL);
     602                 :            :         }
     603                 :            : 
     604                 :       1723 :         d = xcalloc(1, sizeof(*d));
     605                 :       1723 :         d->origin = xstrdup(origin);
     606                 :       1723 :         d->name = xstrdup(name);
     607   [ +  +  +  - ]:       1723 :         if (version != NULL && version[0] != '\0')
     608                 :       1393 :                 d->version = xstrdup(version);
     609                 :       1723 :         d->uid = xstrdup(name);
     610                 :       1723 :         d->locked = locked;
     611                 :            : 
     612   [ +  +  -  + ]:       2045 :         pkghash_safe_add(pkg->depshash, d->name, d, NULL);
     613         [ -  + ]:       1723 :         if (chain == NULL) {
     614         [ +  + ]:       1723 :                 DL_APPEND(pkg->depends, d);
     615                 :       1723 :                 chain = pkg->depends;
     616                 :       1723 :         }
     617                 :            :         else {
     618         [ #  # ]:          0 :                 DL_APPEND2(chain, d, alt_prev, alt_next);
     619                 :            :         }
     620                 :            : 
     621                 :       1723 :         return (chain);
     622                 :       1723 : }
     623                 :            : 
     624                 :            : int
     625                 :        132 : pkg_addrdep(struct pkg *pkg, const char *name, const char *origin, const char *version, bool locked)
     626                 :            : {
     627                 :            :         struct pkg_dep *d;
     628                 :            : 
     629         [ +  - ]:        132 :         assert(pkg != NULL);
     630         [ +  - ]:        132 :         assert(name != NULL && name[0] != '\0');
     631         [ +  - ]:        132 :         assert(origin != NULL && origin[0] != '\0');
     632                 :            : 
     633                 :        132 :         pkg_debug(3, "Pkg: add a new reverse dependency origin: %s, name: %s", origin, name);
     634                 :            : 
     635                 :        132 :         d = xcalloc(1, sizeof(*d));
     636                 :        132 :         d->origin = xstrdup(origin);
     637                 :        132 :         d->name = xstrdup(name);
     638   [ +  -  -  + ]:        132 :         if (version != NULL && version[0] != '\0')
     639                 :        132 :                 d->version = xstrdup(version);
     640                 :        132 :         d->uid = xstrdup(name);
     641                 :        132 :         d->locked = locked;
     642                 :            : 
     643   [ +  +  -  + ]:        156 :         pkghash_safe_add(pkg->rdepshash, d->name, d, NULL);
     644                 :        132 :         LL_PREPEND(pkg->rdepends, d);
     645                 :            : 
     646                 :        132 :         return (EPKG_OK);
     647                 :            : }
     648                 :            : 
     649                 :            : int
     650                 :       2879 : pkg_addfile(struct pkg *pkg, const char *path, const char *sum, bool check_duplicates)
     651                 :            : {
     652                 :       2879 :         return (pkg_addfile_attr(pkg, path, sum, NULL, NULL, 0, 0, check_duplicates));
     653                 :            : }
     654                 :            : 
     655                 :            : int
     656                 :       3149 : pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum,
     657                 :            :     const char *uname, const char *gname, mode_t perm, u_long fflags,
     658                 :            :     bool check_duplicates)
     659                 :            : {
     660                 :       3149 :         struct pkg_file *f = NULL;
     661                 :            :         char abspath[MAXPATHLEN];
     662                 :            : 
     663         [ +  - ]:       3149 :         assert(pkg != NULL);
     664         [ +  - ]:       3149 :         assert(path != NULL && path[0] != '\0');
     665                 :            : 
     666                 :       3149 :         path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
     667                 :       3149 :         pkg_debug(3, "Pkg: add new file '%s'", path);
     668                 :            : 
     669   [ +  +  +  - ]:       3149 :         if (check_duplicates && pkghash_get(pkg->filehash, path) != NULL) {
     670         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     671                 :          0 :                         pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", path);
     672                 :          0 :                         return (EPKG_FATAL);
     673                 :            :                 } else {
     674                 :          0 :                         pkg_emit_error("duplicate file listing: %s, ignoring", path);
     675                 :          0 :                         return (EPKG_OK);
     676                 :            :                 }
     677                 :            :         }
     678                 :            : 
     679                 :       3149 :         f = xcalloc(1, sizeof(*f));
     680                 :       3149 :         strlcpy(f->path, path, sizeof(f->path));
     681                 :            : 
     682         [ +  + ]:       3149 :         if (sum != NULL)
     683                 :       2199 :                 f->sum = xstrdup(sum);
     684                 :            : 
     685         [ +  + ]:       3149 :         if (uname != NULL)
     686                 :        258 :                 strlcpy(f->uname, uname, sizeof(f->uname));
     687                 :            : 
     688         [ +  + ]:       3149 :         if (gname != NULL)
     689                 :        258 :                 strlcpy(f->gname, gname, sizeof(f->gname));
     690                 :            : 
     691         [ +  + ]:       3149 :         if (perm != 0)
     692                 :         32 :                 f->perm = perm;
     693                 :            : 
     694         [ +  + ]:       3149 :         if (fflags != 0)
     695                 :          4 :                 f->fflags = fflags;
     696                 :            : 
     697   [ +  +  +  - ]:       4350 :         pkghash_safe_add(pkg->filehash, f->path, f, NULL);
     698         [ +  + ]:       3149 :         DL_APPEND(pkg->files, f);
     699                 :            : 
     700                 :       3149 :         return (EPKG_OK);
     701                 :       3149 : }
     702                 :            : 
     703                 :            : int
     704                 :        201 : pkg_addconfig_file(struct pkg *pkg, const char *path, const char *content)
     705                 :            : {
     706                 :        201 :         struct pkg_config_file *f = NULL;
     707                 :            :         char abspath[MAXPATHLEN];
     708                 :            : 
     709                 :        201 :         path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
     710                 :        201 :         pkg_debug(3, "Pkg: add new config file '%s'", path);
     711                 :            : 
     712         [ +  + ]:        201 :         if (pkghash_get(pkg->config_files_hash, path) != NULL) {
     713                 :         16 :                 pkg_emit_error("duplicate file listing: %s", path);
     714                 :         16 :                 return (EPKG_FATAL);
     715                 :            :         }
     716                 :        185 :         f = xcalloc(1, sizeof(*f));
     717                 :        185 :         strlcpy(f->path, path, sizeof(f->path));
     718                 :            : 
     719         [ +  + ]:        185 :         if (content != NULL)
     720                 :         70 :                 f->content = xstrdup(content);
     721                 :            : 
     722   [ -  +  #  # ]:        185 :         pkghash_safe_add(pkg->config_files_hash, f->path, f, NULL);
     723         [ -  + ]:        185 :         DL_APPEND(pkg->config_files, f);
     724                 :            : 
     725                 :        185 :         return (EPKG_OK);
     726                 :        201 : }
     727                 :            : 
     728                 :            : int
     729                 :       3407 : pkg_addstring(pkghash **list, const char *val, const char *title)
     730                 :            : {
     731         [ +  - ]:       3407 :         assert(val != NULL);
     732         [ -  + ]:       3407 :         assert(title != NULL);
     733                 :            : 
     734         [ -  + ]:       3407 :         if (pkghash_get(*list, val) != NULL) {
     735         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     736                 :          0 :                         pkg_emit_error("duplicate %s listing: %s, fatal"
     737                 :          0 :                             " (developer mode)", title, val);
     738                 :          0 :                         return (EPKG_FATAL);
     739                 :            :                 } else {
     740                 :          0 :                         pkg_emit_error("duplicate %s listing: %s, "
     741                 :          0 :                             "ignoring", title, val);
     742                 :          0 :                         return (EPKG_OK);
     743                 :            :                 }
     744                 :            :         }
     745                 :            : 
     746   [ -  +  #  # ]:       3407 :         pkghash_safe_add(*list, val, NULL, NULL);
     747                 :            : 
     748                 :       3407 :         return (EPKG_OK);
     749                 :       3407 : }
     750                 :            : 
     751                 :            : int
     752                 :        152 : pkg_adddir(struct pkg *pkg, const char *path, bool check_duplicates)
     753                 :            : {
     754                 :        152 :         return(pkg_adddir_attr(pkg, path, NULL, NULL, 0, 0, check_duplicates));
     755                 :            : }
     756                 :            : 
     757                 :            : int
     758                 :        172 : pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
     759                 :            :     const char *gname, mode_t perm, u_long fflags, bool check_duplicates)
     760                 :            : {
     761                 :        172 :         struct pkg_dir *d = NULL;
     762                 :            :         char abspath[MAXPATHLEN];
     763                 :            : 
     764         [ +  - ]:        172 :         assert(pkg != NULL);
     765         [ +  - ]:        172 :         assert(path != NULL && path[0] != '\0');
     766                 :            : 
     767         [ +  - ]:        172 :         if (strcmp(path, "/") == 0) {
     768                 :          0 :                 pkg_emit_error("skipping useless directory: '%s'\n", path);
     769                 :          0 :                 return (EPKG_OK);
     770                 :            :         }
     771                 :        172 :         path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
     772                 :        172 :         pkg_debug(3, "Pkg: add new directory '%s'", path);
     773   [ +  +  +  - ]:        172 :         if (check_duplicates && pkghash_get(pkg->dirhash, path) != NULL) {
     774         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     775                 :          0 :                         pkg_emit_error("duplicate directory listing: %s, fatal (developer mode)", path);
     776                 :          0 :                         return (EPKG_FATAL);
     777                 :            :                 } else {
     778                 :          0 :                         pkg_emit_error("duplicate directory listing: %s, ignoring", path);
     779                 :          0 :                         return (EPKG_OK);
     780                 :            :                 }
     781                 :            :         }
     782                 :            : 
     783                 :        172 :         d = xcalloc(1, sizeof(*d));
     784                 :        172 :         strlcpy(d->path, path, sizeof(d->path));
     785                 :            : 
     786         [ +  + ]:        172 :         if (uname != NULL)
     787                 :         20 :                 strlcpy(d->uname, uname, sizeof(d->uname));
     788                 :            : 
     789         [ +  + ]:        172 :         if (gname != NULL)
     790                 :         20 :                 strlcpy(d->gname, gname, sizeof(d->gname));
     791                 :            : 
     792         [ +  - ]:        172 :         if (perm != 0)
     793                 :          0 :                 d->perm = perm;
     794                 :            : 
     795         [ +  - ]:        172 :         if (fflags != 0)
     796                 :          0 :                 d->fflags = fflags;
     797                 :            : 
     798   [ +  +  -  + ]:        226 :         pkghash_safe_add(pkg->dirhash, d->path, d, NULL);
     799         [ +  + ]:        172 :         DL_APPEND(pkg->dirs, d);
     800                 :            : 
     801                 :        172 :         return (EPKG_OK);
     802                 :        172 : }
     803                 :            : 
     804                 :            : int
     805                 :        699 : pkg_addscript(struct pkg *pkg, const char *data, pkg_script type)
     806                 :            : {
     807                 :            : 
     808         [ +  - ]:        699 :         assert(pkg != NULL);
     809         [ -  + ]:        699 :         xstring_renew(pkg->scripts[type]);
     810                 :        699 :         fprintf(pkg->scripts[type]->fp, "%s", data);
     811                 :            : 
     812                 :        699 :         return (EPKG_OK);
     813                 :            : }
     814                 :            : 
     815                 :            : int
     816                 :         20 : pkg_add_lua_script(struct pkg *pkg, const char *data, pkg_lua_script type)
     817                 :            : {
     818         [ +  - ]:         20 :         assert(pkg != NULL);
     819                 :            :         struct pkg_lua_script *lua;
     820                 :            : 
     821         [ -  + ]:         20 :         if (type >= PKG_LUA_UNKNOWN)
     822                 :          0 :                 return (EPKG_FATAL);
     823                 :            : 
     824                 :         20 :         lua = xcalloc(1, sizeof(*lua));
     825                 :         20 :         lua->script = xstrdup(data);
     826         [ +  + ]:         20 :         DL_APPEND(pkg->lua_scripts[type], lua);
     827                 :            : 
     828                 :         20 :         return (EPKG_OK);
     829                 :         20 : }
     830                 :            : 
     831                 :            : int
     832                 :          0 : pkg_addluascript_fileat(int fd, struct pkg *pkg, const char *filename)
     833                 :            : {
     834                 :            :         char *data;
     835                 :            :         pkg_lua_script type;
     836                 :          0 :         int ret = EPKG_OK;
     837                 :          0 :         off_t sz = 0;
     838                 :            : 
     839         [ #  # ]:          0 :         assert(pkg != NULL);
     840         [ #  # ]:          0 :         assert(filename != NULL);
     841                 :            : 
     842                 :          0 :         pkg_debug(1, "Adding script from: '%s'", filename);
     843                 :            : 
     844         [ #  # ]:          0 :         if ((ret = file_to_bufferat(fd, filename, &data, &sz)) != EPKG_OK)
     845                 :          0 :                 return (ret);
     846                 :            : 
     847         [ #  # ]:          0 :         if (strcmp(filename, "pkg-pre-install.lua") == 0) {
     848                 :          0 :                 type = PKG_LUA_PRE_INSTALL;
     849         [ #  # ]:          0 :         } else if (strcmp(filename, "pkg-post-install.lua") == 0) {
     850                 :          0 :                 type = PKG_LUA_POST_INSTALL;
     851         [ #  # ]:          0 :         } else if (strcmp(filename, "pkg-pre-deinstall") == 0) {
     852                 :          0 :                 type = PKG_LUA_PRE_DEINSTALL;
     853         [ #  # ]:          0 :         } else if (strcmp(filename, "pkg-post-deinstall") == 0) {
     854                 :          0 :                 type = PKG_LUA_POST_DEINSTALL;
     855                 :          0 :         } else {
     856                 :          0 :                 pkg_emit_error("unknown lua script '%s'", filename);
     857                 :          0 :                 ret = EPKG_FATAL;
     858                 :          0 :                 goto cleanup;
     859                 :            :         }
     860                 :            : 
     861                 :          0 :         ret = pkg_add_lua_script(pkg, data, type);
     862                 :            : cleanup:
     863                 :          0 :         free(data);
     864                 :          0 :         return (ret);
     865                 :          0 : }
     866                 :            : 
     867                 :            : int
     868                 :          0 : pkg_addscript_fileat(int fd, struct pkg *pkg, const char *filename)
     869                 :            : {
     870                 :            :         char *data;
     871                 :            :         pkg_script type;
     872                 :          0 :         int ret = EPKG_OK;
     873                 :          0 :         off_t sz = 0;
     874                 :            : 
     875         [ #  # ]:          0 :         assert(pkg != NULL);
     876         [ #  # ]:          0 :         assert(filename != NULL);
     877                 :            : 
     878                 :          0 :         pkg_debug(1, "Adding script from: '%s'", filename);
     879                 :            : 
     880         [ #  # ]:          0 :         if ((ret = file_to_bufferat(fd, filename, &data, &sz)) != EPKG_OK)
     881                 :          0 :                 return (ret);
     882                 :            : 
     883   [ #  #  #  # ]:          0 :         if (strcmp(filename, "pkg-pre-install") == 0 ||
     884                 :          0 :                         strcmp(filename, "+PRE_INSTALL") == 0) {
     885                 :          0 :                 type = PKG_SCRIPT_PRE_INSTALL;
     886   [ #  #  #  # ]:          0 :         } else if (strcmp(filename, "pkg-post-install") == 0 ||
     887                 :          0 :                         strcmp(filename, "+POST_INSTALL") == 0) {
     888                 :          0 :                 type = PKG_SCRIPT_POST_INSTALL;
     889   [ #  #  #  # ]:          0 :         } else if (strcmp(filename, "pkg-install") == 0 ||
     890                 :          0 :                         strcmp(filename, "+INSTALL") == 0) {
     891                 :          0 :                 type = PKG_SCRIPT_INSTALL;
     892   [ #  #  #  # ]:          0 :         } else if (strcmp(filename, "pkg-pre-deinstall") == 0 ||
     893                 :          0 :                         strcmp(filename, "+PRE_DEINSTALL") == 0) {
     894                 :          0 :                 type = PKG_SCRIPT_PRE_DEINSTALL;
     895   [ #  #  #  # ]:          0 :         } else if (strcmp(filename, "pkg-post-deinstall") == 0 ||
     896                 :          0 :                         strcmp(filename, "+POST_DEINSTALL") == 0) {
     897                 :          0 :                 type = PKG_SCRIPT_POST_DEINSTALL;
     898   [ #  #  #  # ]:          0 :         } else if (strcmp(filename, "pkg-deinstall") == 0 ||
     899                 :          0 :                         strcmp(filename, "+DEINSTALL") == 0) {
     900                 :          0 :                 type = PKG_SCRIPT_DEINSTALL;
     901                 :          0 :         } else {
     902                 :          0 :                 pkg_emit_error("unknown script '%s'", filename);
     903                 :          0 :                 ret = EPKG_FATAL;
     904                 :          0 :                 goto cleanup;
     905                 :            :         }
     906                 :            : 
     907                 :          0 :         ret = pkg_addscript(pkg, data, type);
     908                 :            : cleanup:
     909                 :          0 :         free(data);
     910                 :          0 :         return (ret);
     911                 :          0 : }
     912                 :            : 
     913                 :            : int
     914                 :         12 : pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type)
     915                 :            : {
     916                 :            : 
     917         [ +  - ]:         12 :         assert(pkg != NULL);
     918         [ +  - ]:         12 :         assert(cmd != NULL && cmd[0] != '\0');
     919                 :            : 
     920         [ -  + ]:         12 :         if (pkg->scripts[type] == NULL)
     921                 :         12 :                 pkg->scripts[type] = xstring_new();
     922                 :            : 
     923                 :         12 :         fprintf(pkg->scripts[type]->fp, "%s", cmd);
     924                 :            : 
     925                 :         12 :         return (EPKG_OK);
     926                 :            : }
     927                 :            : 
     928                 :            : int
     929                 :        840 : pkg_addoption(struct pkg *pkg, const char *key, const char *value)
     930                 :            : {
     931                 :        840 :         struct pkg_option       *o = NULL;
     932                 :            : 
     933         [ +  - ]:        840 :         assert(pkg != NULL);
     934         [ +  - ]:        840 :         assert(key != NULL && key[0] != '\0');
     935         [ +  - ]:        840 :         assert(value != NULL && value[0] != '\0');
     936                 :            : 
     937                 :            :         /* There might be a default or description for the option
     938                 :            :            already, so we only count it as a duplicate if the value
     939                 :            :            field is already set. Which implies there could be a
     940                 :            :            default value or description for an option but no actual
     941                 :            :            value. */
     942                 :            : 
     943                 :        840 :         pkg_debug(2,"Pkg> adding options: %s = %s", key, value);
     944         [ -  + ]:        840 :         if (pkghash_get(pkg->optionshash, key) != NULL) {
     945         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     946                 :          0 :                         pkg_emit_error("duplicate options listing: %s, fatal (developer mode)", key);
     947                 :          0 :                         return (EPKG_FATAL);
     948                 :            :                 } else {
     949                 :          0 :                         pkg_emit_error("duplicate options listing: %s, ignoring", key);
     950                 :          0 :                         return (EPKG_OK);
     951                 :            :                 }
     952                 :            :         }
     953                 :        840 :         o = xcalloc(1, sizeof(*o));
     954                 :        840 :         o->key = xstrdup(key);
     955                 :        840 :         o->value = xstrdup(value);
     956   [ +  +  -  + ]:       1510 :         pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
     957         [ +  + ]:        840 :         DL_APPEND(pkg->options, o);
     958                 :            : 
     959                 :        840 :         return (EPKG_OK);
     960                 :        840 : }
     961                 :            : 
     962                 :            : int
     963                 :          0 : pkg_addoption_default(struct pkg *pkg, const char *key,
     964                 :            :                       const char *default_value)
     965                 :            : {
     966                 :          0 :         struct pkg_option *o = NULL;
     967                 :            : 
     968         [ #  # ]:          0 :         assert(pkg != NULL);
     969         [ #  # ]:          0 :         assert(key != NULL && key[0] != '\0');
     970         [ #  # ]:          0 :         assert(default_value != NULL && default_value[0] != '\0');
     971                 :            : 
     972                 :            :         /* There might be a value or description for the option
     973                 :            :            already, so we only count it as a duplicate if the
     974                 :            :            default_value field is already set. Which implies there
     975                 :            :            could be a default value or description for an option but
     976                 :            :            no actual value. */
     977                 :            : 
     978         [ #  # ]:          0 :         if (pkghash_get(pkg->optionshash, key) != NULL) {
     979         [ #  # ]:          0 :                 if (ctx.developer_mode) {
     980                 :          0 :                         pkg_emit_error("duplicate default value for option: %s, fatal (developer mode)", key);
     981                 :          0 :                         return (EPKG_FATAL);
     982                 :            :                 } else {
     983                 :          0 :                         pkg_emit_error("duplicate default value for option: %s, ignoring", key);
     984                 :          0 :                         return (EPKG_OK);
     985                 :            :                 }
     986                 :            :         }
     987                 :          0 :         o = xcalloc(1, sizeof(*o));
     988                 :          0 :         o->key = xstrdup(key);
     989                 :          0 :         o->default_value = xstrdup(default_value);
     990   [ #  #  #  # ]:          0 :         pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
     991         [ #  # ]:          0 :         DL_APPEND(pkg->options, o);
     992                 :            : 
     993                 :          0 :         return (EPKG_OK);
     994                 :          0 : }
     995                 :            : 
     996                 :            : int
     997                 :          0 : pkg_addoption_description(struct pkg *pkg, const char *key,
     998                 :            :                           const char *description)
     999                 :            : {
    1000                 :          0 :         struct pkg_option *o = NULL;
    1001                 :            : 
    1002         [ #  # ]:          0 :         assert(pkg != NULL);
    1003         [ #  # ]:          0 :         assert(key != NULL && key[0] != '\0');
    1004         [ #  # ]:          0 :         assert(description != NULL && description[0] != '\0');
    1005                 :            : 
    1006                 :            :         /* There might be a value or default for the option already,
    1007                 :            :            so we only count it as a duplicate if the description field
    1008                 :            :            is already set. Which implies there could be a default
    1009                 :            :            value or description for an option but no actual value. */
    1010                 :            : 
    1011         [ #  # ]:          0 :         if (pkghash_get(pkg->optionshash, key) != NULL) {
    1012         [ #  # ]:          0 :                 if (ctx.developer_mode) {
    1013                 :          0 :                         pkg_emit_error("duplicate description for option: %s, fatal (developer mode)", key);
    1014                 :          0 :                         return (EPKG_FATAL);
    1015                 :            :                 } else {
    1016                 :          0 :                         pkg_emit_error("duplicate description for option: %s, ignoring", key);
    1017                 :          0 :                         return (EPKG_OK);
    1018                 :            :                 }
    1019                 :            :         }
    1020                 :            : 
    1021                 :          0 :         o = xcalloc(1, sizeof(*o));
    1022                 :          0 :         o->key = xstrdup(key);
    1023                 :          0 :         o->description = xstrdup(description);
    1024   [ #  #  #  # ]:          0 :         pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
    1025         [ #  # ]:          0 :         DL_APPEND(pkg->options, o);
    1026                 :            : 
    1027                 :          0 :         return (EPKG_OK);
    1028                 :          0 : }
    1029                 :            : 
    1030                 :            : int
    1031                 :         80 : pkg_addshlib_required(struct pkg *pkg, const char *name)
    1032                 :            : {
    1033         [ +  - ]:         80 :         assert(pkg != NULL);
    1034         [ +  - ]:         80 :         assert(name != NULL && name[0] != '\0');
    1035                 :            : 
    1036                 :            :         /* silently ignore duplicates in case of shlibs */
    1037         [ -  + ]:         80 :         if (pkghash_get(pkg->shlibs_required, name) != NULL)
    1038                 :          0 :                 return (EPKG_OK);
    1039                 :            : 
    1040   [ -  +  #  # ]:         80 :         pkghash_safe_add(pkg->shlibs_required, name, NULL, NULL);
    1041                 :            : 
    1042                 :         80 :         pkg_debug(3, "added shlib deps for %s on %s", pkg->name, name);
    1043                 :            : 
    1044                 :         80 :         return (EPKG_OK);
    1045                 :         80 : }
    1046                 :            : 
    1047                 :            : int
    1048                 :        166 : pkg_addshlib_provided(struct pkg *pkg, const char *name)
    1049                 :            : {
    1050         [ +  - ]:        166 :         assert(pkg != NULL);
    1051         [ +  - ]:        166 :         assert(name != NULL && name[0] != '\0');
    1052                 :            : 
    1053                 :            :         /* ignore files which are not starting with lib */
    1054         [ -  + ]:        166 :         if (strncmp(name, "lib", 3) != 0)
    1055                 :          0 :                 return (EPKG_OK);
    1056                 :            : 
    1057                 :            :         /* silently ignore duplicates in case of shlibs */
    1058         [ -  + ]:        166 :         if (pkghash_get(pkg->shlibs_provided, name) != NULL)
    1059                 :          0 :                 return (EPKG_OK);
    1060                 :            : 
    1061   [ +  +  +  - ]:        170 :         pkghash_safe_add(pkg->shlibs_provided, name, NULL, NULL);
    1062                 :            : 
    1063                 :        166 :         pkg_debug(3, "added shlib provide %s for %s", name, pkg->name);
    1064                 :            : 
    1065                 :        166 :         return (EPKG_OK);
    1066                 :        166 : }
    1067                 :            : 
    1068                 :            : int
    1069                 :          0 : pkg_addconflict(struct pkg *pkg, const char *uniqueid)
    1070                 :            : {
    1071                 :          0 :         struct pkg_conflict *c = NULL;
    1072                 :            : 
    1073         [ #  # ]:          0 :         assert(pkg != NULL);
    1074         [ #  # ]:          0 :         assert(uniqueid != NULL && uniqueid[0] != '\0');
    1075                 :            : 
    1076         [ #  # ]:          0 :         if (pkghash_get(pkg->conflictshash, uniqueid) != NULL) {
    1077                 :            :                 /* silently ignore duplicates in case of conflicts */
    1078                 :          0 :                 return (EPKG_OK);
    1079                 :            :         }
    1080                 :            : 
    1081                 :          0 :         c = xcalloc(1, sizeof(*c));
    1082                 :          0 :         c->uid = xstrdup(uniqueid);
    1083                 :          0 :         pkg_debug(3, "Pkg: add a new conflict origin: %s, with %s", pkg->uid, uniqueid);
    1084                 :            : 
    1085   [ #  #  #  # ]:          0 :         pkghash_safe_add(pkg->conflictshash, c->uid, c, NULL);
    1086         [ #  # ]:          0 :         DL_APPEND(pkg->conflicts, c);
    1087                 :            : 
    1088                 :          0 :         return (EPKG_OK);
    1089                 :          0 : }
    1090                 :            : 
    1091                 :            : int
    1092                 :        164 : pkg_addrequire(struct pkg *pkg, const char *name)
    1093                 :            : {
    1094         [ +  - ]:        164 :         assert(pkg != NULL);
    1095         [ +  - ]:        164 :         assert(name != NULL && name[0] != '\0');
    1096                 :            : 
    1097                 :            :         /* silently ignore duplicates in case of conflicts */
    1098         [ -  + ]:        164 :         if (pkghash_get(pkg->requires, name) != NULL)
    1099                 :          0 :                 return (EPKG_OK);
    1100                 :            : 
    1101   [ -  +  #  # ]:        164 :         pkghash_safe_add(pkg->requires, name, NULL, NULL);
    1102                 :            : 
    1103                 :        164 :         return (EPKG_OK);
    1104                 :        164 : }
    1105                 :            : 
    1106                 :            : int
    1107                 :         88 : pkg_addprovide(struct pkg *pkg, const char *name)
    1108                 :            : {
    1109         [ +  - ]:         88 :         assert(pkg != NULL);
    1110         [ +  - ]:         88 :         assert(name != NULL && name[0] != '\0');
    1111                 :            : 
    1112                 :            :         /* silently ignore duplicates in case of conflicts */
    1113         [ -  + ]:         88 :         if (pkghash_get(pkg->provides, name) != NULL)
    1114                 :          0 :                 return (EPKG_OK);
    1115                 :            : 
    1116   [ -  +  #  # ]:         88 :         pkghash_safe_add(pkg->provides, name, NULL, NULL);
    1117                 :            : 
    1118                 :         88 :         return (EPKG_OK);
    1119                 :         88 : }
    1120                 :            : 
    1121                 :            : const char *
    1122                 :       4213 : pkg_kv_get(struct pkg_kv *const *kv, const char *tag)
    1123                 :            : {
    1124                 :            :         struct pkg_kv *k;
    1125                 :            : 
    1126         [ +  - ]:       4213 :         assert(tag != NULL);
    1127                 :            : 
    1128         [ +  + ]:       7586 :         LL_FOREACH(*kv, k) {
    1129         [ +  + ]:       4024 :                 if (strcmp(k->key, tag) == 0)
    1130                 :        651 :                         return (k->value);
    1131                 :       3373 :         }
    1132                 :            : 
    1133                 :       3562 :         return (NULL);
    1134                 :       4213 : }
    1135                 :            : 
    1136                 :            : int
    1137                 :       5233 : pkg_kv_add(struct pkg_kv **list, const char *key, const char *val, const char *title)
    1138                 :            : {
    1139                 :            :         struct pkg_kv *kv;
    1140                 :            : 
    1141         [ +  - ]:       5233 :         assert(val != NULL);
    1142         [ -  + ]:       5233 :         assert(title != NULL);
    1143                 :            : 
    1144         [ +  + ]:       6879 :         LL_FOREACH(*list, kv) {
    1145         [ +  - ]:       1646 :                 if (strcmp(kv->key, key) == 0) {
    1146         [ #  # ]:          0 :                         if (ctx.developer_mode) {
    1147                 :          0 :                                 pkg_emit_error("duplicate %s: %s, fatal"
    1148                 :          0 :                                     " (developer mode)", title, key);
    1149                 :          0 :                                 return (EPKG_FATAL);
    1150                 :            :                         } else {
    1151                 :          0 :                                 pkg_emit_error("duplicate %s: %s, "
    1152                 :          0 :                                     "ignoring", title, val);
    1153                 :          0 :                                 return (EPKG_OK);
    1154                 :            :                         }
    1155                 :            :                 }
    1156                 :       1646 :         }
    1157                 :            : 
    1158                 :       5233 :         kv = pkg_kv_new(key, val);
    1159         [ +  + ]:       5233 :         DL_APPEND(*list, kv);
    1160                 :            : 
    1161                 :       5233 :         return (EPKG_OK);
    1162                 :       5233 : }
    1163                 :            : 
    1164                 :            : int
    1165                 :        110 : pkg_list_count(const struct pkg *pkg, pkg_list list)
    1166                 :            : {
    1167   [ -  -  -  +  :        110 :         switch (list) {
          +  -  -  -  +  
          +  -  +  +  -  
                   -  - ]
    1168                 :            :         case PKG_DEPS:
    1169                 :          0 :                 return (pkghash_count(pkg->depshash));
    1170                 :            :         case PKG_RDEPS:
    1171                 :          0 :                 return (pkghash_count(pkg->rdepshash));
    1172                 :            :         case PKG_OPTIONS:
    1173                 :         26 :                 return (pkghash_count(pkg->optionshash));
    1174                 :            :         case PKG_FILES:
    1175                 :         12 :                 return (pkghash_count(pkg->filehash));
    1176                 :            :         case PKG_DIRS:
    1177                 :          0 :                 return (pkghash_count(pkg->dirhash));
    1178                 :            :         case PKG_USERS:
    1179                 :          0 :                 return (pkghash_count(pkg->users));
    1180                 :            :         case PKG_GROUPS:
    1181                 :          0 :                 return (pkghash_count(pkg->groups));
    1182                 :            :         case PKG_SHLIBS_REQUIRED:
    1183                 :         18 :                 return (pkghash_count(pkg->shlibs_required));
    1184                 :            :         case PKG_SHLIBS_PROVIDED:
    1185                 :         18 :                 return (pkghash_count(pkg->shlibs_provided));
    1186                 :            :         case PKG_CONFLICTS:
    1187                 :          0 :                 return (pkghash_count(pkg->conflictshash));
    1188                 :            :         case PKG_PROVIDES:
    1189                 :         18 :                 return (pkghash_count(pkg->provides));
    1190                 :            :         case PKG_REQUIRES:
    1191                 :         18 :                 return (pkghash_count(pkg->requires));
    1192                 :            :         case PKG_CONFIG_FILES:
    1193                 :          0 :                 return (pkghash_count(pkg->config_files_hash));
    1194                 :            :         case PKG_CATEGORIES:
    1195                 :          0 :                 return (pkghash_count(pkg->categories));
    1196                 :            :         case PKG_LICENSES:
    1197                 :          0 :                 return (pkghash_count(pkg->licenses));
    1198                 :            :         }
    1199                 :            : 
    1200                 :          0 :         return (0);
    1201                 :        110 : }
    1202                 :            : 
    1203                 :            : void
    1204                 :      82573 : pkg_list_free(struct pkg *pkg, pkg_list list)  {
    1205                 :            :         struct pkg_dep *cur;
    1206                 :            : 
    1207   [ +  -  +  +  :      82573 :         switch (list) {
          +  +  +  +  +  
          +  -  +  +  +  
                      + ]
    1208                 :            :         case PKG_DEPS:
    1209         [ +  + ]:       7780 :                 DL_FOREACH (pkg->depends, cur) {
    1210         [ +  - ]:       1499 :                         if (cur->alt_next) {
    1211   [ #  #  #  #  :          0 :                                 DL_FREE2(cur->alt_next, pkg_dep_free, alt_prev, alt_next);
          #  #  #  #  #  
                #  #  # ]
    1212                 :          0 :                         }
    1213                 :       1499 :                 }
    1214   [ +  +  +  +  :       7780 :                 DL_FREE(pkg->depends, pkg_dep_free);
          +  -  +  +  -  
                +  #  # ]
    1215                 :       6281 :                 pkghash_destroy(pkg->depshash);
    1216                 :       6281 :                 pkg->depshash = NULL;
    1217                 :       6281 :                 pkg->flags &= ~PKG_LOAD_DEPS;
    1218                 :       6281 :                 break;
    1219                 :            :         case PKG_RDEPS:
    1220   [ +  +  +  +  :       6413 :                 LL_FREE(pkg->rdepends, pkg_dep_free);
          -  +  #  #  #  
                #  #  # ]
    1221                 :       6281 :                 pkghash_destroy(pkg->rdepshash);
    1222                 :       6281 :                 pkg->depshash = NULL;
    1223                 :       6281 :                 pkg->flags &= ~PKG_LOAD_RDEPS;
    1224                 :       6281 :                 break;
    1225                 :            :         case PKG_OPTIONS:
    1226   [ +  +  +  +  :       7089 :                 DL_FREE(pkg->options, pkg_option_free);
          +  -  +  +  -  
                +  #  # ]
    1227                 :       6281 :                 pkghash_destroy(pkg->optionshash);
    1228                 :       6281 :                 pkg->optionshash = NULL;
    1229                 :       6281 :                 pkg->flags &= ~PKG_LOAD_OPTIONS;
    1230                 :       6281 :                 break;
    1231                 :            :         case PKG_FILES:
    1232                 :            :         case PKG_CONFIG_FILES:
    1233   [ +  +  +  +  :       9878 :                 DL_FREE(pkg->files, pkg_file_free);
          +  -  +  +  -  
                +  #  # ]
    1234                 :       6741 :                 pkghash_destroy(pkg->filehash);
    1235                 :       6741 :                 pkg->filehash = NULL;
    1236   [ +  +  +  +  :       6926 :                 DL_FREE(pkg->config_files, pkg_config_file_free);
          +  -  -  +  #  
                #  #  # ]
    1237                 :       6741 :                 pkghash_destroy(pkg->config_files_hash);
    1238                 :       6741 :                 pkg->config_files_hash = NULL;
    1239                 :       6741 :                 pkg->flags &= ~PKG_LOAD_FILES;
    1240                 :       6741 :                 break;
    1241                 :            :         case PKG_DIRS:
    1242   [ +  +  +  +  :       6913 :                 DL_FREE(pkg->dirs, free);
          +  -  +  +  -  
                +  #  # ]
    1243                 :       6741 :                 pkghash_destroy(pkg->dirhash);
    1244                 :       6741 :                 pkg->dirhash = NULL;
    1245                 :       6741 :                 pkg->flags &= ~PKG_LOAD_DIRS;
    1246                 :       6741 :                 break;
    1247                 :            :         case PKG_USERS:
    1248                 :       6281 :                 pkghash_destroy(pkg->users);
    1249                 :       6281 :                 pkg->users = NULL;
    1250                 :       6281 :                 pkg->flags &= ~PKG_LOAD_USERS;
    1251                 :       6281 :                 break;
    1252                 :            :         case PKG_GROUPS:
    1253                 :       6281 :                 pkghash_destroy(pkg->groups);
    1254                 :       6281 :                 pkg->groups = NULL;
    1255                 :       6281 :                 pkg->flags &= ~PKG_LOAD_GROUPS;
    1256                 :       6281 :                 break;
    1257                 :            :         case PKG_SHLIBS_REQUIRED:
    1258                 :       6281 :                 pkghash_destroy(pkg->shlibs_required);
    1259                 :       6281 :                 pkg->shlibs_required = NULL;
    1260                 :       6281 :                 pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
    1261                 :       6281 :                 break;
    1262                 :            :         case PKG_SHLIBS_PROVIDED:
    1263                 :       6281 :                 pkghash_destroy(pkg->shlibs_provided);
    1264                 :       6281 :                 pkg->shlibs_provided = NULL;
    1265                 :       6281 :                 pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
    1266                 :       6281 :                 break;
    1267                 :            :         case PKG_CONFLICTS:
    1268   [ #  #  #  #  :          0 :                 DL_FREE(pkg->conflicts, pkg_conflict_free);
          #  #  #  #  #  
                #  #  # ]
    1269                 :          0 :                 pkghash_destroy(pkg->conflictshash);
    1270                 :          0 :                 pkg->conflictshash = NULL;
    1271                 :          0 :                 pkg->flags &= ~PKG_LOAD_CONFLICTS;
    1272                 :          0 :                 break;
    1273                 :            :         case PKG_PROVIDES:
    1274                 :       6281 :                 pkghash_destroy(pkg->provides);
    1275                 :       6281 :                 pkg->provides = NULL;
    1276                 :       6281 :                 pkg->flags &= ~PKG_LOAD_PROVIDES;
    1277                 :       6281 :                 break;
    1278                 :            :         case PKG_REQUIRES:
    1279                 :       6281 :                 pkghash_destroy(pkg->requires);
    1280                 :       6281 :                 pkg->requires = NULL;
    1281                 :       6281 :                 pkg->flags &= ~PKG_LOAD_REQUIRES;
    1282                 :       6281 :                 break;
    1283                 :            :         case PKG_CATEGORIES:
    1284                 :       6281 :                 pkghash_destroy(pkg->categories);
    1285                 :       6281 :                 pkg->categories = NULL;
    1286                 :       6281 :                 pkg->flags &= ~PKG_LOAD_CATEGORIES;
    1287                 :       6281 :                 break;
    1288                 :            :         case PKG_LICENSES:
    1289                 :       6281 :                 pkghash_destroy(pkg->licenses);
    1290                 :       6281 :                 pkg->licenses = NULL;
    1291                 :       6281 :                 pkg->flags &= ~PKG_LOAD_LICENSES;
    1292                 :       6281 :                 break;
    1293                 :            :         }
    1294                 :      82573 : }
    1295                 :            : 
    1296                 :            : int
    1297                 :        704 : pkg_open(struct pkg **pkg_p, const char *path, struct pkg_manifest_key *keys, int flags)
    1298                 :            : {
    1299                 :            :         struct archive *a;
    1300                 :            :         struct archive_entry *ae;
    1301                 :            :         int ret;
    1302                 :            : 
    1303                 :        704 :         ret = pkg_open2(pkg_p, &a, &ae, path, keys, flags, -1);
    1304                 :            : 
    1305   [ +  +  -  + ]:        704 :         if (ret != EPKG_OK && ret != EPKG_END)
    1306                 :          0 :                 return (EPKG_FATAL);
    1307                 :            : 
    1308                 :        704 :         archive_read_close(a);
    1309                 :        704 :         archive_read_free(a);
    1310                 :            : 
    1311                 :        704 :         return (EPKG_OK);
    1312                 :        704 : }
    1313                 :            : 
    1314                 :            : int
    1315                 :         49 : pkg_open_fd(struct pkg **pkg_p, int fd, struct pkg_manifest_key *keys, int flags)
    1316                 :            : {
    1317                 :            :         struct archive *a;
    1318                 :            :         struct archive_entry *ae;
    1319                 :            :         int ret;
    1320                 :            : 
    1321                 :         49 :         ret = pkg_open2(pkg_p, &a, &ae, NULL, keys, flags, fd);
    1322                 :            : 
    1323   [ +  +  -  + ]:         49 :         if (ret != EPKG_OK && ret != EPKG_END)
    1324                 :          0 :                 return (EPKG_FATAL);
    1325                 :            : 
    1326                 :         49 :         archive_read_close(a);
    1327                 :         49 :         archive_read_free(a);
    1328                 :            : 
    1329                 :         49 :         return (EPKG_OK);
    1330                 :         49 : }
    1331                 :            : 
    1332                 :            : static int
    1333                 :       1495 : pkg_parse_archive(struct pkg *pkg, struct pkg_manifest_key *keys,
    1334                 :            :     struct archive *a, size_t len)
    1335                 :            : {
    1336                 :            :         void *buffer;
    1337                 :            :         int rc;
    1338                 :            : 
    1339                 :       1495 :         buffer = xmalloc(len);
    1340                 :            : 
    1341                 :       1495 :         archive_read_data(a, buffer, len);
    1342                 :       1495 :         rc = pkg_parse_manifest(pkg, buffer, len, keys);
    1343                 :       1495 :         free(buffer);
    1344                 :       1495 :         return (rc);
    1345                 :            : }
    1346                 :            : 
    1347                 :            : int
    1348                 :       1495 : pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae,
    1349                 :            :     const char *path, struct pkg_manifest_key *keys, int flags, int fd)
    1350                 :            : {
    1351                 :       1495 :         struct pkg      *pkg = NULL;
    1352                 :       1495 :         pkg_error_t      retcode = EPKG_OK;
    1353                 :            :         int              ret;
    1354                 :            :         const char      *fpath;
    1355                 :       1495 :         bool             manifest = false;
    1356                 :       1495 :         bool             read_from_stdin = 0;
    1357                 :            : 
    1358                 :       1495 :         *a = archive_read_new();
    1359                 :       1495 :         archive_read_support_filter_all(*a);
    1360                 :       1495 :         archive_read_support_format_tar(*a);
    1361                 :            : 
    1362                 :            :         /* archive_read_open_filename() treats a path of NULL as
    1363                 :            :          * meaning "read from stdin," but we want this behaviour if
    1364                 :            :          * path is exactly "-". In the unlikely event of wanting to
    1365                 :            :          * read an on-disk file called "-", just say "./-" or some
    1366                 :            :          * other leading path. */
    1367                 :            : 
    1368         [ +  + ]:       1495 :         if (fd == -1) {
    1369         [ +  - ]:       1446 :                 if (path == NULL) {
    1370                 :          0 :                         pkg_emit_error("bad usage of pkg_open2");
    1371                 :          0 :                         retcode = EPKG_FATAL;
    1372                 :          0 :                         goto cleanup;
    1373                 :            :                 }
    1374                 :       1446 :                 read_from_stdin = (strncmp(path, "-", 2) == 0);
    1375                 :            : 
    1376   [ -  +  -  + ]:       4338 :                 if (archive_read_open_filename(*a,
    1377         [ +  + ]:       1446 :                     read_from_stdin ? NULL : path, 4096) != ARCHIVE_OK) {
    1378         [ #  # ]:          0 :                         if ((flags & PKG_OPEN_TRY) == 0)
    1379                 :          0 :                                 pkg_emit_error("archive_read_open_filename(%s): %s", path,
    1380                 :          0 :                                         archive_error_string(*a));
    1381                 :            : 
    1382                 :          0 :                         retcode = EPKG_FATAL;
    1383                 :          0 :                         goto cleanup;
    1384                 :            :                 }
    1385                 :       1446 :         } else {
    1386         [ -  + ]:         49 :                 if (archive_read_open_fd(*a, fd, 4096) != ARCHIVE_OK) {
    1387         [ #  # ]:          0 :                         if ((flags & PKG_OPEN_TRY) == 0)
    1388                 :          0 :                                 pkg_emit_error("archive_read_open_fd: %s",
    1389                 :          0 :                                         archive_error_string(*a));
    1390                 :            : 
    1391                 :          0 :                         retcode = EPKG_FATAL;
    1392                 :          0 :                         goto cleanup;
    1393                 :            :                 }
    1394                 :            :         }
    1395                 :            : 
    1396                 :       1495 :         retcode = pkg_new(pkg_p, PKG_FILE);
    1397         [ -  + ]:       1495 :         if (retcode != EPKG_OK)
    1398                 :          0 :                 goto cleanup;
    1399                 :            : 
    1400                 :       1495 :         pkg = *pkg_p;
    1401                 :            : 
    1402         [ +  + ]:       4217 :         while ((ret = archive_read_next_header(*a, ae)) == ARCHIVE_OK) {
    1403                 :       3782 :                 fpath = archive_entry_pathname(*ae);
    1404         [ +  + ]:       3782 :                 if (fpath[0] != '+')
    1405                 :        816 :                         break;
    1406                 :            : 
    1407   [ +  -  -  + ]:       2990 :                 if (!manifest &&
    1408         [ +  + ]:       2966 :                         (flags & PKG_OPEN_MANIFEST_COMPACT) &&
    1409                 :         24 :                         strcmp(fpath, "+COMPACT_MANIFEST") == 0) {
    1410                 :         24 :                         manifest = true;
    1411                 :            : 
    1412                 :         24 :                         ret = pkg_parse_archive(pkg, keys, *a, archive_entry_size(*ae));
    1413         [ +  - ]:         24 :                         if (ret != EPKG_OK) {
    1414                 :          0 :                                 retcode = EPKG_FATAL;
    1415                 :          0 :                                 goto cleanup;
    1416                 :            :                         }
    1417                 :            :                         /* Do not read anything more */
    1418                 :         24 :                         break;
    1419                 :            :                 }
    1420   [ +  -  +  + ]:       2942 :                 if (!manifest && strcmp(fpath, "+MANIFEST") == 0) {
    1421                 :       1471 :                         manifest = true;
    1422                 :            : 
    1423                 :       1471 :                         ret = pkg_parse_archive(pkg, keys, *a, archive_entry_size(*ae));
    1424         [ +  - ]:       1471 :                         if (ret != EPKG_OK) {
    1425         [ #  # ]:          0 :                                 if ((flags & PKG_OPEN_TRY) == 0)
    1426                 :          0 :                                         pkg_emit_error("%s is not a valid package: "
    1427                 :          0 :                                                 "Invalid manifest", path);
    1428                 :            : 
    1429                 :          0 :                                 retcode = EPKG_FATAL;
    1430                 :          0 :                                 goto cleanup;
    1431                 :            :                         }
    1432                 :            : 
    1433         [ +  + ]:       1471 :                         if (flags & PKG_OPEN_MANIFEST_ONLY)
    1434                 :        220 :                                 break;
    1435                 :       1251 :                 }
    1436                 :            :         }
    1437                 :            : 
    1438   [ +  +  +  - ]:       1495 :         if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) {
    1439         [ #  # ]:          0 :                 if ((flags & PKG_OPEN_TRY) == 0)
    1440                 :          0 :                         pkg_emit_error("archive_read_next_header(): %s",
    1441                 :          0 :                                 archive_error_string(*a));
    1442                 :            : 
    1443                 :          0 :                 retcode = EPKG_FATAL;
    1444                 :          0 :         }
    1445                 :            : 
    1446         [ +  + ]:       1495 :         if (ret == ARCHIVE_EOF)
    1447                 :        435 :                 retcode = EPKG_END;
    1448                 :            : 
    1449         [ +  - ]:       1495 :         if (!manifest) {
    1450                 :          0 :                 retcode = EPKG_FATAL;
    1451         [ #  # ]:          0 :                 if ((flags & PKG_OPEN_TRY) == 0)
    1452                 :          0 :                         pkg_emit_error("%s is not a valid package: no manifest found", path);
    1453                 :          0 :         }
    1454                 :            : 
    1455                 :            :         cleanup:
    1456   [ +  +  +  - ]:       1495 :         if (retcode != EPKG_OK && retcode != EPKG_END) {
    1457         [ #  # ]:          0 :                 if (*a != NULL) {
    1458                 :          0 :                         archive_read_close(*a);
    1459                 :          0 :                         archive_read_free(*a);
    1460                 :          0 :                 }
    1461                 :          0 :                 free(pkg);
    1462                 :          0 :                 *pkg_p = NULL;
    1463                 :          0 :                 *a = NULL;
    1464                 :          0 :                 *ae = NULL;
    1465                 :          0 :         }
    1466                 :            : 
    1467                 :       1495 :         return (retcode);
    1468                 :            : }
    1469                 :            : 
    1470                 :            : int
    1471                 :       1922 : pkg_validate(struct pkg *pkg, struct pkgdb *db)
    1472                 :            : {
    1473         [ +  - ]:       1922 :         assert(pkg != NULL);
    1474                 :       1922 :         unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
    1475                 :            :                                         PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
    1476                 :            :                                         PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
    1477                 :            :                                         PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
    1478                 :            : 
    1479         [ +  + ]:       1922 :         if (pkg->uid == NULL) {
    1480                 :            :                 /* Keep that part for the day we have to change it */
    1481                 :            :                 /* Generate uid from name*/
    1482         [ +  - ]:        212 :                 if (pkg->name == NULL)
    1483                 :          0 :                         return (EPKG_FATAL);
    1484                 :            : 
    1485                 :        212 :                 pkg->uid = xstrdup(pkg->name);
    1486                 :        212 :         }
    1487                 :            : 
    1488   [ +  +  -  +  :       1922 :         if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest,
                   -  + ]
    1489                 :       1706 :                         strlen(pkg->digest))) {
    1490                 :            :                 /* Calculate new digest */
    1491         [ +  + ]:        216 :                 if (pkgdb_ensure_loaded(db, pkg, flags)) {
    1492                 :        212 :                         return (pkg_checksum_calculate(pkg, db, false, true, false));
    1493                 :            :                 }
    1494                 :          4 :                 return (EPKG_FATAL);
    1495                 :            :         }
    1496                 :            : 
    1497                 :       1706 :         return (EPKG_OK);
    1498                 :       1922 : }
    1499                 :            : 
    1500                 :            : int
    1501                 :          0 : pkg_test_filesum(struct pkg *pkg)
    1502                 :            : {
    1503                 :          0 :         struct pkg_file *f = NULL;
    1504                 :          0 :         int rc = EPKG_OK;
    1505                 :            :         int ret;
    1506                 :            : 
    1507         [ #  # ]:          0 :         assert(pkg != NULL);
    1508                 :            : 
    1509         [ #  # ]:          0 :         while (pkg_files(pkg, &f) == EPKG_OK) {
    1510         [ #  # ]:          0 :                 if (f->sum != NULL) {
    1511                 :          0 :                         ret = pkg_checksum_validate_file(f->path, f->sum);
    1512         [ #  # ]:          0 :                         if (ret != 0) {
    1513         [ #  # ]:          0 :                                 if (ret == ENOENT)
    1514                 :          0 :                                         pkg_emit_file_missing(pkg, f);
    1515                 :            :                                 else
    1516                 :          0 :                                         pkg_emit_file_mismatch(pkg, f, f->sum);
    1517                 :          0 :                                 rc = EPKG_FATAL;
    1518                 :          0 :                         }
    1519                 :          0 :                 }
    1520                 :            :         }
    1521                 :            : 
    1522                 :          0 :         return (rc);
    1523                 :            : }
    1524                 :            : 
    1525                 :            : int
    1526                 :          0 : pkg_recompute(struct pkgdb *db, struct pkg *pkg)
    1527                 :            : {
    1528                 :          0 :         struct pkg_file *f = NULL;
    1529                 :          0 :         hardlinks_t *hl = NULL;
    1530                 :          0 :         int64_t flatsize = 0;
    1531                 :            :         struct stat st;
    1532                 :          0 :         bool regular = false;
    1533                 :            :         char *sum;
    1534                 :          0 :         int rc = EPKG_OK;
    1535                 :            : 
    1536                 :          0 :         hl = kh_init_hardlinks();
    1537         [ #  # ]:          0 :         while (pkg_files(pkg, &f) == EPKG_OK) {
    1538         [ #  # ]:          0 :                 if (lstat(f->path, &st) != 0)
    1539                 :          0 :                         continue;
    1540                 :          0 :                 regular = true;
    1541                 :          0 :                 sum = pkg_checksum_generate_file(f->path,
    1542                 :            :                     PKG_HASH_TYPE_SHA256_HEX);
    1543                 :            : 
    1544         [ #  # ]:          0 :                 if (S_ISLNK(st.st_mode))
    1545                 :          0 :                         regular = false;
    1546                 :            : 
    1547         [ #  # ]:          0 :                 if (sum == NULL) {
    1548                 :          0 :                         rc = EPKG_FATAL;
    1549                 :          0 :                         break;
    1550                 :            :                 }
    1551                 :            : 
    1552         [ #  # ]:          0 :                 if (st.st_nlink > 1)
    1553                 :          0 :                         regular = !check_for_hardlink(hl, &st);
    1554                 :            : 
    1555         [ #  # ]:          0 :                 if (regular)
    1556                 :          0 :                         flatsize += st.st_size;
    1557                 :            : 
    1558         [ #  # ]:          0 :                 if (strcmp(sum, f->sum) != 0)
    1559                 :          0 :                         pkgdb_file_set_cksum(db, f, sum);
    1560                 :          0 :                 free(sum);
    1561                 :            :         }
    1562                 :          0 :         kh_destroy_hardlinks(hl);
    1563                 :            : 
    1564         [ #  # ]:          0 :         if (flatsize != pkg->flatsize)
    1565                 :          0 :                 pkg->flatsize = flatsize;
    1566                 :            : 
    1567                 :          0 :         return (rc);
    1568                 :            : }
    1569                 :            : 
    1570                 :            : int
    1571                 :        688 : pkg_try_installed(struct pkgdb *db, const char *name,
    1572                 :            :                 struct pkg **pkg, unsigned flags) {
    1573                 :        688 :         struct pkgdb_it *it = NULL;
    1574                 :        688 :         int ret = EPKG_FATAL;
    1575                 :            : 
    1576         [ -  + ]:        688 :         if ((it = pkgdb_query(db, name, MATCH_EXACT)) == NULL)
    1577                 :          0 :                 return (EPKG_FATAL);
    1578                 :            : 
    1579                 :        688 :         ret = pkgdb_it_next(it, pkg, flags);
    1580                 :        688 :         pkgdb_it_free(it);
    1581                 :            : 
    1582                 :        688 :         return (ret);
    1583                 :        688 : }
    1584                 :            : 
    1585                 :            : int
    1586                 :        485 : pkg_is_installed(struct pkgdb *db, const char *name)
    1587                 :            : {
    1588                 :        485 :         struct pkg *pkg = NULL;
    1589                 :        485 :         int ret = EPKG_FATAL;
    1590                 :            : 
    1591                 :        485 :         ret = pkg_try_installed(db, name, &pkg, PKG_LOAD_BASIC);
    1592                 :        485 :         pkg_free(pkg);
    1593                 :            : 
    1594                 :        485 :         return (ret);
    1595                 :            : }
    1596                 :            : 
    1597                 :            : bool
    1598                 :         24 : pkg_has_message(struct pkg *p)
    1599                 :            : {
    1600                 :         24 :         return (p->message != NULL);
    1601                 :            : }
    1602                 :            : 
    1603                 :            : bool
    1604                 :       1303 : pkg_is_locked(const struct pkg * restrict p)
    1605                 :            : {
    1606         [ +  - ]:       1303 :         assert(p != NULL);
    1607                 :            : 
    1608                 :       1303 :         return (p->locked);
    1609                 :            : }
    1610                 :            : 
    1611                 :            : bool
    1612                 :         22 : pkg_is_config_file(struct pkg *p, const char *path,
    1613                 :            :     const struct pkg_file **file,
    1614                 :            :     struct pkg_config_file **cfile)
    1615                 :            : {
    1616                 :         22 :         *file = NULL;
    1617                 :         22 :         *cfile = NULL;
    1618                 :            : 
    1619         [ +  + ]:         22 :         if (pkghash_count(p->config_files_hash) == 0)
    1620                 :         10 :                 return (false);
    1621                 :            : 
    1622                 :         12 :         *file = pkghash_get_value(p->filehash, path);
    1623         [ +  - ]:         12 :         if (*file == NULL)
    1624                 :          0 :                 return (false);
    1625                 :         12 :         *cfile = pkghash_get_value(p->config_files_hash, path);
    1626         [ -  + ]:         12 :         if (*cfile == NULL) {
    1627                 :          0 :                 *file = NULL;
    1628                 :          0 :                 return (false);
    1629                 :            :         }
    1630                 :            : 
    1631                 :         12 :         return (true);
    1632                 :         22 : }
    1633                 :            : 
    1634                 :            : struct pkg_dir *
    1635                 :         24 : pkg_get_dir(struct pkg *p, const char *path)
    1636                 :            : {
    1637                 :         24 :         return (pkghash_get_value(p->dirhash, path));
    1638                 :            : }
    1639                 :            : 
    1640                 :            : struct pkg_file *
    1641                 :        522 : pkg_get_file(struct pkg *p, const char *path)
    1642                 :            : {
    1643                 :        522 :         return (pkghash_get_value(p->filehash, path));
    1644                 :            : }
    1645                 :            : 
    1646                 :            : bool
    1647                 :        388 : pkg_has_file(struct pkg *p, const char *path)
    1648                 :            : {
    1649                 :        388 :         return (pkghash_get(p->filehash, path) != NULL);
    1650                 :            : }
    1651                 :            : 
    1652                 :            : bool
    1653                 :         56 : pkg_has_dir(struct pkg *p, const char *path)
    1654                 :            : {
    1655                 :         56 :         return (pkghash_get(p->dirhash, path) != NULL);
    1656                 :            : }
    1657                 :            : 
    1658                 :            : int
    1659                 :       1197 : pkg_open_root_fd(struct pkg *pkg)
    1660                 :            : {
    1661                 :            :         const char *path;
    1662                 :            : 
    1663         [ +  + ]:       1197 :         if (pkg->rootfd != -1)
    1664                 :        170 :                 return (EPKG_OK);
    1665                 :            : 
    1666                 :       1027 :         path = pkg_kv_get(&pkg->annotations, "relocated");
    1667         [ -  + ]:       1027 :         if (path == NULL) {
    1668         [ -  + ]:       1027 :                 if ((pkg->rootfd = dup(ctx.rootfd)) == -1) {
    1669                 :          0 :                         pkg_emit_errno("dup2", "rootfd");
    1670                 :          0 :                         return (EPKG_FATAL);
    1671                 :            :                 }
    1672                 :       1027 :                 return (EPKG_OK);
    1673                 :            :         }
    1674                 :            : 
    1675                 :          0 :         pkg_absolutepath(path, pkg->rootpath, sizeof(pkg->rootpath), false);
    1676                 :            : 
    1677         [ #  # ]:          0 :         if ((pkg->rootfd = openat(ctx.rootfd, pkg->rootpath + 1, O_DIRECTORY)) >= 0 )
    1678                 :          0 :                 return (EPKG_OK);
    1679                 :            : 
    1680                 :          0 :         pkg->rootpath[0] = '\0';
    1681                 :          0 :         pkg_emit_errno("open", path);
    1682                 :            : 
    1683                 :          0 :         return (EPKG_FATAL);
    1684                 :       1197 : }
    1685                 :            : 
    1686                 :            : int
    1687                 :        160 : pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
    1688                 :            : {
    1689                 :        160 :         struct pkg_message *msg = NULL;
    1690                 :            :         const ucl_object_t *elt, *cur;
    1691                 :        160 :         ucl_object_iter_t it = NULL;
    1692                 :            : 
    1693         [ +  + ]:        160 :         if (ucl_object_type(obj) == UCL_STRING) {
    1694                 :         12 :                 msg = xcalloc(1, sizeof(*msg));
    1695                 :         12 :                 msg->str = xstrdup(ucl_object_tostring(obj));
    1696                 :         12 :                 msg->type = PKG_MESSAGE_ALWAYS;
    1697         [ -  + ]:         12 :                 DL_APPEND(pkg->message, msg);
    1698                 :         12 :                 return (EPKG_OK);
    1699                 :            :         }
    1700                 :            : 
    1701                 :            :         /* New format of pkg message */
    1702         [ +  - ]:        148 :         if (ucl_object_type(obj) != UCL_ARRAY)
    1703                 :          0 :                 pkg_emit_error("package message badly formatted, an array was"
    1704                 :            :                     " expected");
    1705                 :            : 
    1706         [ +  + ]:        668 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
    1707                 :        520 :                 elt = ucl_object_find_key(cur, "message");
    1708                 :            : 
    1709   [ +  -  -  + ]:        520 :                 if (elt == NULL || ucl_object_type(elt) != UCL_STRING) {
    1710                 :          0 :                         pkg_emit_error("package message lacks 'message' key"
    1711                 :            :                             " that is required");
    1712                 :            : 
    1713                 :          0 :                         return (EPKG_FATAL);
    1714                 :            :                 }
    1715                 :            : 
    1716                 :        520 :                 msg = xcalloc(1, sizeof(*msg));
    1717                 :            : 
    1718                 :        520 :                 msg->str = xstrdup(ucl_object_tostring(elt));
    1719                 :        520 :                 msg->type = PKG_MESSAGE_ALWAYS;
    1720                 :        520 :                 elt = ucl_object_find_key(cur, "type");
    1721   [ +  +  -  + ]:        520 :                 if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
    1722         [ +  + ]:        368 :                         if (strcasecmp(ucl_object_tostring(elt), "install") == 0)
    1723                 :         68 :                                 msg->type = PKG_MESSAGE_INSTALL;
    1724         [ +  + ]:        300 :                         else if (strcasecmp(ucl_object_tostring(elt), "remove") == 0)
    1725                 :         64 :                                 msg->type = PKG_MESSAGE_REMOVE;
    1726         [ -  + ]:        236 :                         else if (strcasecmp(ucl_object_tostring(elt), "upgrade") == 0)
    1727                 :        236 :                                 msg->type = PKG_MESSAGE_UPGRADE;
    1728                 :            :                         else
    1729                 :          0 :                                 pkg_emit_error("Unknown message type,"
    1730                 :            :                                     " message will always be printed");
    1731                 :        368 :                 }
    1732         [ +  + ]:        520 :                 if (msg->type != PKG_MESSAGE_UPGRADE) {
    1733         [ +  + ]:        284 :                         DL_APPEND(pkg->message, msg);
    1734                 :        284 :                         continue;
    1735                 :            :                 }
    1736                 :            : 
    1737                 :        236 :                 elt = ucl_object_find_key(cur, "minimum_version");
    1738   [ +  +  -  + ]:        236 :                 if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
    1739                 :        112 :                         msg->minimum_version = xstrdup(ucl_object_tostring(elt));
    1740                 :        112 :                 }
    1741                 :            : 
    1742                 :        236 :                 elt = ucl_object_find_key(cur, "maximum_version");
    1743   [ +  +  -  + ]:        236 :                 if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
    1744                 :        112 :                         msg->maximum_version = xstrdup(ucl_object_tostring(elt));
    1745                 :        112 :                 }
    1746                 :            : 
    1747         [ +  - ]:        236 :                 DL_APPEND(pkg->message, msg);
    1748                 :            :         }
    1749                 :            : 
    1750                 :        148 :         return (EPKG_OK);
    1751                 :        160 : }
    1752                 :            : 
    1753                 :            : int
    1754                 :         68 : pkg_message_from_str(struct pkg *pkg, const char *str, size_t len)
    1755                 :            : {
    1756                 :            :         struct ucl_parser *parser;
    1757                 :            :         ucl_object_t *obj;
    1758                 :         68 :         int ret = EPKG_FATAL;
    1759                 :            : 
    1760         [ +  - ]:         68 :         assert(str != NULL);
    1761                 :            : 
    1762         [ +  + ]:         68 :         if (len == 0) {
    1763                 :         60 :                 len = strlen(str);
    1764                 :         60 :         }
    1765                 :            : 
    1766                 :         68 :         parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
    1767         [ +  + ]:         68 :         if (pkg->prefix != NULL) {
    1768                 :          8 :                 ucl_parser_register_variable(parser, "PREFIX", pkg->prefix);
    1769                 :          8 :         }
    1770         [ -  + ]:         68 :         if (pkg->name != NULL) {
    1771                 :         68 :                 ucl_parser_register_variable(parser, "PKGNAME", pkg->name);
    1772                 :         68 :         }
    1773         [ -  + ]:         68 :         if (pkg->origin != NULL) {
    1774                 :         68 :                 ucl_parser_register_variable(parser, "PKGORIGIN", pkg->origin);
    1775                 :         68 :         }
    1776         [ +  + ]:         68 :         if (pkg->maintainer != NULL) {
    1777                 :          8 :                 ucl_parser_register_variable(parser, "MAINTAINER", pkg->origin);
    1778                 :          8 :         }
    1779                 :            : 
    1780         [ +  - ]:         68 :         if (ucl_parser_add_chunk(parser, (const unsigned char*)str, len)) {
    1781                 :         68 :                 obj = ucl_parser_get_object(parser);
    1782                 :         68 :                 ucl_parser_free(parser);
    1783                 :            : 
    1784                 :         68 :                 ret = pkg_message_from_ucl(pkg, obj);
    1785                 :         68 :                 ucl_object_unref(obj);
    1786                 :            : 
    1787                 :         68 :                 return (ret);
    1788                 :            :         }
    1789                 :            : 
    1790                 :          0 :         ucl_parser_free (parser);
    1791                 :            : 
    1792                 :          0 :         return (ret);
    1793                 :         68 : }
    1794                 :            : 
    1795                 :            : ucl_object_t*
    1796                 :         88 : pkg_message_to_ucl(const struct pkg *pkg)
    1797                 :            : {
    1798                 :            :         struct pkg_message *msg;
    1799                 :            :         ucl_object_t *array;
    1800                 :            :         ucl_object_t *obj;
    1801                 :            : 
    1802                 :         88 :         array = ucl_object_typed_new(UCL_ARRAY);
    1803         [ +  + ]:        360 :         LL_FOREACH(pkg->message, msg) {
    1804                 :        272 :                 obj = ucl_object_typed_new (UCL_OBJECT);
    1805                 :            : 
    1806                 :        544 :                 ucl_object_insert_key(obj,
    1807                 :        272 :                     ucl_object_fromstring_common(msg->str, 0,
    1808                 :            :                     UCL_STRING_RAW|UCL_STRING_TRIM),
    1809                 :            :                     "message", 0, false);
    1810                 :            : 
    1811   [ -  +  +  +  :        272 :                 switch (msg->type) {
                      + ]
    1812                 :            :                 case PKG_MESSAGE_ALWAYS:
    1813                 :         96 :                         break;
    1814                 :            :                 case PKG_MESSAGE_INSTALL:
    1815                 :         72 :                         ucl_object_insert_key(obj,
    1816                 :         36 :                             ucl_object_fromstring("install"),
    1817                 :            :                             "type", 0, false);
    1818                 :         36 :                         break;
    1819                 :            :                 case PKG_MESSAGE_UPGRADE:
    1820                 :        224 :                         ucl_object_insert_key(obj,
    1821                 :        112 :                             ucl_object_fromstring("upgrade"),
    1822                 :            :                             "type", 0, false);
    1823                 :        112 :                         break;
    1824                 :            :                 case PKG_MESSAGE_REMOVE:
    1825                 :         56 :                         ucl_object_insert_key(obj,
    1826                 :         28 :                             ucl_object_fromstring("remove"),
    1827                 :            :                             "type", 0, false);
    1828                 :         28 :                         break;
    1829                 :            :                 }
    1830         [ +  + ]:        272 :                 if (msg->maximum_version) {
    1831                 :         96 :                         ucl_object_insert_key(obj,
    1832                 :         48 :                             ucl_object_fromstring(msg->maximum_version),
    1833                 :            :                             "maximum_version", 0, false);
    1834                 :         48 :                 }
    1835         [ +  + ]:        272 :                 if (msg->minimum_version) {
    1836                 :         96 :                         ucl_object_insert_key(obj,
    1837                 :         48 :                             ucl_object_fromstring(msg->minimum_version),
    1838                 :            :                             "minimum_version", 0, false);
    1839                 :         48 :                 }
    1840                 :        272 :                 ucl_array_append(array, obj);
    1841                 :        272 :         }
    1842                 :            : 
    1843                 :         88 :         return (array);
    1844                 :            : }
    1845                 :            : 
    1846                 :            : char*
    1847                 :       1080 : pkg_message_to_str(struct pkg *pkg)
    1848                 :            : {
    1849                 :            :         ucl_object_t *obj;
    1850                 :       1080 :         char *ret = NULL;
    1851                 :            : 
    1852         [ +  + ]:       1080 :         if (pkg->message == NULL) {
    1853                 :       1024 :                 return (NULL);
    1854                 :            :         }
    1855                 :            : 
    1856                 :         56 :         obj = pkg_message_to_ucl(pkg);
    1857                 :         56 :         ret = ucl_object_emit(obj, UCL_EMIT_JSON_COMPACT);
    1858                 :         56 :         ucl_object_unref(obj);
    1859                 :            : 
    1860                 :         56 :         return (ret);
    1861                 :       1080 : }

Generated by: LCOV version 1.15