LCOV - code coverage report
Current view: top level - libpkg - pkg_create.c (source / functions) Hit Total Coverage
Test: rapport Lines: 243 334 72.8 %
Date: 2021-12-10 16:22:55 Functions: 22 26 84.6 %
Branches: 101 158 63.9 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2020 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2014-2015 Matthew Seaman <matthew@FreeBSD.org>
       5                 :            :  * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       6                 :            :  * All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  * 1. Redistributions of source code must retain the above copyright
      12                 :            :  *    notice, this list of conditions and the following disclaimer
      13                 :            :  *    in this position and unchanged.
      14                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      15                 :            :  *    notice, this list of conditions and the following disclaimer in the
      16                 :            :  *    documentation and/or other materials provided with the distribution.
      17                 :            :  *
      18                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      19                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      20                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      21                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      22                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      23                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      24                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      25                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      26                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      27                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      28                 :            :  */
      29                 :            : 
      30                 :            : #include <sys/stat.h>
      31                 :            : 
      32                 :            : #include <errno.h>
      33                 :            : #include <regex.h>
      34                 :            : #include <fcntl.h>
      35                 :            : 
      36                 :            : #include <bsd_compat.h>
      37                 :            : 
      38                 :            : #include "pkg.h"
      39                 :            : #include "private/event.h"
      40                 :            : #include "private/pkg.h"
      41                 :            : 
      42                 :            : #define TICK    100
      43                 :            : 
      44                 :            : static int load_metadata(struct pkg *pkg, const char *metadata, const char *plist,
      45                 :            :     const char *rootdir);
      46                 :            : static void fixup_abi(struct pkg *pkg, const char *rootdir, bool testing);
      47                 :            : static void counter_init(const char *what, int64_t max);
      48                 :            : static void counter_count(void);
      49                 :            : static void counter_end(void);
      50                 :            : 
      51                 :            : extern struct pkg_ctx ctx;
      52                 :            : 
      53                 :            : static int
      54                 :        996 : pkg_create_from_dir(struct pkg *pkg, const char *root,
      55                 :            :     struct pkg_create *pc, struct packing *pkg_archive)
      56                 :            : {
      57                 :            :         char             fpath[MAXPATHLEN];
      58                 :        996 :         struct pkg_file *file = NULL;
      59                 :        996 :         struct pkg_dir  *dir = NULL;
      60                 :            :         int              ret;
      61                 :            :         struct stat      st;
      62                 :        996 :         int64_t          flatsize = 0;
      63                 :            :         int64_t          nfiles;
      64                 :            :         const char      *relocation;
      65                 :            :         hardlinks_t     *hardlinks;
      66                 :            : 
      67         [ -  + ]:        996 :         if (pkg_is_valid(pkg) != EPKG_OK) {
      68                 :          0 :                 pkg_emit_error("the package is not valid");
      69                 :          0 :                 return (EPKG_FATAL);
      70                 :            :         }
      71                 :            : 
      72                 :        996 :         relocation = pkg_kv_get(&pkg->annotations, "relocated");
      73         [ -  + ]:        996 :         if (relocation == NULL)
      74                 :        996 :                 relocation = "";
      75         [ +  - ]:        996 :         if (ctx.pkg_rootdir != NULL)
      76                 :          0 :                 relocation = ctx.pkg_rootdir;
      77                 :            : 
      78                 :            :         /*
      79                 :            :          * Get / compute size / checksum if not provided in the manifest
      80                 :            :          */
      81                 :            : 
      82                 :        996 :         nfiles = pkghash_count(pkg->filehash);
      83                 :        996 :         counter_init("file sizes/checksums", nfiles);
      84                 :            : 
      85                 :        996 :         hardlinks = kh_init_hardlinks();
      86         [ +  + ]:       1749 :         while (pkg_files(pkg, &file) == EPKG_OK) {
      87                 :            : 
      88         [ +  + ]:        757 :                 snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
      89                 :        757 :                     relocation, file->path);
      90                 :            : 
      91         [ +  - ]:        757 :                 if (lstat(fpath, &st) == -1) {
      92                 :          0 :                         pkg_emit_error("file '%s' is missing", fpath);
      93                 :          0 :                         kh_destroy_hardlinks(hardlinks);
      94                 :          0 :                         return (EPKG_FATAL);
      95                 :            :                 }
      96                 :            : 
      97   [ +  +  +  + ]:        757 :                 if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) {
      98                 :          4 :                         pkg_emit_error("file '%s' is not a regular file or symlink", fpath);
      99                 :          4 :                         kh_destroy_hardlinks(hardlinks);
     100                 :          4 :                         return (EPKG_FATAL);
     101                 :            :                 }
     102                 :            : 
     103         [ -  + ]:        753 :                 if (file->size == 0)
     104                 :        753 :                         file->size = (int64_t)st.st_size;
     105                 :            : 
     106   [ +  +  +  + ]:        753 :                 if (st.st_nlink == 1 || !check_for_hardlink(hardlinks, &st)) {
     107                 :        730 :                         flatsize += file->size;
     108                 :        730 :                 }
     109                 :            : 
     110                 :        753 :                 file->sum = pkg_checksum_generate_file(fpath,
     111                 :            :                     PKG_HASH_TYPE_SHA256_HEX);
     112         [ +  - ]:        753 :                 if (file->sum == NULL) {
     113                 :          0 :                         kh_destroy_hardlinks(hardlinks);
     114                 :          0 :                         return (EPKG_FATAL);
     115                 :            :                 }
     116                 :            : 
     117                 :        753 :                 counter_count();
     118                 :            :         }
     119                 :        992 :         kh_destroy_hardlinks(hardlinks);
     120                 :            : 
     121                 :        992 :         counter_end();
     122                 :            : 
     123                 :        992 :         pkg->flatsize = flatsize;
     124                 :            : 
     125         [ -  + ]:        992 :         if (pkg->type == PKG_OLD_FILE) {
     126                 :          0 :                 pkg_emit_error("Cannot create an old format package");
     127                 :          0 :                 return (EPKG_FATAL);
     128                 :            :         }
     129                 :            :         /*
     130                 :            :          * Register shared libraries used by the package if
     131                 :            :          * SHLIBS enabled in conf.  Deletes shlib info if not.
     132                 :            :          */
     133                 :        992 :         xstring *b = xstring_new();
     134                 :            : 
     135                 :        992 :         pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
     136                 :        992 :         fflush(b->fp);
     137                 :        992 :         packing_append_buffer(pkg_archive, b->buf, "+COMPACT_MANIFEST", strlen(b->buf));
     138                 :        992 :         xstring_reset(b);
     139         [ -  + ]:        992 :         if (pc->expand_manifest)
     140                 :          0 :                 pkg_emit_manifest_buf(pkg, b, PKG_MANIFEST_EMIT_UCL, NULL);
     141                 :            :         else
     142                 :        992 :                 pkg_emit_manifest_buf(pkg, b, 0, NULL);
     143                 :        992 :         fflush(b->fp);
     144                 :        992 :         packing_append_buffer(pkg_archive, b->buf, "+MANIFEST", strlen(b->buf));
     145                 :        992 :         xstring_free(b);
     146                 :            : 
     147                 :        992 :         counter_init("packing files", nfiles);
     148                 :            : 
     149         [ +  + ]:       1741 :         while (pkg_files(pkg, &file) == EPKG_OK) {
     150                 :            : 
     151         [ +  + ]:        749 :                 snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
     152                 :        749 :                     relocation, file->path);
     153                 :            : 
     154                 :       1498 :                 ret = packing_append_file_attr(pkg_archive, fpath, file->path,
     155                 :        749 :                     file->uname, file->gname, file->perm, file->fflags);
     156   [ -  +  #  # ]:        749 :                 if (ctx.developer_mode && ret != EPKG_OK)
     157                 :          0 :                         return (ret);
     158                 :        749 :                 counter_count();
     159                 :            :         }
     160                 :            : 
     161                 :        992 :         counter_end();
     162                 :            : 
     163                 :        992 :         nfiles = pkghash_count(pkg->dirhash);
     164                 :        992 :         counter_init("packing directories", nfiles);
     165                 :            : 
     166         [ +  + ]:       1024 :         while (pkg_dirs(pkg, &dir) == EPKG_OK) {
     167         [ +  + ]:         32 :                 snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
     168                 :         32 :                     relocation, dir->path);
     169                 :            : 
     170                 :         64 :                 ret = packing_append_file_attr(pkg_archive, fpath, dir->path,
     171                 :         32 :                     dir->uname, dir->gname, dir->perm, dir->fflags);
     172   [ -  +  #  # ]:         32 :                 if (ctx.developer_mode && ret != EPKG_OK)
     173                 :          0 :                         return (ret);
     174                 :         32 :                 counter_count();
     175                 :            :         }
     176                 :            : 
     177                 :        992 :         counter_end();
     178                 :            : 
     179                 :        992 :         return (EPKG_OK);
     180                 :        996 : }
     181                 :            : 
     182                 :            : static struct packing *
     183                 :       1000 : pkg_create_archive(struct pkg *pkg, struct pkg_create *pc, unsigned required_flags)
     184                 :            : {
     185                 :       1000 :         char            *pkg_path = NULL;
     186                 :       1000 :         struct packing  *pkg_archive = NULL;
     187                 :            : 
     188                 :            :         /*
     189                 :            :          * Ensure that we have all the information we need
     190                 :            :          */
     191         [ -  + ]:       1000 :         if (pkg->type != PKG_OLD_FILE)
     192         [ +  - ]:       1000 :                 assert((pkg->flags & required_flags) == required_flags);
     193                 :            : 
     194         [ -  + ]:       1000 :         if (mkdirs(pc->outdir) != EPKG_OK)
     195                 :          0 :                 return NULL;
     196                 :            : 
     197         [ +  - ]:       1000 :         if (pkg_asprintf(&pkg_path, "%S/%n-%v", pc->outdir, pkg, pkg) == -1) {
     198                 :          0 :                 pkg_emit_errno("pkg_asprintf", "");
     199                 :          0 :                 return (NULL);
     200                 :            :         }
     201                 :            : 
     202   [ +  +  +  +  :       3000 :         if (packing_init(&pkg_archive, pkg_path, pc->format,
                   +  + ]
     203                 :       2000 :             pc->compression_level, pc->timestamp, pc->overwrite, false) != EPKG_OK) {
     204                 :          4 :                 pkg_archive = NULL;
     205                 :          4 :         }
     206                 :            : 
     207                 :       1000 :         free(pkg_path);
     208                 :            : 
     209                 :       1000 :         return pkg_archive;
     210                 :       1000 : }
     211                 :            : 
     212                 :            : static const char * const scripts[] = {
     213                 :            :         "+INSTALL",
     214                 :            :         "+PRE_INSTALL",
     215                 :            :         "+POST_INSTALL",
     216                 :            :         "+POST_INSTALL",
     217                 :            :         "+DEINSTALL",
     218                 :            :         "+PRE_DEINSTALL",
     219                 :            :         "+POST_DEINSTALL",
     220                 :            :         "pkg-install",
     221                 :            :         "pkg-pre-install",
     222                 :            :         "pkg-post-install",
     223                 :            :         "pkg-deinstall",
     224                 :            :         "pkg-pre-deinstall",
     225                 :            :         "pkg-post-deinstall",
     226                 :            :         NULL
     227                 :            : };
     228                 :            : 
     229                 :            : static const char * const lua_scripts[] = {
     230                 :            :         "pkg-pre-install.lua",
     231                 :            :         "pkg-post-install.lua",
     232                 :            :         "pkg-pre-deinstall.lua",
     233                 :            :         "pkg-post-deinstall.lua",
     234                 :            :         NULL
     235                 :            : };
     236                 :            : 
     237                 :            : struct pkg_create *
     238                 :       1077 : pkg_create_new(void)
     239                 :            : {
     240                 :            :         struct pkg_create *pc;
     241                 :            : 
     242                 :       1077 :         pc = xcalloc(1, sizeof(*pc));
     243                 :       1077 :         pc->format = DEFAULT_COMPRESSION;
     244                 :       1077 :         pc->compression_level = ctx.compression_level;
     245                 :       1077 :         pc->timestamp = (time_t) -1;
     246                 :       1077 :         pc->overwrite = true;
     247                 :       1077 :         pc->expand_manifest = false;
     248                 :            : 
     249                 :       1077 :         return (pc);
     250                 :            : }
     251                 :            : 
     252                 :            : void
     253                 :       1077 : pkg_create_free(struct pkg_create *pc)
     254                 :            : {
     255                 :       1077 :         free(pc);
     256                 :       1077 : }
     257                 :            : 
     258                 :            : bool
     259                 :         12 : pkg_create_set_format(struct pkg_create *pc, const char *format)
     260                 :            : {
     261         [ +  - ]:         12 :         if (strcmp(format, "tzst") == 0)
     262                 :          0 :                 pc->format = TZS;
     263         [ +  + ]:         12 :         else if (strcmp(format, "txz") == 0)
     264                 :          8 :                 pc->format = TXZ;
     265         [ +  - ]:          4 :         else if (strcmp(format, "tbz") == 0)
     266                 :          0 :                 pc->format = TBZ;
     267         [ +  - ]:          4 :         else if (strcmp(format, "tgz") == 0)
     268                 :          0 :                 pc->format = TGZ;
     269         [ +  - ]:          4 :         else if (strcmp(format, "tar") == 0)
     270                 :          4 :                 pc->format = TAR;
     271                 :            :         else
     272                 :          0 :                 return (false);
     273                 :         12 :         return (true);
     274                 :         12 : }
     275                 :            : 
     276                 :            : void
     277                 :       1077 : pkg_create_set_compression_level(struct pkg_create *pc, int clevel)
     278                 :            : {
     279                 :       1077 :         pc->compression_level = clevel;
     280                 :       1077 : }
     281                 :            : 
     282                 :            : void
     283                 :       1077 : pkg_create_set_expand_manifest(struct pkg_create *pc, bool expand)
     284                 :            : {
     285                 :       1077 :         pc->expand_manifest = expand;
     286                 :       1077 : }
     287                 :            : 
     288                 :            : void
     289                 :       1077 : pkg_create_set_rootdir(struct pkg_create *pc, const char *rootdir)
     290                 :            : {
     291                 :       1077 :         pc->rootdir = rootdir;
     292                 :       1077 : }
     293                 :            : 
     294                 :            : void
     295                 :       1077 : pkg_create_set_output_dir(struct pkg_create *pc, const char *outdir)
     296                 :            : {
     297                 :       1077 :         pc->outdir = outdir;
     298                 :       1077 : }
     299                 :            : 
     300                 :            : void
     301                 :          8 : pkg_create_set_timestamp(struct pkg_create *pc, time_t timestamp)
     302                 :            : {
     303                 :          8 :         pc->timestamp = timestamp;
     304                 :          8 : }
     305                 :            : 
     306                 :            : void
     307                 :       1077 : pkg_create_set_overwrite(struct pkg_create *pc, bool overwrite)
     308                 :            : {
     309                 :       1077 :         pc->overwrite = overwrite;
     310                 :       1077 : }
     311                 :            : 
     312                 :            : static int
     313                 :          4 : hash_file(struct pkg_create *pc, struct pkg *pkg)
     314                 :            : {
     315                 :            :         char hash_dest[MAXPATHLEN];
     316                 :            :         char filename[MAXPATHLEN];
     317                 :            : 
     318                 :            :         /* Find the hash and rename the file and create a symlink */
     319                 :          8 :         pkg_snprintf(filename, sizeof(filename), "%n-%v.pkg",
     320                 :          4 :                         pkg, pkg);
     321                 :          4 :         pkg->sum = pkg_checksum_file(filename,
     322                 :            :                         PKG_HASH_TYPE_SHA256_HEX);
     323                 :          8 :         pkg_snprintf(hash_dest, sizeof(hash_dest), "%n-%v-%z.pkg",
     324                 :          4 :                         pkg, pkg, pkg);
     325                 :            : 
     326                 :          4 :         pkg_debug(1, "Rename the pkg file from: %s to: %s",
     327                 :          4 :                         filename, hash_dest);
     328         [ +  - ]:          4 :         if (rename(filename, hash_dest) == -1) {
     329                 :          0 :                 pkg_emit_errno("rename", hash_dest);
     330                 :          0 :                 unlink(hash_dest);
     331                 :          0 :                 return (EPKG_FATAL);
     332                 :            :         }
     333         [ -  + ]:          4 :         if (symlink(hash_dest, filename) == -1) {
     334                 :          0 :                 pkg_emit_errno("symlink", hash_dest);
     335                 :          0 :                 return (EPKG_FATAL);
     336                 :            :         }
     337                 :          4 :         return (EPKG_OK);
     338                 :          4 : }
     339                 :            : 
     340                 :            : int
     341                 :          0 : pkg_create_i(struct pkg_create *pc, struct pkg *pkg, bool hash)
     342                 :            : {
     343                 :          0 :         struct packing *pkg_archive = NULL;
     344                 :            :         int ret;
     345                 :            : 
     346                 :          0 :         unsigned required_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
     347                 :            :                 PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
     348                 :            :                 PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES | PKG_LOAD_LUA_SCRIPTS;
     349                 :            : 
     350   [ #  #  #  # ]:          0 :         assert(pkg->type == PKG_INSTALLED || pkg->type == PKG_OLD_FILE);
     351                 :            : 
     352                 :          0 :         pkg_archive = pkg_create_archive(pkg, pc, required_flags);
     353         [ #  # ]:          0 :         if (pkg_archive == NULL) {
     354         [ #  # ]:          0 :                 if (errno == EEXIST)
     355                 :          0 :                         return (EPKG_EXIST);
     356                 :          0 :                 pkg_emit_error("unable to create archive");
     357                 :          0 :                 return (EPKG_FATAL);
     358                 :            :         }
     359                 :            : 
     360         [ #  # ]:          0 :         if ((ret = pkg_create_from_dir(pkg, NULL, pc, pkg_archive)) != EPKG_OK) {
     361                 :          0 :                 pkg_emit_error("package creation failed");
     362                 :          0 :         }
     363                 :          0 :         packing_finish(pkg_archive);
     364                 :            : 
     365   [ #  #  #  # ]:          0 :         if (hash && ret == EPKG_OK)
     366                 :          0 :                 ret = hash_file(pc, pkg);
     367                 :            : 
     368                 :          0 :         return (ret);
     369                 :          0 : }
     370                 :            : 
     371                 :            : int
     372                 :       1077 : pkg_create(struct pkg_create *pc, const char *metadata, const char *plist,
     373                 :            :     bool hash)
     374                 :            : {
     375                 :       1077 :         struct pkg *pkg = NULL;
     376                 :       1077 :         struct packing *pkg_archive = NULL;
     377                 :       1077 :         int ret = ENOMEM;
     378                 :            : 
     379                 :       1077 :         pkg_debug(1, "Creating package");
     380         [ -  + ]:       1077 :         if (pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
     381                 :          0 :                 return (EPKG_FATAL);
     382                 :            :         }
     383                 :            : 
     384         [ +  + ]:       1077 :         if (load_metadata(pkg, metadata, plist, pc->rootdir) != EPKG_OK) {
     385                 :         77 :                 pkg_free(pkg);
     386                 :         77 :                 return (EPKG_FATAL);
     387                 :            :         }
     388                 :       1000 :         fixup_abi(pkg, pc->rootdir, false);
     389                 :            : 
     390                 :       1000 :         pkg_archive = pkg_create_archive(pkg, pc, 0);
     391         [ +  + ]:       1000 :         if (pkg_archive == NULL) {
     392         [ +  - ]:          4 :                 if (errno == EEXIST) {
     393                 :          4 :                         pkg_emit_notice("%s-%s already packaged, skipping...\n",
     394                 :          4 :                             pkg->name, pkg->version);
     395                 :          4 :                         pkg_free(pkg);
     396                 :          4 :                         return (EPKG_EXIST);
     397                 :            :                 }
     398                 :          0 :                 pkg_free(pkg);
     399                 :          0 :                 return (EPKG_FATAL);
     400                 :            :         }
     401                 :            : 
     402         [ +  + ]:        996 :         if ((ret = pkg_create_from_dir(pkg, pc->rootdir, pc, pkg_archive)) != EPKG_OK)
     403                 :          4 :                 pkg_emit_error("package creation failed");
     404                 :            : 
     405                 :        996 :         packing_finish(pkg_archive);
     406   [ +  +  +  - ]:        996 :         if (hash && ret == EPKG_OK)
     407                 :          4 :                 ret = hash_file(pc, pkg);
     408                 :            : 
     409                 :        996 :         pkg_free(pkg);
     410                 :        996 :         return (ret);
     411                 :       1077 : }
     412                 :            : 
     413                 :            : /* The "no concessions to old pkg_tools" variant: just get everything
     414                 :            :  * from the manifest */
     415                 :            : int
     416                 :          0 : pkg_create_from_manifest(const char *outdir, pkg_formats format,
     417                 :            :     const char *rootdir, const char *manifest, const char *plist)
     418                 :            : {
     419                 :            :         struct pkg_create *pc;
     420                 :            :         int ret;
     421                 :            : 
     422                 :          0 :         pc = pkg_create_new();
     423                 :          0 :         pc->format = format;
     424                 :          0 :         pkg_create_set_rootdir(pc, rootdir);
     425                 :          0 :         pkg_create_set_output_dir(pc, outdir);
     426                 :            : 
     427                 :          0 :         ret = pkg_create(pc, manifest, plist, false);
     428                 :          0 :         pkg_create_free(pc);
     429                 :          0 :         return (ret);
     430                 :            : }
     431                 :            : 
     432                 :            : static int
     433                 :        128 : pkg_load_message_from_file(int fd, struct pkg *pkg, const char *path)
     434                 :            : {
     435                 :        128 :         char *buf = NULL;
     436                 :        128 :         off_t size = 0;
     437                 :            :         int ret;
     438                 :            :         ucl_object_t *obj;
     439                 :            : 
     440         [ +  - ]:        128 :         assert(pkg != NULL);
     441         [ -  + ]:        128 :         assert(path != NULL);
     442                 :            : 
     443         [ +  + ]:        128 :         if (faccessat(fd, path, F_OK, 0) == -1) {
     444                 :        108 :                 return (EPKG_FATAL);
     445                 :            :         }
     446                 :            : 
     447                 :         20 :         pkg_debug(1, "Reading message: '%s'", path);
     448         [ -  + ]:         20 :         if ((ret = file_to_bufferat(fd, path, &buf, &size)) != EPKG_OK) {
     449                 :          0 :                 return (ret);
     450                 :            :         }
     451                 :            : 
     452         [ +  + ]:         20 :         if (*buf == '[') {
     453                 :          8 :                 ret = pkg_message_from_str(pkg, buf, size);
     454                 :          8 :                 free(buf);
     455                 :          8 :                 return (ret);
     456                 :            :         }
     457                 :         12 :         obj = ucl_object_fromstring_common(buf, size,
     458                 :            :             UCL_STRING_RAW|UCL_STRING_TRIM);
     459                 :         12 :         ret = pkg_message_from_ucl(pkg, obj);
     460                 :         12 :         ucl_object_unref(obj);
     461                 :         12 :         free(buf);
     462                 :            : 
     463                 :         12 :         return (ret);
     464                 :        128 : }
     465                 :            : 
     466                 :            : /* TODO use file descriptor for rootdir */
     467                 :            : static int
     468                 :       1321 : load_manifest(struct pkg *pkg, const char *metadata, const char *plist,
     469                 :            :     struct pkg_manifest_key *keys, const char *rootdir)
     470                 :            : {
     471                 :            :         int ret;
     472                 :            : 
     473                 :       1321 :         ret = pkg_parse_manifest_file(pkg, metadata, keys);
     474                 :            : 
     475   [ +  +  +  + ]:       1321 :         if (ret == EPKG_OK && plist != NULL)
     476                 :        135 :                 ret = ports_parse_plist(pkg, plist, rootdir);
     477                 :       1321 :         return (ret);
     478                 :            : }
     479                 :            : 
     480                 :            : /* TODO use file descriptor for rootdir */
     481                 :            : static int
     482                 :       1462 : load_metadata(struct pkg *pkg, const char *metadata, const char *plist,
     483                 :            :     const char *rootdir)
     484                 :            : {
     485                 :       1462 :         struct pkg_manifest_key *keys = NULL;
     486                 :            :         regex_t preg;
     487                 :            :         regmatch_t pmatch[2];
     488                 :            :         size_t size;
     489                 :            :         int fd, i;
     490                 :            : 
     491                 :       1462 :         pkg_manifest_keys_new(&keys);
     492                 :            : 
     493                 :            :         /* Let's see if we have a directory or a manifest */
     494         [ +  + ]:       1462 :         if ((fd = open(metadata, O_DIRECTORY|O_CLOEXEC)) == -1) {
     495         [ +  - ]:       1321 :                 if (errno == ENOTDIR)
     496                 :       1321 :                         return (load_manifest(pkg, metadata, plist, keys, rootdir));
     497                 :          0 :                 pkg_emit_errno("open", metadata);
     498                 :          0 :                 pkg_manifest_keys_free(keys);
     499                 :          0 :                 return (EPKG_FATAL);
     500                 :            :         }
     501                 :            : 
     502         [ +  + ]:        141 :         if ((pkg_parse_manifest_fileat(fd, pkg, "+MANIFEST", keys)) != EPKG_OK) {
     503                 :         13 :                 pkg_manifest_keys_free(keys);
     504                 :         13 :                 close(fd);
     505                 :         13 :                 return (EPKG_FATAL);
     506                 :            :         }
     507                 :        128 :         pkg_manifest_keys_free(keys);
     508                 :            : 
     509                 :        128 :         pkg_load_message_from_file(fd, pkg, "+DISPLAY");
     510         [ -  + ]:        128 :         if (pkg->desc == NULL)
     511                 :          0 :                 pkg_set_from_fileat(fd, pkg, PKG_DESC, "+DESC", false);
     512                 :            : 
     513         [ +  + ]:       1792 :         for (i = 0; scripts[i] != NULL; i++) {
     514         [ +  - ]:       1664 :                 if (faccessat(fd, scripts[i], F_OK, 0) == 0)
     515                 :          0 :                         pkg_addscript_fileat(fd, pkg, scripts[i]);
     516                 :       1664 :         }
     517                 :            : 
     518         [ +  + ]:        640 :         for (i = 0; lua_scripts[i] != NULL; i++) {
     519         [ +  - ]:        512 :                 if (faccessat(fd, lua_scripts[i], F_OK, 0) == 0)
     520                 :          0 :                         pkg_addluascript_fileat(fd, pkg, lua_scripts[i]);
     521                 :        512 :         }
     522                 :            : 
     523   [ +  +  +  + ]:        128 :         if (plist != NULL && ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) {
     524                 :         48 :                 return (EPKG_FATAL);
     525                 :            :         }
     526                 :         80 :         close(fd);
     527                 :            : 
     528         [ +  - ]:         80 :         if (pkg->www == NULL) {
     529         [ #  # ]:          0 :                 if (pkg->desc == NULL) {
     530                 :          0 :                         pkg_emit_error("No www or desc defined in manifest");
     531                 :          0 :                         return (EPKG_FATAL);
     532                 :            :                 }
     533                 :          0 :                 regcomp(&preg, "^WWW:[[:space:]]*(.*)$",
     534                 :            :                     REG_EXTENDED|REG_ICASE|REG_NEWLINE);
     535         [ #  # ]:          0 :                 if (regexec(&preg, pkg->desc, 2, pmatch, 0) == 0) {
     536                 :          0 :                         size = pmatch[1].rm_eo - pmatch[1].rm_so;
     537                 :          0 :                         pkg->www = xstrndup(&pkg->desc[pmatch[1].rm_so], size);
     538                 :          0 :                 } else {
     539                 :          0 :                         pkg->www = xstrdup("UNKNOWN");
     540                 :            :                 }
     541                 :          0 :                 regfree(&preg);
     542                 :          0 :         }
     543                 :            : 
     544                 :         80 :         return (EPKG_OK);
     545                 :       1462 : }
     546                 :            : 
     547                 :            : static void
     548                 :       1381 : fixup_abi(struct pkg *pkg, const char *rootdir, bool testing)
     549                 :            : {
     550                 :       1381 :         bool defaultarch = false;
     551                 :            :         const char *arch;
     552                 :            : 
     553                 :            :         /* if no arch autodetermine it */
     554         [ +  + ]:       1381 :         if (pkg->abi == NULL) {
     555                 :            : #ifdef __FreeBSD__
     556                 :            :                 char *osversion;
     557                 :       1020 :                 xasprintf(&osversion, "%d", ctx.osversion);
     558                 :       1020 :                 pkg_kv_add(&pkg->annotations, "FreeBSD_version", osversion, "annotation");
     559                 :            : #endif
     560                 :       1020 :                 arch = pkg_object_string(pkg_config_get("ABI"));
     561                 :       1020 :                 pkg->abi = xstrdup(arch);
     562                 :       1020 :                 defaultarch = true;
     563                 :       1020 :         }
     564                 :            : 
     565         [ +  + ]:       1381 :         if (!testing)
     566                 :       1323 :                 pkg_analyse_files(NULL, pkg, rootdir);
     567                 :            : 
     568         [ +  - ]:       1381 :         if (ctx.developer_mode)
     569                 :          0 :                 suggest_arch(pkg, defaultarch);
     570                 :       1381 : }
     571                 :            : 
     572                 :            : int
     573                 :        385 : pkg_load_metadata(struct pkg *pkg, const char *mfile, const char *md_dir,
     574                 :            :     const char *plist, const char *rootdir, bool testing)
     575                 :            : {
     576                 :            :         int ret;
     577                 :            : 
     578         [ +  + ]:        385 :         ret = load_metadata(pkg, md_dir != NULL ? md_dir: mfile, plist, rootdir);
     579         [ +  + ]:        385 :         if (ret != EPKG_OK)
     580                 :          4 :                 return (ret);
     581                 :            : 
     582                 :        381 :         fixup_abi(pkg, rootdir, testing);
     583                 :        381 :         return (ret);
     584                 :        385 : }
     585                 :            : 
     586                 :            : int
     587                 :          0 : pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
     588                 :            :     const char *md_dir, char *plist, bool hash)
     589                 :            : {
     590                 :            :         struct pkg_create *pc;
     591                 :            :         int ret;
     592                 :            : 
     593                 :          0 :         pc = pkg_create_new();
     594                 :          0 :         pc->format = format;
     595                 :          0 :         pkg_create_set_rootdir(pc, rootdir);
     596                 :          0 :         pkg_create_set_output_dir(pc, outdir);
     597                 :            : 
     598                 :          0 :         ret = pkg_create(pc, md_dir, plist, hash);
     599                 :          0 :         pkg_create_free(pc);
     600                 :          0 :         return (ret);
     601                 :            : }
     602                 :            : 
     603                 :            : int
     604                 :          0 : pkg_create_installed(const char *outdir, pkg_formats format, struct pkg *pkg)
     605                 :            : {
     606                 :            :         struct pkg_create *pc;
     607                 :            :         int ret;
     608                 :            : 
     609                 :          0 :         pc = pkg_create_new();
     610                 :          0 :         pc->format = format;
     611                 :          0 :         pkg_create_set_output_dir(pc, outdir);
     612                 :            : 
     613                 :          0 :         ret = pkg_create_i(pc, pkg, false);
     614                 :          0 :         pkg_create_free(pc);
     615                 :          0 :         return (ret);
     616                 :            : }
     617                 :            : 
     618                 :            : static int64_t  count;
     619                 :            : static int64_t  maxcount;
     620                 :            : static const char *what;
     621                 :            : 
     622                 :       2980 : static int magnitude(int64_t num)
     623                 :            : {
     624                 :            :         int oom;
     625                 :            : 
     626         [ +  + ]:       2980 :         if (num == 0)
     627                 :       1712 :                 return (1);
     628         [ -  + ]:       1268 :         if (num < 0)
     629                 :          0 :                 num = -num;
     630                 :            : 
     631         [ -  + ]:       1268 :         for (oom = 1; num >= 10; oom++)
     632                 :          0 :                 num /= 10;
     633                 :            : 
     634                 :       1268 :         return (oom);
     635                 :       2980 : }
     636                 :            : 
     637                 :            : static void
     638                 :       2980 : counter_init(const char *count_what, int64_t max)
     639                 :            : {
     640                 :       2980 :         count = 0;
     641                 :       2980 :         what = count_what;
     642                 :       2980 :         maxcount = max;
     643                 :       5960 :         pkg_emit_progress_start("%-20s%*s[%jd]", what,
     644                 :       2980 :             6 - magnitude(maxcount), " ", (intmax_t)maxcount);
     645                 :            : 
     646                 :       2980 :         return;
     647                 :            : }
     648                 :            : 
     649                 :            : static void
     650                 :       1534 : counter_count(void)
     651                 :            : {
     652                 :       1534 :         count++;
     653                 :            : 
     654         [ -  + ]:       1534 :         if (count % TICK == 0)
     655                 :          0 :                 pkg_emit_progress_tick(count, maxcount);
     656                 :            : 
     657                 :       1534 :         return;
     658                 :            : }
     659                 :            : 
     660                 :            : static void
     661                 :       2976 : counter_end(void)
     662                 :            : {
     663                 :       2976 :         pkg_emit_progress_tick(count, maxcount);
     664                 :       2976 :         return;
     665                 :            : }

Generated by: LCOV version 1.15