LCOV - code coverage report
Current view: top level - libpkg - pkg_manifest.c (source / functions) Hit Total Coverage
Test: plop Lines: 527 751 70.2 %
Date: 2024-12-28 18:40:32 Functions: 21 22 95.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 270 485 55.7 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2023 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       5                 :            :  * All rights reserved.
       6                 :            :  *
       7                 :            :  * Redistribution and use in source and binary forms, with or without
       8                 :            :  * modification, are permitted provided that the following conditions
       9                 :            :  * are met:
      10                 :            :  * 1. Redistributions of source code must retain the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer
      12                 :            :  *    in this position and unchanged.
      13                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer in the
      15                 :            :  *    documentation and/or other materials provided with the distribution.
      16                 :            :  *
      17                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      18                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      19                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      20                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      21                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      22                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      26                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27                 :            :  */
      28                 :            : 
      29                 :            : #include <sys/types.h>
      30                 :            : #include <stddef.h>
      31                 :            : 
      32                 :            : #include <assert.h>
      33                 :            : #include <ctype.h>
      34                 :            : #include <errno.h>
      35                 :            : #include <stdbool.h>
      36                 :            : #include <stdlib.h>
      37                 :            : #include <string.h>
      38                 :            : #include <fcntl.h>
      39                 :            : #include <ucl.h>
      40                 :            : 
      41                 :            : #include "pkg.h"
      42                 :            : #include "private/event.h"
      43                 :            : #include "private/pkg.h"
      44                 :            : #include "private/utils.h"
      45                 :            : 
      46                 :            : #define dbg(x, ...) pkg_dbg(PKG_DBG_MANIFEST, x, __VA_ARGS__)
      47                 :            : 
      48                 :            : enum {
      49                 :            :         MANIFEST_ANNOTATIONS,
      50                 :            :         MANIFEST_CATEGORIES,
      51                 :            :         MANIFEST_CONFIG_FILES,
      52                 :            :         MANIFEST_CONFLICTS,
      53                 :            :         MANIFEST_DEPS,
      54                 :            :         MANIFEST_DIRECTORIES,
      55                 :            :         MANIFEST_DIRS,
      56                 :            :         MANIFEST_FILES,
      57                 :            :         MANIFEST_GROUPS,
      58                 :            :         MANIFEST_LICENSES,
      59                 :            :         MANIFEST_LUA_SCRIPTS,
      60                 :            :         MANIFEST_OPTIONS,
      61                 :            :         MANIFEST_OPTION_DEFAULTS,
      62                 :            :         MANIFEST_OPTION_DESCRIPTIONS,
      63                 :            :         MANIFEST_PROVIDES,
      64                 :            :         MANIFEST_REQUIRES,
      65                 :            :         MANIFEST_SCRIPTS,
      66                 :            :         MANIFEST_SHLIBS_PROVIDED,
      67                 :            :         MANIFEST_SHLIBS_REQUIRED,
      68                 :            :         MANIFEST_USERS,
      69                 :            : };
      70                 :            : 
      71                 :            : #define PKG_MESSAGE_LEGACY      1
      72                 :            : #define PKG_MESSAGE_NEW 2
      73                 :            : 
      74                 :            : static int pkg_string(struct pkg *, const ucl_object_t *, uint32_t);
      75                 :            : static int pkg_obj(struct pkg *, const ucl_object_t *, uint32_t);
      76                 :            : static int pkg_array(struct pkg *, const ucl_object_t *, uint32_t);
      77                 :            : static int pkg_int(struct pkg *, const ucl_object_t *, uint32_t);
      78                 :            : static int pkg_boolean(struct pkg *, const ucl_object_t *, uint32_t);
      79                 :            : static int pkg_message(struct pkg *, const ucl_object_t *, uint32_t);
      80                 :            : static int pkg_set_deps_from_object(struct pkg *, const ucl_object_t *);
      81                 :            : static int pkg_set_files_from_object(struct pkg *, const ucl_object_t *);
      82                 :            : static int pkg_set_dirs_from_object(struct pkg *, const ucl_object_t *);
      83                 :            : 
      84                 :            : /*
      85                 :            :  * Keep sorted
      86                 :            :  */
      87                 :            : #define TYPE_SHIFT(x) (1 << (x))
      88                 :            : #define STRING_FLAG_LICENSE (1U << 31)
      89                 :            : #define STRING_FLAG_URLDECODE (1U << 30)
      90                 :            : #define STRING_FLAG_MASK ~(STRING_FLAG_LICENSE|STRING_FLAG_URLDECODE)
      91                 :            : 
      92                 :            : static struct pkg_manifest_key {
      93                 :            :         const char *key;
      94                 :            :         uint32_t type;
      95                 :            :         uint16_t valid_type;
      96                 :            :         int (*parse_data)(struct pkg *, const ucl_object_t *, uint32_t);
      97                 :            : } manifest_keys[] = {
      98                 :            :         { "annotations",         MANIFEST_ANNOTATIONS,
      99                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     100                 :            : 
     101                 :            :         { "abi",                 offsetof(struct pkg, abi),
     102                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     103                 :            : 
     104                 :            :         { "arch",                offsetof(struct pkg, altabi),
     105                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     106                 :            : 
     107                 :            :         { "categories",          MANIFEST_CATEGORIES,
     108                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     109                 :            : 
     110                 :            :         { "comment",             offsetof(struct pkg, comment),
     111                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     112                 :            : 
     113                 :            :         { "conflicts",           MANIFEST_CONFLICTS,
     114                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     115                 :            : 
     116                 :            :         { "config",              MANIFEST_CONFIG_FILES,
     117                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     118                 :            : 
     119                 :            :         { "dep_formula",         offsetof(struct pkg, dep_formula),
     120                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     121                 :            : 
     122                 :            :         { "deps",                MANIFEST_DEPS,
     123                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     124                 :            : 
     125                 :            :         { "desc",                offsetof(struct pkg, desc) | STRING_FLAG_URLDECODE,
     126                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     127                 :            : 
     128                 :            :         { "directories",         MANIFEST_DIRECTORIES,
     129                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     130                 :            : 
     131                 :            :         { "dirs",                MANIFEST_DIRS,
     132                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     133                 :            : 
     134                 :            :         { "files",               MANIFEST_FILES,
     135                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     136                 :            : 
     137                 :            :         { "flatsize",            offsetof(struct pkg, flatsize),
     138                 :            :                         TYPE_SHIFT(UCL_INT),    pkg_int},
     139                 :            : 
     140                 :            :         { "groups",              MANIFEST_GROUPS,
     141                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     142                 :            : 
     143                 :            :         { "licenselogic",        offsetof(struct pkg, licenselogic) | STRING_FLAG_LICENSE,
     144                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     145                 :            : 
     146                 :            :         { "licenses",            MANIFEST_LICENSES,
     147                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     148                 :            : 
     149                 :            :         { "lua_scripts",         MANIFEST_LUA_SCRIPTS,
     150                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     151                 :            : 
     152                 :            :         { "maintainer",          offsetof(struct pkg, maintainer),
     153                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     154                 :            : 
     155                 :            :         { "messages",            PKG_MESSAGE_NEW,
     156                 :            :                         TYPE_SHIFT(UCL_STRING)|TYPE_SHIFT(UCL_ARRAY), pkg_message},
     157                 :            : 
     158                 :            :         { "message",             PKG_MESSAGE_LEGACY,
     159                 :            :                         TYPE_SHIFT(UCL_STRING)|TYPE_SHIFT(UCL_ARRAY), pkg_message},
     160                 :            : 
     161                 :            :         { "name",                offsetof(struct pkg, name),
     162                 :            :                         TYPE_SHIFT(UCL_STRING)|TYPE_SHIFT(UCL_INT), pkg_string},
     163                 :            : 
     164                 :            :         { "options",             MANIFEST_OPTIONS,
     165                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     166                 :            : 
     167                 :            :         { "option_defaults",     MANIFEST_OPTION_DEFAULTS,
     168                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     169                 :            : 
     170                 :            :         { "option_descriptions", MANIFEST_OPTION_DESCRIPTIONS,
     171                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     172                 :            : 
     173                 :            :         { "origin",              offsetof(struct pkg, origin),
     174                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     175                 :            : 
     176                 :            :         { "path",                offsetof(struct pkg, repopath),
     177                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     178                 :            : 
     179                 :            :         { "repopath",            offsetof(struct pkg, repopath),
     180                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     181                 :            : 
     182                 :            :         { "pkgsize",             offsetof(struct pkg, pkgsize),
     183                 :            :                         TYPE_SHIFT(UCL_INT),    pkg_int},
     184                 :            : 
     185                 :            :         { "prefix",              offsetof(struct pkg, prefix),
     186                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     187                 :            : 
     188                 :            :         { "provides",            MANIFEST_PROVIDES,
     189                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     190                 :            : 
     191                 :            :         { "requires",            MANIFEST_REQUIRES,
     192                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     193                 :            : 
     194                 :            :         { "scripts",             MANIFEST_SCRIPTS,
     195                 :            :                         TYPE_SHIFT(UCL_OBJECT), pkg_obj},
     196                 :            : 
     197                 :            :         { "shlibs",              MANIFEST_SHLIBS_REQUIRED,
     198                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array}, /* Backwards compat with 1.0.x packages */
     199                 :            : 
     200                 :            :         { "shlibs_provided",     MANIFEST_SHLIBS_PROVIDED,
     201                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     202                 :            : 
     203                 :            :         { "shlibs_required",     MANIFEST_SHLIBS_REQUIRED,
     204                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     205                 :            : 
     206                 :            :         { "sum",                 offsetof(struct pkg, sum),
     207                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     208                 :            : 
     209                 :            :         { "users",               MANIFEST_USERS,
     210                 :            :                         TYPE_SHIFT(UCL_ARRAY),  pkg_array},
     211                 :            : 
     212                 :            :         { "version",             offsetof(struct pkg, version),
     213                 :            :                         TYPE_SHIFT(UCL_STRING)|TYPE_SHIFT(UCL_INT), pkg_string},
     214                 :            : 
     215                 :            :         { "vital",            offsetof(struct pkg, vital),
     216                 :            :                         TYPE_SHIFT(UCL_BOOLEAN),    pkg_boolean},
     217                 :            : 
     218                 :            :         { "www",                 offsetof(struct pkg, www),
     219                 :            :                         TYPE_SHIFT(UCL_STRING), pkg_string},
     220                 :            : 
     221                 :            : };
     222                 :            : 
     223                 :            : static int
     224                 :       1007 : urlencode(const char *src, xstring **dest)
     225                 :            : {
     226                 :            :         size_t len;
     227                 :            :         size_t i;
     228                 :            : 
     229         [ +  + ]:       1007 :         xstring_renew(*dest);
     230                 :            : 
     231                 :       1007 :         len = strlen(src);
     232         [ +  + ]:      19257 :         for (i = 0; i < len; i++) {
     233   [ +  -  -  + ]:      18250 :                 if (!isascii(src[i]) || src[i] == '%')
     234                 :          0 :                         fprintf((*dest)->fp, "%%%.2x", (unsigned char)src[i]);
     235                 :            :                 else
     236                 :      18250 :                         fputc(src[i], (*dest)->fp);
     237                 :      18250 :         }
     238                 :            : 
     239                 :       1007 :         fflush((*dest)->fp);
     240                 :       1007 :         return (EPKG_OK);
     241                 :            : }
     242                 :            : 
     243                 :            : static int
     244                 :       1854 : urldecode(const char *src, xstring **dest)
     245                 :            : {
     246                 :            :         size_t len;
     247                 :            :         size_t i;
     248                 :            :         char c;
     249                 :       1854 :         char hex[] = {'\0', '\0', '\0'};
     250                 :            : 
     251         [ +  + ]:       1854 :         xstring_renew(*dest);
     252                 :            : 
     253                 :       1854 :         len = strlen(src);
     254         [ +  + ]:      45198 :         for (i = 0; i < len; i++) {
     255         [ +  - ]:      43344 :                 if (src[i] != '%') {
     256                 :      43344 :                         fputc(src[i], (*dest)->fp);
     257                 :      43344 :                 } else {
     258         [ #  # ]:          0 :                         if (i + 2 > len) {
     259                 :          0 :                                 pkg_emit_error("unexpected end of string");
     260                 :          0 :                                 return (EPKG_FATAL);
     261                 :            :                         }
     262                 :            : 
     263                 :          0 :                         hex[0] = src[++i];
     264                 :          0 :                         hex[1] = src[++i];
     265                 :          0 :                         errno = 0;
     266                 :          0 :                         c = strtol(hex, NULL, 16);
     267         [ #  # ]:          0 :                         if (errno != 0) {
     268                 :            :                                 /*
     269                 :            :                                  * if it fails consider this is not a urlencoded
     270                 :            :                                  * information
     271                 :            :                                  */
     272                 :          0 :                                 fprintf((*dest)->fp, "%%%s", hex);
     273                 :          0 :                         } else {
     274                 :          0 :                                 fputc(c,(*dest)->fp);
     275                 :            :                         }
     276                 :            :                 }
     277                 :      43344 :         }
     278                 :            : 
     279                 :       1854 :         fflush((*dest)->fp);
     280                 :       1854 :         return (EPKG_OK);
     281                 :       1854 : }
     282                 :            : 
     283                 :            : static int
     284                 :         64 : lua_script_type_str(const char *str)
     285                 :            : {
     286         [ +  - ]:         64 :         if (STREQ(str, "pre-install"))
     287                 :          0 :                 return (PKG_LUA_PRE_INSTALL);
     288         [ -  + ]:         64 :         if (STREQ(str, "post-install"))
     289                 :         64 :                 return (PKG_LUA_POST_INSTALL);
     290         [ #  # ]:          0 :         if (STREQ(str, "pre-deinstall"))
     291                 :          0 :                 return (PKG_LUA_PRE_DEINSTALL);
     292         [ #  # ]:          0 :         if (STREQ(str, "post-deinstall"))
     293                 :          0 :                 return (PKG_LUA_POST_DEINSTALL);
     294                 :          0 :         return (PKG_LUA_UNKNOWN);
     295                 :         64 : }
     296                 :            : 
     297                 :            : static int
     298                 :         80 : script_type_str(const char *str)
     299                 :            : {
     300         [ +  + ]:         80 :         if (STREQ(str, "pre-install"))
     301                 :         20 :                 return (PKG_SCRIPT_PRE_INSTALL);
     302         [ +  - ]:         60 :         if (STREQ(str, "install"))
     303                 :          0 :                 return (PKG_SCRIPT_INSTALL);
     304         [ +  + ]:         60 :         if (STREQ(str, "post-install"))
     305                 :         45 :                 return (PKG_SCRIPT_POST_INSTALL);
     306         [ +  + ]:         15 :         if (STREQ(str, "pre-deinstall"))
     307                 :          4 :                 return (PKG_SCRIPT_PRE_DEINSTALL);
     308         [ +  - ]:         11 :         if (STREQ(str, "deinstall"))
     309                 :          0 :                 return (PKG_SCRIPT_DEINSTALL);
     310         [ -  + ]:         11 :         if (STREQ(str, "post-deinstall"))
     311                 :         11 :                 return (PKG_SCRIPT_POST_DEINSTALL);
     312                 :          0 :         return (PKG_SCRIPT_UNKNOWN);
     313                 :         80 : }
     314                 :            : 
     315                 :            : static int
     316                 :      10608 : pkg_string(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)
     317                 :            : {
     318                 :            :         const char *str;
     319                 :            :         char **dest;
     320                 :      10608 :         xstring *buf = NULL;
     321                 :            : 
     322                 :      10608 :         str = ucl_object_tostring_forced(obj);
     323                 :            : 
     324         [ +  + ]:      10608 :         if (offset & STRING_FLAG_LICENSE) {
     325         [ -  + ]:          8 :                 if (STREQ(str, "single"))
     326                 :          8 :                         pkg->licenselogic = LICENSE_SINGLE;
     327   [ #  #  #  # ]:          0 :                 else if (STREQ(str, "or") ||
     328                 :          0 :                                 STREQ(str, "dual"))
     329                 :          0 :                         pkg->licenselogic = LICENSE_OR;
     330   [ #  #  #  # ]:          0 :                 else if (STREQ(str, "and") ||
     331                 :          0 :                                 STREQ(str, "multi"))
     332                 :          0 :                         pkg->licenselogic = LICENSE_AND;
     333                 :            :                 else {
     334                 :          0 :                         pkg_emit_error("Unknown license logic: %s", str);
     335                 :          0 :                         return (EPKG_FATAL);
     336                 :            :                 }
     337                 :          8 :         }
     338                 :            :         else {
     339                 :            : 
     340         [ +  + ]:      10600 :                 if (offset & STRING_FLAG_URLDECODE) {
     341                 :       1076 :                         urldecode(str, &buf);
     342                 :       1076 :                         str = buf->buf;
     343                 :       1076 :                 }
     344                 :            : 
     345                 :            :                 /* Remove flags from the offset */
     346                 :      10600 :                 offset &= STRING_FLAG_MASK;
     347                 :      10600 :                 dest = (char **) ((unsigned char *)pkg + offset);
     348                 :      10600 :                 *dest = xstrdup(str);
     349                 :            : 
     350                 :      10600 :                 xstring_free(buf);
     351                 :            :         }
     352                 :            : 
     353                 :      10608 :         return (EPKG_OK);
     354                 :      10608 : }
     355                 :            : 
     356                 :            : static int
     357                 :        876 : pkg_int(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)
     358                 :            : {
     359                 :            :         int64_t *dest;
     360                 :            : 
     361                 :        876 :         dest = (int64_t *)((unsigned char *)pkg + offset);
     362                 :        876 :         *dest = ucl_object_toint(obj);
     363                 :            : 
     364                 :        876 :         return (EPKG_OK);
     365                 :            : }
     366                 :            : 
     367                 :            : static int
     368                 :          9 : pkg_boolean(struct pkg *pkg, const ucl_object_t *obj, uint32_t offset)
     369                 :            : {
     370                 :            :         bool *dest;
     371                 :            : 
     372                 :          9 :         dest = (bool *)((unsigned char *)pkg + offset);
     373                 :          9 :         *dest = ucl_object_toboolean(obj);
     374                 :            : 
     375                 :          9 :         return (EPKG_OK);
     376                 :            : }
     377                 :            : 
     378                 :            : static int
     379                 :       1211 : pkg_array(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
     380                 :            : {
     381                 :            :         const ucl_object_t *cur;
     382                 :       1211 :         ucl_object_iter_t it = NULL;
     383                 :            :         int ret;
     384                 :            : 
     385                 :       1211 :         dbg(3, "%s", "parsing array");
     386         [ +  + ]:       2435 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     387   [ +  +  +  -  :       1225 :                 switch (attr) {
          -  -  +  +  -  
                +  +  + ]
     388                 :            :                 case MANIFEST_CATEGORIES:
     389         [ -  + ]:       1050 :                         if (cur->type != UCL_STRING)
     390                 :          0 :                                 pkg_emit_error("Skipping malformed category");
     391                 :            :                         else
     392                 :       2100 :                                 pkg_addstring(&pkg->categories,
     393                 :       1050 :                                     ucl_object_tostring(cur), "category");
     394                 :       1050 :                         break;
     395                 :            :                 case MANIFEST_LICENSES:
     396         [ -  + ]:          4 :                         if (cur->type != UCL_STRING)
     397                 :          0 :                                 pkg_emit_error("Skipping malformed license");
     398                 :            :                         else
     399                 :          8 :                                 pkg_addstring(&pkg->licenses,
     400                 :          4 :                                     ucl_object_tostring(cur), "license");
     401                 :          4 :                         break;
     402                 :            :                 case MANIFEST_USERS:
     403         [ #  # ]:          0 :                         if (cur->type == UCL_STRING)
     404                 :          0 :                                 pkg_adduser(pkg, ucl_object_tostring(cur));
     405         [ #  # ]:          0 :                         else if (cur->type == UCL_OBJECT)
     406                 :          0 :                                 pkg_obj(pkg, cur, attr);
     407                 :            :                         else
     408                 :          0 :                                 pkg_emit_error("Skipping malformed license");
     409                 :          0 :                         break;
     410                 :            :                 case MANIFEST_GROUPS:
     411         [ #  # ]:          0 :                         if (cur->type == UCL_STRING)
     412                 :          0 :                                 pkg_addgroup(pkg, ucl_object_tostring(cur));
     413         [ #  # ]:          0 :                         else if (cur->type == UCL_OBJECT)
     414                 :          0 :                                 pkg_obj(pkg, cur, attr);
     415                 :            :                         else
     416                 :          0 :                                 pkg_emit_error("Skipping malformed license");
     417                 :          0 :                         break;
     418                 :            :                 case MANIFEST_DIRS:
     419         [ #  # ]:          0 :                         if (cur->type == UCL_STRING)
     420                 :          0 :                                 pkg_adddir(pkg, ucl_object_tostring(cur), false);
     421         [ #  # ]:          0 :                         else if (cur->type == UCL_OBJECT)
     422                 :          0 :                                 pkg_obj(pkg, cur, attr);
     423                 :            :                         else
     424                 :          0 :                                 pkg_emit_error("Skipping malformed dirs");
     425                 :          0 :                         break;
     426                 :            :                 case MANIFEST_SHLIBS_REQUIRED:
     427         [ -  + ]:         54 :                         if (cur->type != UCL_STRING)
     428                 :          0 :                                 pkg_emit_error("Skipping malformed required shared library");
     429                 :            :                         else
     430                 :         54 :                                 pkg_addshlib_required(pkg, ucl_object_tostring(cur), PKG_SHLIB_FLAGS_NONE);
     431                 :         54 :                         break;
     432                 :            :                 case MANIFEST_SHLIBS_PROVIDED:
     433         [ -  + ]:         28 :                         if (cur->type != UCL_STRING)
     434                 :          0 :                                 pkg_emit_error("Skipping malformed provided shared library");
     435                 :            :                         else
     436                 :         28 :                                 pkg_addshlib_provided(pkg, ucl_object_tostring(cur), PKG_SHLIB_FLAGS_NONE);
     437                 :         28 :                         break;
     438                 :            :                 case MANIFEST_CONFLICTS:
     439         [ #  # ]:          0 :                         if (cur->type != UCL_STRING)
     440                 :          0 :                                 pkg_emit_error("Skipping malformed conflict name");
     441                 :            :                         else
     442                 :          0 :                                 pkg_addconflict(pkg, ucl_object_tostring(cur));
     443                 :          0 :                         break;
     444                 :            :                 case MANIFEST_PROVIDES:
     445         [ -  + ]:         22 :                         if (cur->type != UCL_STRING)
     446                 :          0 :                                 pkg_emit_error("Skipping malformed provide name");
     447                 :            :                         else
     448                 :         22 :                                 pkg_addprovide(pkg, ucl_object_tostring(cur));
     449                 :         22 :                         break;
     450                 :            :                 case MANIFEST_CONFIG_FILES:
     451         [ -  + ]:         31 :                         if (cur->type != UCL_STRING)
     452                 :          0 :                                 pkg_emit_error("Skipping malformed config file name");
     453                 :            :                         else {
     454                 :         31 :                                 ret = pkg_addconfig_file(pkg, ucl_object_tostring(cur), NULL);
     455         [ +  + ]:         31 :                                 if (ret != EPKG_OK)
     456                 :          1 :                                         return (ret);
     457                 :            :                         }
     458                 :         30 :                         break;
     459                 :            :                 case MANIFEST_REQUIRES:
     460         [ -  + ]:         35 :                         if (cur->type != UCL_STRING)
     461                 :          0 :                                 pkg_emit_error("Skipping malformed require name");
     462                 :            :                         else
     463                 :         35 :                                 pkg_addrequire(pkg, ucl_object_tostring(cur));
     464                 :         35 :                         break;
     465                 :            :                 }
     466                 :            :         }
     467                 :            : 
     468                 :       1208 :         return (EPKG_OK);
     469                 :       1209 : }
     470                 :            : 
     471                 :            : static int
     472                 :       1330 : pkg_obj(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr)
     473                 :            : {
     474                 :       1330 :         xstring *tmp = NULL;
     475                 :            :         const ucl_object_t *cur;
     476                 :       1330 :         ucl_object_iter_t it = NULL;
     477                 :            :         pkg_script script_type;
     478                 :            :         pkg_lua_script lua_script_type;
     479                 :            :         const char *key, *buf;
     480                 :            :         size_t len;
     481                 :            : 
     482                 :       1330 :         dbg(3, "%s", "parsing object");
     483         [ +  + ]:       3096 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     484                 :       1766 :                 key = ucl_object_key(cur);
     485         [ +  - ]:       1766 :                 if (key == NULL)
     486                 :          0 :                         continue;
     487   [ +  +  -  +  :       1766 :                 switch (attr) {
          +  +  -  -  +  
                   +  + ]
     488                 :            :                 case MANIFEST_DEPS:
     489   [ -  +  #  # ]:        299 :                         if (cur->type != UCL_OBJECT && cur->type != UCL_ARRAY)
     490                 :          0 :                                 pkg_emit_error("Skipping malformed dependency %s",
     491                 :          0 :                                     key);
     492                 :            :                         else
     493                 :        299 :                                 pkg_set_deps_from_object(pkg, cur);
     494                 :        299 :                         break;
     495                 :            :                 case MANIFEST_DIRS:
     496         [ #  # ]:          0 :                         if (cur->type != UCL_OBJECT)
     497                 :          0 :                                 pkg_emit_error("Skipping malformed dirs %s",
     498                 :          0 :                                     key);
     499                 :            :                         else
     500                 :          0 :                                 pkg_set_dirs_from_object(pkg, cur);
     501                 :          0 :                         break;
     502                 :            :                 case MANIFEST_DIRECTORIES:
     503         [ -  + ]:         32 :                         if (cur->type == UCL_BOOLEAN) {
     504                 :          0 :                                 urldecode(key, &tmp);
     505                 :          0 :                                 pkg_adddir(pkg, tmp->buf, false);
     506         [ +  - ]:         32 :                         } else if (cur->type == UCL_OBJECT) {
     507                 :          0 :                                 pkg_set_dirs_from_object(pkg, cur);
     508         [ +  - ]:         32 :                         } else if (cur->type == UCL_STRING) {
     509                 :         32 :                                 urldecode(key, &tmp);
     510                 :         32 :                                 pkg_adddir(pkg, tmp->buf, false);
     511                 :         32 :                         } else {
     512                 :          0 :                                 pkg_emit_error("Skipping malformed directories %s",
     513                 :          0 :                                     key);
     514                 :            :                         }
     515                 :         32 :                         break;
     516                 :            :                 case MANIFEST_FILES:
     517         [ +  + ]:        666 :                         if (cur->type == UCL_STRING) {
     518                 :        643 :                                 buf = ucl_object_tolstring(cur, &len);
     519                 :        643 :                                 urldecode(key, &tmp);
     520         [ +  + ]:        643 :                                 pkg_addfile(pkg, tmp->buf, len >= 2 ? buf : NULL, false);
     521         [ -  + ]:        666 :                         } else if (cur->type == UCL_OBJECT)
     522                 :         23 :                                 pkg_set_files_from_object(pkg, cur);
     523                 :            :                         else
     524                 :          0 :                                 pkg_emit_error("Skipping malformed files %s",
     525                 :          0 :                                    key);
     526                 :        666 :                         break;
     527                 :            :                 case MANIFEST_OPTIONS:
     528   [ -  +  #  # ]:        134 :                         if (cur->type != UCL_STRING && cur->type != UCL_BOOLEAN)
     529                 :          0 :                                 pkg_emit_error("Skipping malformed option %s",
     530                 :          0 :                                     key);
     531         [ +  - ]:        134 :                         else if (cur->type == UCL_STRING) {
     532                 :        134 :                                 pkg_addoption(pkg, key, ucl_object_tostring(cur));
     533                 :        134 :                         } else {
     534                 :          0 :                                 pkg_addoption(pkg, key, ucl_object_toboolean(cur) ? "on" : "off");
     535                 :            :                         }
     536                 :        134 :                         break;
     537                 :            :                 case MANIFEST_OPTION_DEFAULTS:
     538         [ #  # ]:          0 :                         if (cur->type != UCL_STRING)
     539                 :          0 :                                 pkg_emit_error("Skipping malformed option default %s",
     540                 :          0 :                                     key);
     541                 :            :                         else
     542                 :          0 :                                 pkg_addoption_default(pkg, key,
     543                 :          0 :                                     ucl_object_tostring(cur));
     544                 :          0 :                         break;
     545                 :            :                 case MANIFEST_OPTION_DESCRIPTIONS:
     546         [ #  # ]:          0 :                         if (cur->type != UCL_STRING)
     547                 :          0 :                                 pkg_emit_error("Skipping malformed option description %s",
     548                 :          0 :                                     key);
     549                 :            :                         else
     550                 :          0 :                                 pkg_addoption_description(pkg, key,
     551                 :          0 :                                     ucl_object_tostring(cur));
     552                 :          0 :                         break;
     553                 :            :                 case MANIFEST_SCRIPTS:
     554         [ -  + ]:         80 :                         if (cur->type != UCL_STRING)
     555                 :          0 :                                 pkg_emit_error("Skipping malformed scripts %s",
     556                 :          0 :                                     key);
     557                 :            :                         else {
     558                 :         80 :                                 script_type = script_type_str(key);
     559         [ -  + ]:         80 :                                 if (script_type == PKG_SCRIPT_UNKNOWN) {
     560                 :          0 :                                         pkg_emit_error("Skipping unknown script "
     561                 :          0 :                                             "type: %s", key);
     562                 :          0 :                                         break;
     563                 :            :                                 }
     564                 :            : 
     565                 :         80 :                                 urldecode(ucl_object_tostring(cur), &tmp);
     566                 :         80 :                                 pkg_addscript(pkg, tmp->buf, script_type);
     567                 :            :                         }
     568                 :         80 :                         break;
     569                 :            :                 case MANIFEST_LUA_SCRIPTS:
     570         [ -  + ]:         64 :                         if (cur->type != UCL_ARRAY) {
     571                 :          0 :                                 pkg_emit_error("Skipping malformed dependency %s",
     572                 :          0 :                                     key);
     573                 :          0 :                                 break;
     574                 :            :                         }
     575                 :         64 :                         lua_script_type = lua_script_type_str(key);
     576         [ -  + ]:         64 :                         if (lua_script_type == PKG_LUA_UNKNOWN) {
     577                 :          0 :                                 pkg_emit_error("Skipping unknown script "
     578                 :          0 :                                     "type: %s", key);
     579                 :          0 :                                 break;
     580                 :            :                         }
     581                 :         64 :                         pkg_lua_script_from_ucl(pkg, cur, lua_script_type);
     582                 :         64 :                         break;
     583                 :            :                 case MANIFEST_ANNOTATIONS:
     584         [ -  + ]:        487 :                         if (cur->type != UCL_STRING)
     585                 :          0 :                                 pkg_emit_error("Skipping malformed annotation %s",
     586                 :          0 :                                     key);
     587                 :            :                         else
     588                 :        487 :                                 pkg_kv_add(&pkg->annotations, key, ucl_object_tostring(cur), "annotation");
     589                 :        487 :                         break;
     590                 :            :                 }
     591                 :            :         }
     592                 :            : 
     593                 :       1330 :         xstring_free(tmp);
     594                 :            : 
     595                 :       1330 :         return (EPKG_OK);
     596                 :            : }
     597                 :            : 
     598                 :            : static int
     599                 :         21 : pkg_message(struct pkg *pkg, const ucl_object_t *obj, uint32_t attr __unused)
     600                 :            : {
     601                 :         21 :         return pkg_message_from_ucl(pkg, obj);
     602                 :            : }
     603                 :            : 
     604                 :            : static int
     605                 :         23 : pkg_set_files_from_object(struct pkg *pkg, const ucl_object_t *obj)
     606                 :            : {
     607                 :            :         const ucl_object_t *cur;
     608                 :         23 :         ucl_object_iter_t it = NULL;
     609                 :         23 :         const char *sum = NULL;
     610                 :         23 :         const char *uname = NULL;
     611                 :         23 :         const char *gname = NULL;
     612                 :         23 :         mode_t perm = 0;
     613                 :         23 :         xstring *fname = NULL;
     614                 :            :         const char *key, *okey;
     615                 :            : 
     616                 :         23 :         okey = ucl_object_key(obj);
     617         [ +  - ]:         23 :         if (okey == NULL)
     618                 :          0 :                 return (EPKG_FATAL);
     619                 :         23 :         urldecode(okey, &fname);
     620         [ +  + ]:         46 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     621                 :         23 :                 key = ucl_object_key(cur);
     622         [ +  - ]:         23 :                 if (key == NULL)
     623                 :          0 :                         continue;
     624   [ -  +  #  # ]:         23 :                 if (STRIEQ(key, "uname") && cur->type == UCL_STRING)
     625                 :          0 :                         uname = ucl_object_tostring(cur);
     626   [ -  +  #  # ]:         23 :                 else if (STRIEQ(key, "gname") && cur->type == UCL_STRING)
     627                 :          0 :                         gname = ucl_object_tostring(cur);
     628   [ -  +  #  #  :         23 :                 else if (STRIEQ(key, "sum") && cur->type == UCL_STRING &&
                   #  # ]
     629                 :          0 :                          strlen(ucl_object_tostring(cur)) == 64)
     630                 :          0 :                         sum = ucl_object_tostring(cur);
     631   [ -  +  +  - ]:         46 :                 else if (STRIEQ(key, "perm") &&
     632         [ +  - ]:         23 :                          (cur->type == UCL_STRING || cur->type == UCL_INT)) {
     633                 :         23 :                         void *set = 0;
     634         [ +  - ]:         23 :                         if ((set = setmode(ucl_object_tostring_forced(cur))) == NULL)
     635                 :          0 :                                 pkg_emit_error("Not a valid mode: %s",
     636                 :          0 :                                     ucl_object_tostring(cur));
     637                 :            :                         else
     638                 :         23 :                                 perm = getmode(set, 0);
     639                 :         23 :                         free(set);
     640                 :         23 :                 } else {
     641                 :          0 :                         dbg(1, "Skipping unknown key for file(%s): %s",
     642                 :            :                             fname->buf, key);
     643                 :            :                 }
     644                 :            :         }
     645                 :            : 
     646                 :         23 :         pkg_addfile_attr(pkg, fname->buf, sum, uname, gname, perm, 0,
     647                 :            :             false);
     648                 :         23 :         xstring_free(fname);
     649                 :            : 
     650                 :         23 :         return (EPKG_OK);
     651                 :         23 : }
     652                 :            : 
     653                 :            : static int
     654                 :          0 : pkg_set_dirs_from_object(struct pkg *pkg, const ucl_object_t *obj)
     655                 :            : {
     656                 :            :         const ucl_object_t *cur;
     657                 :          0 :         ucl_object_iter_t it = NULL;
     658                 :          0 :         const char *uname = NULL;
     659                 :          0 :         const char *gname = NULL;
     660                 :          0 :         mode_t perm = 0;
     661                 :          0 :         xstring *dirname = NULL;
     662                 :            :         const char *key, *okey;
     663                 :            : 
     664                 :          0 :         okey = ucl_object_key(obj);
     665         [ #  # ]:          0 :         if (okey == NULL)
     666                 :          0 :                 return (EPKG_FATAL);
     667                 :          0 :         urldecode(okey, &dirname);
     668         [ #  # ]:          0 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     669                 :          0 :                 key = ucl_object_key(cur);
     670         [ #  # ]:          0 :                 if (key == NULL)
     671                 :          0 :                         continue;
     672   [ #  #  #  # ]:          0 :                 if (STRIEQ(key, "uname") && cur->type == UCL_STRING)
     673                 :          0 :                         uname = ucl_object_tostring(cur);
     674   [ #  #  #  # ]:          0 :                 else if (STRIEQ(key, "gname") && cur->type == UCL_STRING)
     675                 :          0 :                         gname = ucl_object_tostring(cur);
     676   [ #  #  #  # ]:          0 :                 else if (STRIEQ(key, "perm") &&
     677         [ #  # ]:          0 :                          (cur->type == UCL_STRING || cur->type == UCL_INT)) {
     678                 :          0 :                         void *set = 0;
     679         [ #  # ]:          0 :                         if ((set = setmode(ucl_object_tostring_forced(cur))) == NULL)
     680                 :          0 :                                 pkg_emit_error("Not a valid mode: %s",
     681                 :          0 :                                     ucl_object_tostring(cur));
     682                 :            :                         else
     683                 :          0 :                                 perm = getmode(set, 0);
     684                 :          0 :                         free(set);
     685   [ #  #  #  # ]:          0 :                 } else if (STRIEQ(key, "try") && cur->type == UCL_BOOLEAN) {
     686                 :            :                         /* ignore on purpose : compatibility*/
     687                 :          0 :                 } else {
     688                 :          0 :                         dbg(1, "Skipping unknown key for dir(%s): %s",
     689                 :            :                             dirname->buf, key);
     690                 :            :                 }
     691                 :            :         }
     692                 :            : 
     693                 :          0 :         pkg_adddir_attr(pkg, dirname->buf, uname, gname, perm, 0, false);
     694                 :          0 :         xstring_free(dirname);
     695                 :            : 
     696                 :          0 :         return (EPKG_OK);
     697                 :          0 : }
     698                 :            : 
     699                 :            : static int
     700                 :        297 : pkg_set_deps_from_object(struct pkg *pkg, const ucl_object_t *obj)
     701                 :            : {
     702                 :            :         const ucl_object_t *cur, *self;
     703                 :        297 :         ucl_object_iter_t it = NULL, it2;
     704                 :        297 :         const char *origin = NULL;
     705                 :        297 :         const char *version = NULL;
     706                 :            :         const char *key, *okey;
     707                 :        297 :         bool noversion = false;
     708                 :            : 
     709                 :        297 :         noversion = (getenv("PKG_NO_VERSION_FOR_DEPS") != NULL);
     710                 :        297 :         okey = ucl_object_key(obj);
     711         [ +  - ]:        297 :         if (okey == NULL)
     712                 :          0 :                 return (EPKG_FATAL);
     713                 :        297 :         dbg(2, "Found %s", okey);
     714         [ +  + ]:        595 :         while ((self = ucl_iterate_object(obj, &it, (obj->type == UCL_ARRAY)))) {
     715                 :        296 :                 it2 = NULL;
     716         [ +  + ]:        887 :                 while ((cur = ucl_iterate_object(self, &it2, true))) {
     717                 :        589 :                         key = ucl_object_key(cur);
     718         [ +  - ]:        589 :                         if (key == NULL)
     719                 :          0 :                                 continue;
     720         [ +  + ]:        589 :                         if (cur->type != UCL_STRING) {
     721                 :            :                                 /* accept version to be an integer */
     722   [ +  -  -  + ]:         13 :                                 if (cur->type == UCL_INT && STRIEQ(key, "version")) {
     723         [ -  + ]:         13 :                                         if (!noversion)
     724                 :         13 :                                                 version = ucl_object_tostring_forced(cur);
     725                 :         13 :                                         continue;
     726                 :            :                                 }
     727                 :            : 
     728                 :          0 :                                 pkg_emit_error("Skipping malformed dependency entry "
     729                 :          0 :                                                 "for %s", okey);
     730                 :          0 :                                 continue;
     731                 :            :                         }
     732         [ +  + ]:        576 :                         if (STRIEQ(key, "origin"))
     733                 :        298 :                                 origin = ucl_object_tostring(cur);
     734   [ +  +  +  + ]:        576 :                         if (STRIEQ(key, "version") && !noversion)
     735                 :        280 :                                 version = ucl_object_tostring(cur);
     736                 :            :                 }
     737         [ +  - ]:        298 :                 if (origin != NULL)
     738                 :        298 :                         pkg_adddep(pkg, okey, origin, version, false);
     739                 :            :                 else
     740                 :          0 :                         pkg_emit_error("Skipping malformed dependency %s", okey);
     741                 :            :         }
     742                 :            : 
     743                 :        299 :         return (EPKG_OK);
     744                 :        299 : }
     745                 :            : 
     746                 :            : static struct pkg_manifest_key *
     747                 :      28011 : select_manifest_key(const char *key)
     748                 :            : {
     749         [ +  + ]:     516789 :         for (int i = 0; i < NELEM(manifest_keys); i++)
     750         [ +  + ]:     516787 :                 if (STREQ(manifest_keys[i].key, key))
     751                 :      28009 :                         return (&(manifest_keys[i]));
     752                 :          2 :         return (NULL);
     753                 :      28011 : }
     754                 :            : static int
     755                 :       1076 : parse_manifest(struct pkg *pkg, ucl_object_t *obj)
     756                 :            : {
     757                 :            :         const ucl_object_t *cur;
     758                 :       1076 :         ucl_object_iter_t it = NULL;
     759                 :       1076 :         struct pkg_manifest_key *selected_key = NULL;
     760                 :            :         const char *key;
     761                 :       1076 :         int ret = EPKG_OK;
     762                 :            : 
     763         [ +  + ]:      15172 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     764                 :      14097 :                 key = ucl_object_key(cur);
     765         [ +  - ]:      14097 :                 if (key == NULL)
     766                 :          0 :                         continue;
     767                 :      14097 :                 dbg(3, "found key: '%s'", key);
     768         [ +  + ]:      14097 :                 if ((selected_key = select_manifest_key(key)) == NULL) {
     769                 :          1 :                         dbg(1, "Skipping unknown key '%s'", key);
     770                 :          1 :                         continue;
     771                 :            :                 }
     772         [ +  - ]:      14096 :                 if (TYPE_SHIFT(ucl_object_type(cur)) & selected_key->valid_type) {
     773                 :      14096 :                         ret = selected_key->parse_data(pkg, cur, selected_key->type);
     774         [ +  + ]:      14096 :                         if (ret != EPKG_OK)
     775                 :          1 :                                 return (ret);
     776                 :      14095 :                 } else {
     777                 :          0 :                         pkg_emit_error("Skipping malformed key '%s'", key);
     778                 :            :                 }
     779                 :            :         }
     780                 :            : 
     781                 :       1075 :         return (EPKG_OK);
     782                 :       1076 : }
     783                 :            : 
     784                 :            : int
     785                 :       1075 : pkg_parse_manifest_ucl(struct pkg *pkg, ucl_object_t *obj)
     786                 :            : {
     787                 :            :         const ucl_object_t *cur;
     788                 :       1075 :         ucl_object_iter_t it = NULL;
     789                 :       1075 :         struct pkg_manifest_key *sk = NULL;
     790                 :            :         const char *key;
     791                 :            : 
     792                 :            :         /* do a minimal validation */
     793         [ +  + ]:      15109 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     794                 :      14035 :                 key = ucl_object_key(cur);
     795         [ +  - ]:      14035 :                 if (key == NULL)
     796                 :          0 :                         continue;
     797         [ +  + ]:      14035 :                 if ((sk = select_manifest_key(key)) == NULL)
     798                 :          1 :                         continue;
     799         [ +  + ]:      14034 :                 if (!(sk->valid_type & TYPE_SHIFT(ucl_object_type(cur)))) {
     800                 :          1 :                         pkg_emit_error("Bad format in manifest for key:"
     801                 :          1 :                                 " %s", key);
     802                 :          1 :                         UCL_FREE (sizeof (*it), it);
     803                 :          1 :                         return (EPKG_FATAL);
     804                 :            :                 }
     805                 :            :         }
     806                 :            : 
     807                 :       1074 :         return (parse_manifest(pkg, obj));
     808                 :       1075 : }
     809                 :            : 
     810                 :            : int
     811                 :        568 : pkg_parse_manifest(struct pkg *pkg, const char *buf, size_t len)
     812                 :            : {
     813                 :        568 :         struct ucl_parser *p = NULL;
     814                 :        568 :         ucl_object_t *obj = NULL;
     815                 :            :         int rc;
     816                 :            : 
     817         [ +  - ]:        568 :         assert(pkg != NULL);
     818         [ +  - ]:        568 :         assert(buf != NULL);
     819                 :            : 
     820                 :        568 :         dbg(2, "%s", "Parsing from buffer");
     821                 :            : 
     822                 :        568 :         p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
     823         [ +  - ]:        568 :         if (!ucl_parser_add_chunk(p, buf, len)) {
     824                 :          0 :                 pkg_emit_error("Error parsing manifest: %s",
     825                 :          0 :                     ucl_parser_get_error(p));
     826                 :          0 :                 ucl_parser_free(p);
     827                 :            : 
     828                 :          0 :                 return (EPKG_FATAL);
     829                 :            :         }
     830                 :            : 
     831         [ +  - ]:        568 :         if ((obj = ucl_parser_get_object(p)) == NULL) {
     832                 :          0 :                 ucl_parser_free(p);
     833                 :          0 :                 return (EPKG_FATAL);
     834                 :            :         }
     835                 :            : 
     836                 :        568 :         ucl_parser_free(p);
     837                 :        568 :         rc = pkg_parse_manifest_ucl(pkg, obj);
     838                 :        568 :         ucl_object_unref(obj);
     839                 :            : 
     840                 :        568 :         return (rc);
     841                 :        568 : }
     842                 :            : 
     843                 :            : int
     844                 :        359 : pkg_parse_manifest_fileat(int dfd, struct pkg *pkg, const char *file)
     845                 :            : {
     846                 :        359 :         struct ucl_parser *p = NULL;
     847                 :        359 :         ucl_object_t *obj = NULL;
     848                 :            :         int rc;
     849                 :            :         char *data;
     850                 :        359 :         off_t sz = 0;
     851                 :            : 
     852         [ +  - ]:        359 :         assert(pkg != NULL);
     853         [ +  - ]:        359 :         assert(file != NULL);
     854                 :            : 
     855                 :        359 :         dbg(1, "Parsing from '%s'", file);
     856                 :            : 
     857                 :        359 :         errno = 0;
     858                 :            : 
     859         [ -  + ]:        359 :         if (file_to_bufferat(dfd, file, &data, &sz) != EPKG_OK)
     860                 :          0 :                 return (EPKG_FATAL);
     861                 :            : 
     862                 :        359 :         p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
     863         [ +  - ]:        359 :         if (!ucl_parser_add_string(p, data, sz)) {
     864                 :          0 :                 pkg_emit_error("manifest parsing error: %s", ucl_parser_get_error(p));
     865                 :          0 :                 ucl_parser_free(p);
     866                 :          0 :                 free(data);
     867                 :          0 :                 return (EPKG_FATAL);
     868                 :            :         }
     869                 :            : 
     870         [ +  - ]:        359 :         if ((obj = ucl_parser_get_object(p)) == NULL) {
     871                 :          0 :                 ucl_parser_free(p);
     872                 :          0 :                 free(data);
     873                 :          0 :                 return (EPKG_FATAL);
     874                 :            :         }
     875                 :        359 :         ucl_parser_free(p);
     876                 :            : 
     877                 :        359 :         rc = pkg_parse_manifest_ucl(pkg, obj);
     878                 :        359 :         ucl_object_unref(obj);
     879                 :        359 :         free(data);
     880                 :            : 
     881                 :        359 :         return (rc);
     882                 :        359 : }
     883                 :            : 
     884                 :            : int
     885                 :        322 : pkg_parse_manifest_file(struct pkg *pkg, const char *file)
     886                 :            : {
     887                 :        322 :         return pkg_parse_manifest_fileat(AT_FDCWD, pkg, file);
     888                 :            : }
     889                 :            : 
     890                 :            : #define MANIFEST_EXPORT_FIELD(result, o, field, type)   do { \
     891                 :            :         ucl_object_insert_key((result), ucl_object_from ## type (o->field), #field, 0, false); \
     892                 :            :         } while (0)
     893                 :            : 
     894                 :            : int
     895                 :          4 : pkg_emit_filelist(struct pkg *pkg, FILE *f)
     896                 :            : {
     897                 :          4 :         ucl_object_t *obj = NULL, *seq;
     898                 :          4 :         struct pkg_file *file = NULL;
     899                 :          4 :         xstring *b = NULL;
     900                 :            : 
     901                 :          4 :         obj = ucl_object_typed_new(UCL_OBJECT);
     902                 :          4 :         MANIFEST_EXPORT_FIELD(obj, pkg, origin, string);
     903                 :          4 :         MANIFEST_EXPORT_FIELD(obj, pkg, name, string);
     904                 :          4 :         MANIFEST_EXPORT_FIELD(obj, pkg, version, string);
     905                 :            : 
     906                 :          4 :         seq = NULL;
     907         [ +  + ]:          8 :         while (pkg_files(pkg, &file) == EPKG_OK) {
     908                 :            :                 char dpath[MAXPATHLEN];
     909                 :          4 :                 const char *dp = file->path;
     910                 :            : 
     911         [ +  - ]:          4 :                 if (pkg->oprefix != NULL) {
     912                 :          0 :                         size_t l = strlen(pkg->prefix);
     913   [ #  #  #  # ]:          0 :                         if (strncmp(file->path, pkg->prefix, l) == 0 &&
     914         [ #  # ]:          0 :                             (file->path[l] == '/' || l == 1)) {
     915                 :          0 :                                 snprintf(dpath, sizeof(dpath), "%s%s%s",
     916                 :          0 :                                     pkg->oprefix, l == 1 ? "/" : "", file->path + l);
     917                 :          0 :                                 dp = dpath;
     918                 :          0 :                         }
     919                 :          0 :                 }
     920                 :          4 :                 urlencode(dp, &b);
     921         [ -  + ]:          4 :                 if (seq == NULL)
     922                 :          4 :                         seq = ucl_object_typed_new(UCL_ARRAY);
     923                 :          4 :                 ucl_array_append(seq, ucl_object_fromlstring(b->buf, strlen(b->buf)));
     924                 :            :         }
     925         [ -  + ]:          4 :         if (seq != NULL)
     926                 :          4 :                 ucl_object_insert_key(obj, seq, "files", 5, false);
     927                 :            : 
     928                 :          4 :         ucl_object_emit_file(obj, UCL_EMIT_JSON_COMPACT, f);
     929                 :            : 
     930                 :          4 :         xstring_free(b);
     931                 :          4 :         ucl_object_unref(obj);
     932                 :            : 
     933                 :          4 :         return (EPKG_OK);
     934                 :            : }
     935                 :            : 
     936                 :            : pkg_object*
     937                 :        708 : pkg_emit_object(struct pkg *pkg, short flags)
     938                 :            : {
     939                 :            :         struct pkg_kv           *kv;
     940                 :        708 :         struct pkg_dep          *dep      = NULL;
     941                 :        708 :         struct pkg_option       *option   = NULL;
     942                 :        708 :         struct pkg_file         *file     = NULL;
     943                 :        708 :         struct pkg_dir          *dir      = NULL;
     944                 :        708 :         struct pkg_conflict     *conflict = NULL;
     945                 :        708 :         struct pkg_config_file  *cf       = NULL;
     946                 :        708 :         xstring         *tmpsbuf  = NULL;
     947                 :            :         int i;
     948                 :        708 :         const char *script_types = NULL;
     949                 :            :         char legacyarch[BUFSIZ];
     950                 :            :         ucl_object_t *map, *seq, *submap;
     951                 :        708 :         ucl_object_t *top = ucl_object_typed_new(UCL_OBJECT);
     952                 :            : 
     953   [ -  +  #  # ]:        708 :         if (pkg->abi == NULL && pkg->altabi != NULL)
     954                 :          0 :                 pkg->abi = xstrdup(pkg->altabi);
     955                 :        708 :         pkg_arch_to_legacy(pkg->abi, legacyarch, BUFSIZ);
     956                 :        708 :         free(pkg->altabi);
     957                 :        708 :         pkg->altabi = xstrdup(legacyarch);
     958                 :        708 :         dbg(4, "Emitting basic metadata");
     959                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, name, string);
     960                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, origin, string);
     961                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, version, string);
     962                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, comment, string);
     963                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, maintainer, string);
     964                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, www, string);
     965                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, abi, string);
     966                 :            :         /* We need to keep altabi named arch in the manifest */
     967                 :        708 :         ucl_object_insert_key(top, ucl_object_fromstring(pkg->altabi), "arch", 0, false);
     968                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, prefix, string);
     969                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, sum, string);
     970                 :        708 :         MANIFEST_EXPORT_FIELD(top, pkg, flatsize, int);
     971         [ +  - ]:        708 :         if (pkg->dep_formula != NULL)
     972                 :          0 :                 MANIFEST_EXPORT_FIELD(top, pkg, dep_formula, string);
     973   [ -  +  #  # ]:        708 :         if (pkg->type == PKG_INSTALLED &&
     974                 :          0 :             (flags & PKG_MANIFEST_EMIT_LOCAL_METADATA) == PKG_MANIFEST_EMIT_LOCAL_METADATA) {
     975                 :          0 :                 MANIFEST_EXPORT_FIELD(top, pkg, timestamp, int);
     976                 :          0 :         }
     977                 :            : 
     978                 :            :         /*
     979                 :            :          * XXX: dirty hack to be compatible with pkg 1.2
     980                 :            :          */
     981         [ +  + ]:        708 :         if (pkg->repopath) {
     982                 :        306 :                 ucl_object_insert_key(top,
     983                 :        153 :                         ucl_object_fromstring(pkg->repopath), "path", 4, false);
     984                 :        153 :                 MANIFEST_EXPORT_FIELD(top, pkg, repopath, string);
     985                 :        153 :         }
     986                 :            : 
     987   [ -  +  -  - ]:        708 :         switch (pkg->licenselogic) {
     988                 :            :         case LICENSE_SINGLE:
     989                 :          0 :                 ucl_object_insert_key(top, ucl_object_fromlstring("single", 6), "licenselogic", 12, false);
     990                 :          0 :                 break;
     991                 :            :         case LICENSE_AND:
     992                 :          0 :                 ucl_object_insert_key(top, ucl_object_fromlstring("and", 3), "licenselogic", 12, false);
     993                 :          0 :                 break;
     994                 :            :         case LICENSE_OR:
     995                 :          0 :                 ucl_object_insert_key(top, ucl_object_fromlstring("or", 2), "licenselogic", 12, false);
     996                 :          0 :                 break;
     997                 :            :         }
     998                 :            : 
     999                 :        708 :         dbg(4, "Emitting licenses");
    1000                 :        708 :         seq = NULL;
    1001   [ -  +  -  +  :        708 :         tll_foreach(pkg->licenses, l) {
                   #  # ]
    1002         [ #  # ]:          0 :                 if (seq == NULL)
    1003                 :          0 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1004                 :          0 :                 ucl_array_append(seq, ucl_object_fromstring(l->item));
    1005                 :          0 :         }
    1006         [ +  - ]:        708 :         if (seq)
    1007                 :          0 :                 ucl_object_insert_key(top, seq, "licenses", 8, false);
    1008                 :            : 
    1009         [ +  + ]:        708 :         if (pkg->pkgsize > 0)
    1010                 :        153 :                 MANIFEST_EXPORT_FIELD(top, pkg, pkgsize, int);
    1011         [ +  + ]:        708 :         if (pkg->vital)
    1012                 :          6 :                 MANIFEST_EXPORT_FIELD(top, pkg, vital, bool);
    1013                 :            : 
    1014         [ -  + ]:        708 :         if (pkg->desc != NULL) {
    1015                 :        708 :                 urlencode(pkg->desc, &tmpsbuf);
    1016                 :       1416 :                 ucl_object_insert_key(top,
    1017                 :        708 :                         ucl_object_fromstring_common(tmpsbuf->buf, strlen(tmpsbuf->buf), UCL_STRING_TRIM),
    1018                 :            :                         "desc", 4, false);
    1019                 :        708 :         }
    1020                 :            : 
    1021                 :        708 :         dbg(4, "Emitting deps");
    1022                 :        708 :         map = NULL;
    1023         [ +  + ]:        901 :         while (pkg_deps(pkg, &dep) == EPKG_OK) {
    1024                 :        193 :                 submap = ucl_object_typed_new(UCL_OBJECT);
    1025                 :        193 :                 MANIFEST_EXPORT_FIELD(submap, dep, origin, string);
    1026                 :        193 :                 MANIFEST_EXPORT_FIELD(submap, dep, version, string);
    1027         [ +  + ]:        193 :                 if (map == NULL)
    1028                 :        158 :                         map = ucl_object_typed_new(UCL_OBJECT);
    1029                 :        193 :                 ucl_object_insert_key(map, submap, dep->name, 0, false);
    1030                 :            :         }
    1031         [ +  + ]:        708 :         if (map)
    1032                 :        158 :                 ucl_object_insert_key(top, map, "deps", 4, false);
    1033                 :            : 
    1034                 :        708 :         dbg(4, "Emitting categories");
    1035                 :        708 :         seq = NULL;
    1036   [ +  +  +  +  :       1410 :         tll_foreach(pkg->categories, c) {
                   -  + ]
    1037         [ -  + ]:        702 :                 if (seq == NULL)
    1038                 :        702 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1039                 :        702 :                 ucl_array_append(seq, ucl_object_fromstring(c->item));
    1040                 :        702 :         }
    1041         [ +  + ]:        708 :         if (seq)
    1042                 :        702 :                 ucl_object_insert_key(top, seq, "categories", 10, false);
    1043                 :            : 
    1044                 :        708 :         dbg(4, "Emitting users");
    1045                 :        708 :         seq = NULL;
    1046   [ -  +  -  +  :        708 :         tll_foreach(pkg->users, u) {
                   #  # ]
    1047         [ #  # ]:          0 :                 if (seq == NULL)
    1048                 :          0 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1049                 :          0 :                 ucl_array_append(seq, ucl_object_fromstring(u->item));
    1050                 :          0 :         }
    1051         [ +  - ]:        708 :         if (seq)
    1052                 :          0 :                 ucl_object_insert_key(top, seq, "users", 5, false);
    1053                 :            : 
    1054                 :        708 :         dbg(4, "Emitting groups");
    1055                 :        708 :         seq = NULL;
    1056   [ -  +  -  +  :        708 :         tll_foreach(pkg->groups, g) {
                   #  # ]
    1057         [ #  # ]:          0 :                 if (seq == NULL)
    1058                 :          0 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1059                 :          0 :                 ucl_array_append(seq, ucl_object_fromstring(g->item));
    1060                 :          0 :         }
    1061         [ +  - ]:        708 :         if (seq)
    1062                 :          0 :                 ucl_object_insert_key(top, seq, "groups", 6, false);
    1063                 :            : 
    1064                 :        708 :         dbg(4, "Emitting shibs_required");
    1065                 :        708 :         seq = NULL;
    1066   [ +  +  +  +  :        806 :         tll_foreach(pkg->shlibs_required, s) {
                   +  + ]
    1067         [ +  + ]:         98 :                 if (seq == NULL)
    1068                 :         77 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1069                 :         98 :                 ucl_array_append(seq, ucl_object_fromstring(s->item));
    1070                 :         98 :         }
    1071         [ +  + ]:        708 :         if (seq)
    1072                 :         77 :                 ucl_object_insert_key(top, seq, "shlibs_required", 15, false);
    1073                 :            : 
    1074                 :        708 :         dbg(4, "Emitting shlibs_provided");
    1075                 :        708 :         seq = NULL;
    1076   [ +  +  +  +  :        728 :         tll_foreach(pkg->shlibs_provided, s) {
                   -  + ]
    1077         [ -  + ]:         20 :                 if (seq == NULL)
    1078                 :         20 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1079                 :         20 :                 ucl_array_append(seq, ucl_object_fromstring(s->item));
    1080                 :         20 :         }
    1081         [ +  + ]:        708 :         if (seq)
    1082                 :         20 :                 ucl_object_insert_key(top, seq, "shlibs_provided", 15, false);
    1083                 :            : 
    1084                 :        708 :         dbg(4, "Emitting conflicts");
    1085                 :        708 :         seq = NULL;
    1086         [ -  + ]:        708 :         while (pkg_conflicts(pkg, &conflict) == EPKG_OK) {
    1087         [ #  # ]:          0 :                 if (seq == NULL)
    1088                 :          0 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1089                 :          0 :                 ucl_array_append(seq, ucl_object_fromstring(conflict->uid));
    1090                 :            :         }
    1091         [ +  - ]:        708 :         if (seq)
    1092                 :          0 :                 ucl_object_insert_key(top, seq, "conflicts", 9, false);
    1093                 :            : 
    1094                 :        708 :         dbg(4, "Emitting provides");
    1095                 :        708 :         seq = NULL;
    1096   [ +  +  +  +  :        720 :         tll_foreach(pkg->provides, p) {
                   -  + ]
    1097         [ -  + ]:         12 :                 if (seq == NULL)
    1098                 :         12 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1099                 :         12 :                 ucl_array_append(seq, ucl_object_fromstring(p->item));
    1100                 :         12 :         }
    1101         [ +  + ]:        708 :         if (seq)
    1102                 :         12 :                 ucl_object_insert_key(top, seq, "provides", 8, false);
    1103                 :            : 
    1104                 :        708 :         dbg(4, "Emitting requires");
    1105                 :        708 :         seq = NULL;
    1106   [ +  +  +  +  :        729 :         tll_foreach(pkg->requires, r) {
                   -  + ]
    1107         [ -  + ]:         21 :                 if (seq == NULL)
    1108                 :         21 :                         seq = ucl_object_typed_new(UCL_ARRAY);
    1109                 :         21 :                 ucl_array_append(seq, ucl_object_fromstring(r->item));
    1110                 :         21 :         }
    1111         [ +  + ]:        708 :         if (seq)
    1112                 :         21 :                 ucl_object_insert_key(top, seq, "requires", 8, false);
    1113                 :            : 
    1114                 :        708 :         dbg(4, "Emitting options");
    1115                 :        708 :         map = NULL;
    1116         [ +  + ]:        728 :         while (pkg_options(pkg, &option) == EPKG_OK) {
    1117                 :         20 :                 dbg(4, "Emitting option: %s", option->value);
    1118         [ +  + ]:         20 :                 if (map == NULL)
    1119                 :         10 :                         map = ucl_object_typed_new(UCL_OBJECT);
    1120                 :         40 :                 ucl_object_insert_key(map,
    1121                 :         20 :                     ucl_object_fromstring(option->value),
    1122                 :         20 :                     option->key, 0, false);
    1123                 :            :         }
    1124         [ +  + ]:        708 :         if (map)
    1125                 :         10 :                 ucl_object_insert_key(top, map, "options", 7, false);
    1126                 :            : 
    1127                 :        708 :         map = NULL;
    1128   [ +  +  +  +  :       1140 :         tll_foreach(pkg->annotations, k) {
                   -  + ]
    1129                 :        432 :                 kv = k->item;
    1130         [ -  + ]:        432 :                 if (map == NULL)
    1131                 :        432 :                         map = ucl_object_typed_new(UCL_OBJECT);
    1132                 :            :                 /* Add annotations except for internal ones. */
    1133   [ +  -  #  # ]:        432 :                 if ((STREQ(kv->key, "repository") ||
    1134         [ -  + ]:        432 :                      STREQ(kv->key, "relocated")) &&
    1135                 :          0 :                     (flags & PKG_MANIFEST_EMIT_LOCAL_METADATA) == 0)
    1136                 :          0 :                         continue;
    1137                 :        864 :                 ucl_object_insert_key(map, ucl_object_fromstring(kv->value),
    1138                 :        432 :                     kv->key, strlen(kv->key), true);
    1139                 :        432 :         }
    1140         [ +  + ]:        708 :         if (map)
    1141                 :        432 :                 ucl_object_insert_key(top, map, "annotations", 11, false);
    1142                 :            : 
    1143         [ +  + ]:        708 :         if ((flags & PKG_MANIFEST_EMIT_COMPACT) == 0) {
    1144         [ -  + ]:        445 :                 if ((flags & PKG_MANIFEST_EMIT_NOFILES) == 0) {
    1145                 :        445 :                         dbg(4, "Emitting files");
    1146                 :        445 :                         map = NULL;
    1147         [ +  + ]:        689 :                         while (pkg_files(pkg, &file) == EPKG_OK) {
    1148                 :            :                                 char dpath[MAXPATHLEN];
    1149                 :        244 :                                 const char *dp = file->path;
    1150                 :            : 
    1151         [ +  + ]:        244 :                                 if (pkg->oprefix != NULL) {
    1152                 :          2 :                                         size_t l = strlen(pkg->prefix);
    1153   [ -  +  +  - ]:          4 :                                         if (strncmp(file->path, pkg->prefix, l) == 0 &&
    1154         [ +  - ]:          2 :                                                         (file->path[l] == '/' || l == 1)) {
    1155                 :          4 :                                                 snprintf(dpath, sizeof(dpath), "%s%s%s",
    1156                 :          2 :                                                                 pkg->oprefix, l == 1 ? "/" : "", file->path + l);
    1157                 :          2 :                                                 dp = dpath;
    1158                 :          2 :                                         }
    1159                 :          2 :                                 }
    1160         [ +  - ]:        244 :                                 if (file->sum == NULL)
    1161                 :          0 :                                         file->sum = xstrdup("-");
    1162                 :            : 
    1163                 :        244 :                                 urlencode(dp, &tmpsbuf);
    1164         [ +  + ]:        244 :                                 if (map == NULL)
    1165                 :        204 :                                         map = ucl_object_typed_new(UCL_OBJECT);
    1166                 :        488 :                                 ucl_object_insert_key(map,
    1167                 :        244 :                                     ucl_object_fromstring(file->sum),
    1168                 :        244 :                                     tmpsbuf->buf, strlen(tmpsbuf->buf), true);
    1169                 :            :                         }
    1170         [ +  + ]:        445 :                         if (map)
    1171                 :        204 :                                 ucl_object_insert_key(top, map, "files", 5, false);
    1172                 :            : 
    1173                 :        445 :                         dbg(4, "Emitting config files");
    1174                 :        445 :                         seq = NULL;
    1175         [ +  + ]:        460 :                         while (pkg_config_files(pkg, &cf) == EPKG_OK) {
    1176                 :         15 :                                 urlencode(cf->path, &tmpsbuf);
    1177         [ -  + ]:         15 :                                 if (seq == NULL)
    1178                 :         15 :                                         seq = ucl_object_typed_new(UCL_ARRAY);
    1179                 :         15 :                                 ucl_array_append(seq, ucl_object_fromstring(tmpsbuf->buf));
    1180                 :            :                         }
    1181         [ +  + ]:        445 :                         if (seq)
    1182                 :         15 :                                 ucl_object_insert_key(top, seq, "config", 6, false);
    1183                 :            : 
    1184                 :        445 :                         dbg(4, "Emitting directories");
    1185                 :        445 :                         map = NULL;
    1186         [ +  + ]:        454 :                         while (pkg_dirs(pkg, &dir) == EPKG_OK) {
    1187                 :          9 :                                 urlencode(dir->path, &tmpsbuf);
    1188         [ +  + ]:          9 :                                 if (map == NULL)
    1189                 :          8 :                                         map = ucl_object_typed_new(UCL_OBJECT);
    1190                 :         18 :                                 ucl_object_insert_key(map,
    1191                 :          9 :                                     ucl_object_fromstring("y"),
    1192                 :          9 :                                     tmpsbuf->buf, strlen(tmpsbuf->buf), true);
    1193                 :            :                         }
    1194         [ +  + ]:        445 :                         if (map)
    1195                 :          8 :                                 ucl_object_insert_key(top, map, "directories", 11, false);
    1196                 :        445 :                 }
    1197                 :            : 
    1198                 :        445 :                 dbg(4, "Emitting scripts");
    1199                 :        445 :                 map = NULL;
    1200         [ +  + ]:       4450 :                 for (i = 0; i < PKG_NUM_SCRIPTS; i++) {
    1201         [ +  + ]:       4005 :                         if (pkg_script_get(pkg, i) == NULL)
    1202                 :       3978 :                                 continue;
    1203                 :            : 
    1204   [ +  -  +  -  :         27 :                         switch (i) {
                -  -  - ]
    1205                 :            :                         case PKG_SCRIPT_PRE_INSTALL:
    1206                 :          9 :                                 script_types = "pre-install";
    1207                 :          9 :                                 break;
    1208                 :            :                         case PKG_SCRIPT_INSTALL:
    1209                 :          0 :                                 script_types = "install";
    1210                 :          0 :                                 break;
    1211                 :            :                         case PKG_SCRIPT_POST_INSTALL:
    1212                 :         18 :                                 script_types = "post-install";
    1213                 :         18 :                                 break;
    1214                 :            :                         case PKG_SCRIPT_PRE_DEINSTALL:
    1215                 :          0 :                                 script_types = "pre-deinstall";
    1216                 :          0 :                                 break;
    1217                 :            :                         case PKG_SCRIPT_DEINSTALL:
    1218                 :          0 :                                 script_types = "deinstall";
    1219                 :          0 :                                 break;
    1220                 :            :                         case PKG_SCRIPT_POST_DEINSTALL:
    1221                 :          0 :                                 script_types = "post-deinstall";
    1222                 :          0 :                                 break;
    1223                 :            :                         }
    1224                 :         27 :                         urlencode(pkg_script_get(pkg, i), &tmpsbuf);
    1225         [ +  + ]:         27 :                         if (map == NULL)
    1226                 :         19 :                                 map = ucl_object_typed_new(UCL_OBJECT);
    1227                 :         54 :                         ucl_object_insert_key(map,
    1228                 :         54 :                             ucl_object_fromstring_common(tmpsbuf->buf,
    1229                 :         27 :                                 strlen(tmpsbuf->buf), UCL_STRING_TRIM),
    1230                 :         27 :                             script_types, 0, true);
    1231                 :         27 :                 }
    1232         [ +  + ]:        445 :                 if (map)
    1233                 :         19 :                         ucl_object_insert_key(top, map, "scripts", 7, false);
    1234                 :            : 
    1235                 :        445 :                 dbg(4, "Emitting lua scripts");
    1236                 :        445 :                 map = NULL;
    1237         [ +  + ]:       2670 :                 for (i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
    1238         [ +  + ]:       2225 :                         if (tll_length(pkg->lua_scripts[i]) == 0)
    1239                 :       2204 :                                 continue;
    1240   [ -  -  +  -  :         21 :                         switch(i) {
                      - ]
    1241                 :            :                         case PKG_LUA_PRE_INSTALL:
    1242                 :          0 :                                 script_types = "pre-install";
    1243                 :          0 :                                 break;
    1244                 :            :                         case PKG_LUA_POST_INSTALL:
    1245                 :         21 :                                 script_types = "post-install";
    1246                 :         21 :                                 break;
    1247                 :            :                         case PKG_LUA_PRE_DEINSTALL:
    1248                 :          0 :                                 script_types = "pre-deinstall";
    1249                 :          0 :                                 break;
    1250                 :            :                         case PKG_LUA_POST_DEINSTALL:
    1251                 :          0 :                                 script_types = "post-deinstall";
    1252                 :          0 :                                 break;
    1253                 :            :                         }
    1254         [ -  + ]:         21 :                         if (map == NULL)
    1255                 :         21 :                                 map = ucl_object_typed_new(UCL_OBJECT);
    1256                 :         42 :                         ucl_object_insert_key(map,
    1257                 :         21 :                             pkg_lua_script_to_ucl(&pkg->lua_scripts[i]),
    1258                 :         21 :                                     script_types, 0, true);
    1259                 :         21 :                 }
    1260         [ +  + ]:        445 :                 if (map)
    1261                 :         21 :                         ucl_object_insert_key(top, map, "lua_scripts", 11, false);
    1262                 :        445 :         }
    1263                 :            : 
    1264                 :        708 :         dbg(4, "Emitting message");
    1265         [ +  + ]:        708 :         if (pkg_has_message(pkg))  {
    1266                 :         18 :                 ucl_object_insert_key(top,
    1267                 :          9 :                         pkg_message_to_ucl(pkg),
    1268                 :            :                         "messages", sizeof("messages") - 1, false);
    1269                 :          9 :         }
    1270                 :            : 
    1271                 :        708 :         xstring_free(tmpsbuf);
    1272                 :            : 
    1273                 :        708 :         return (top);
    1274                 :            : }
    1275                 :            : 
    1276                 :            : int
    1277                 :         29 : pkg_emit_manifest_file(struct pkg *pkg, FILE *out, short flags)
    1278                 :            : {
    1279                 :            :         ucl_object_t *top;
    1280                 :            : 
    1281                 :         29 :         top = pkg_emit_object(pkg, flags);
    1282                 :            : 
    1283         [ +  + ]:         29 :         if ((flags & PKG_MANIFEST_EMIT_PRETTY) == PKG_MANIFEST_EMIT_PRETTY)
    1284                 :          1 :                 ucl_object_emit_file(top, UCL_EMIT_YAML, out);
    1285         [ +  - ]:         28 :         else if ((flags & PKG_MANIFEST_EMIT_UCL) == PKG_MANIFEST_EMIT_UCL)
    1286                 :         28 :                 ucl_object_emit_file(top, UCL_EMIT_CONFIG, out);
    1287         [ #  # ]:          0 :         else if ((flags & PKG_MANIFEST_EMIT_JSON) == PKG_MANIFEST_EMIT_JSON)
    1288                 :          0 :                 ucl_object_emit_file(top, UCL_EMIT_JSON, out);
    1289                 :            :         else
    1290                 :          0 :                 ucl_object_emit_file(top, UCL_EMIT_JSON_COMPACT, out);
    1291                 :            : 
    1292                 :         29 :         ucl_object_unref(top);
    1293                 :            : 
    1294                 :         29 :         return (EPKG_OK);
    1295                 :            : }

Generated by: LCOV version 1.15