LCOV - code coverage report
Current view: top level - libpkg - pkg_config.c (source / functions) Hit Total Coverage
Test: rapport Lines: 558 776 71.9 %
Date: 2021-12-10 16:22:55 Functions: 36 39 92.3 %
Branches: 241 416 57.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2011-2021 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
       5                 :            :  * Copyright (c) 2016 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 "pkg_config.h"
      31                 :            : 
      32                 :            : #include <assert.h>
      33                 :            : #include <sys/socket.h>
      34                 :            : #include <sys/un.h>
      35                 :            : #include <ctype.h>
      36                 :            : #include <dirent.h>
      37                 :            : #include <dlfcn.h>
      38                 :            : #include <errno.h>
      39                 :            : #include <fcntl.h>
      40                 :            : #ifdef HAVE_OSRELDATE_H
      41                 :            : #include <osreldate.h>
      42                 :            : #endif
      43                 :            : #include <ucl.h>
      44                 :            : 
      45                 :            : #include "pkg.h"
      46                 :            : #include "private/pkg.h"
      47                 :            : #include "private/event.h"
      48                 :            : #include "pkg_repos.h"
      49                 :            : 
      50                 :            : #ifndef PORTSDIR
      51                 :            : #define PORTSDIR "/usr/ports"
      52                 :            : #endif
      53                 :            : #ifndef DEFAULT_VULNXML_URL
      54                 :            : #define DEFAULT_VULNXML_URL "http://vuxml.freebsd.org/freebsd/vuln.xml.xz"
      55                 :            : #endif
      56                 :            : 
      57                 :            : #ifdef  OSMAJOR
      58                 :            : #define STRINGIFY(X)    TEXT(X)
      59                 :            : #define TEXT(X)         #X
      60                 :            : #define INDEXFILE       "INDEX-" STRINGIFY(OSMAJOR)
      61                 :            : #else
      62                 :            : #define INDEXFILE       "INDEX"
      63                 :            : #endif
      64                 :            : 
      65                 :            : struct pkg_ctx ctx = {
      66                 :            :         .eventpipe = -1,
      67                 :            :         .debug_level = 0,
      68                 :            :         .developer_mode = false,
      69                 :            :         .pkg_rootdir = NULL,
      70                 :            :         .dbdir = NULL,
      71                 :            :         .cachedir = NULL,
      72                 :            :         .rootfd = -1,
      73                 :            :         .cachedirfd = -1,
      74                 :            :         .pkg_dbdirfd = -1,
      75                 :            :         .osversion = 0,
      76                 :            :         .backup_libraries = false,
      77                 :            :         .triggers = true,
      78                 :            :         .compression_level = -1,
      79                 :            :         .defer_triggers = false,
      80                 :            : };
      81                 :            : 
      82                 :            : struct config_entry {
      83                 :            :         uint8_t type;
      84                 :            :         const char *key;
      85                 :            :         const char *def;
      86                 :            :         const char *desc;
      87                 :            : };
      88                 :            : 
      89                 :            : static char myabi[BUFSIZ], myabi_legacy[BUFSIZ];
      90                 :            : #ifdef __FreeBSD__
      91                 :            : static char myosversion[BUFSIZ];
      92                 :            : #endif
      93                 :            : static struct pkg_repo *repos = NULL;
      94                 :            : ucl_object_t *config = NULL;
      95                 :            : 
      96                 :            : static struct config_entry c[] = {
      97                 :            :         {
      98                 :            :                 PKG_STRING,
      99                 :            :                 "PKG_DBDIR",
     100                 :            :                 "/var/db/pkg",
     101                 :            :                 "Where the package databases are stored",
     102                 :            :         },
     103                 :            :         {
     104                 :            :                 PKG_STRING,
     105                 :            :                 "PKG_CACHEDIR",
     106                 :            :                 "/var/cache/pkg",
     107                 :            :                 "Directory containing cache of downloaded packages",
     108                 :            :         },
     109                 :            :         {
     110                 :            :                 PKG_STRING,
     111                 :            :                 "PORTSDIR",
     112                 :            :                 "/usr/ports",
     113                 :            :                 "Location of the ports collection",
     114                 :            :         },
     115                 :            :         {
     116                 :            :                 PKG_STRING,
     117                 :            :                 "INDEXDIR",
     118                 :            :                 NULL,           /* Default to PORTSDIR unless defined */
     119                 :            :                 "Location of the ports INDEX",
     120                 :            :         },
     121                 :            :         {
     122                 :            :                 PKG_STRING,
     123                 :            :                 "INDEXFILE",
     124                 :            :                 INDEXFILE,
     125                 :            :                 "Filename of the ports INDEX",
     126                 :            :         },
     127                 :            :         {
     128                 :            :                 PKG_BOOL,
     129                 :            :                 "HANDLE_RC_SCRIPTS",
     130                 :            :                 "NO",
     131                 :            :                 "Automatically handle restarting services",
     132                 :            :         },
     133                 :            :         {
     134                 :            :                 PKG_BOOL,
     135                 :            :                 "DEFAULT_ALWAYS_YES",
     136                 :            :                 "NO",
     137                 :            :                 "Default to 'yes' for all pkg(8) questions",
     138                 :            :         },
     139                 :            :         {
     140                 :            :                 PKG_BOOL,
     141                 :            :                 "ASSUME_ALWAYS_YES",
     142                 :            :                 "NO",
     143                 :            :                 "Answer 'yes' to all pkg(8) questions",
     144                 :            :         },
     145                 :            :         {
     146                 :            :                 PKG_ARRAY,
     147                 :            :                 "REPOS_DIR",
     148                 :            :                 "/etc/pkg/,"PREFIX"/etc/pkg/repos/",
     149                 :            :                 "Location of the repository configuration files"
     150                 :            :         },
     151                 :            :         {
     152                 :            :                 PKG_STRING,
     153                 :            :                 "PLIST_KEYWORDS_DIR",
     154                 :            :                 NULL,
     155                 :            :                 "Directory containing definitions of plist keywords",
     156                 :            :         },
     157                 :            :         {
     158                 :            :                 PKG_BOOL,
     159                 :            :                 "SYSLOG",
     160                 :            :                 "YES",
     161                 :            :                 "Log pkg(8) operations via syslog(3)",
     162                 :            :         },
     163                 :            :         {
     164                 :            :                 PKG_STRING,
     165                 :            :                 "ABI",
     166                 :            :                 myabi,
     167                 :            :                 "Override the automatically detected ABI",
     168                 :            :         },
     169                 :            :         {
     170                 :            :                 PKG_STRING,
     171                 :            :                 "ALTABI",
     172                 :            :                 myabi_legacy,
     173                 :            :                 "Override the automatically detected old-form ABI",
     174                 :            :         },
     175                 :            :         {
     176                 :            :                 PKG_BOOL,
     177                 :            :                 "DEVELOPER_MODE",
     178                 :            :                 "NO",
     179                 :            :                 "Add extra strict, pedantic warnings as an aid to package maintainers",
     180                 :            :         },
     181                 :            :         {
     182                 :            :                 PKG_STRING,
     183                 :            :                 "VULNXML_SITE",
     184                 :            :                 DEFAULT_VULNXML_URL,
     185                 :            :                 "URL giving location of the vulnxml database",
     186                 :            :         },
     187                 :            :         {
     188                 :            :                 PKG_INT,
     189                 :            :                 "FETCH_RETRY",
     190                 :            :                 "3",
     191                 :            :                 "How many times to retry fetching files",
     192                 :            :         },
     193                 :            :         {
     194                 :            :                 PKG_STRING,
     195                 :            :                 "PKG_PLUGINS_DIR",
     196                 :            :                 PREFIX"/lib/pkg/",
     197                 :            :                 "Directory which pkg(8) will load plugins from",
     198                 :            :         },
     199                 :            :         {
     200                 :            :                 PKG_BOOL,
     201                 :            :                 "PKG_ENABLE_PLUGINS",
     202                 :            :                 "YES",
     203                 :            :                 "Activate plugin support",
     204                 :            :         },
     205                 :            :         {
     206                 :            :                 PKG_ARRAY,
     207                 :            :                 "PLUGINS",
     208                 :            :                 NULL,
     209                 :            :                 "List of plugins that pkg(8) should load",
     210                 :            :         },
     211                 :            :         {
     212                 :            :                 PKG_BOOL,
     213                 :            :                 "DEBUG_SCRIPTS",
     214                 :            :                 "NO",
     215                 :            :                 "Run shell scripts in verbose mode to facilitate debugging",
     216                 :            :         },
     217                 :            :         {
     218                 :            :                 PKG_STRING,
     219                 :            :                 "PLUGINS_CONF_DIR",
     220                 :            :                 PREFIX"/etc/pkg/",
     221                 :            :                 "Directory containing plugin configuration data",
     222                 :            :         },
     223                 :            :         {
     224                 :            :                 PKG_BOOL,
     225                 :            :                 "PERMISSIVE",
     226                 :            :                 "NO",
     227                 :            :                 "Permit package installation despite presence of conflicting packages",
     228                 :            :         },
     229                 :            :         {
     230                 :            :                 PKG_BOOL,
     231                 :            :                 "REPO_AUTOUPDATE",
     232                 :            :                 "YES",
     233                 :            :                 "Automatically update repository catalogues prior to package updates",
     234                 :            :         },
     235                 :            :         {
     236                 :            :                 PKG_STRING,
     237                 :            :                 "NAMESERVER",
     238                 :            :                 NULL,
     239                 :            :                 "Use this nameserver when looking up addresses",
     240                 :            :         },
     241                 :            :         {
     242                 :            :                 PKG_STRING,
     243                 :            :                 "HTTP_USER_AGENT",
     244                 :            :                 "pkg/"PKGVERSION,
     245                 :            :                 "HTTP User-Agent",
     246                 :            :         },
     247                 :            :         {
     248                 :            :                 PKG_STRING,
     249                 :            :                 "EVENT_PIPE",
     250                 :            :                 NULL,
     251                 :            :                 "Send all events to the specified fifo or Unix socket",
     252                 :            :         },
     253                 :            :         {
     254                 :            :                 PKG_INT,
     255                 :            :                 "FETCH_TIMEOUT",
     256                 :            :                 "30",
     257                 :            :                 "Number of seconds before fetch(3) times out",
     258                 :            :         },
     259                 :            :         {
     260                 :            :                 PKG_BOOL,
     261                 :            :                 "UNSET_TIMESTAMP",
     262                 :            :                 "NO",
     263                 :            :                 "Do not include timestamps in the package",
     264                 :            :         },
     265                 :            :         {
     266                 :            :                 PKG_STRING,
     267                 :            :                 "SSH_RESTRICT_DIR",
     268                 :            :                 NULL,
     269                 :            :                 "Directory the ssh subsystem will be restricted to",
     270                 :            :         },
     271                 :            :         {
     272                 :            :                 PKG_OBJECT,
     273                 :            :                 "PKG_ENV",
     274                 :            :                 NULL,
     275                 :            :                 "Environment variables pkg will use",
     276                 :            :         },
     277                 :            :         {
     278                 :            :                 PKG_STRING,
     279                 :            :                 "PKG_SSH_ARGS",
     280                 :            :                 NULL,
     281                 :            :                 "Extras arguments to pass to ssh(1)",
     282                 :            :         },
     283                 :            :         {
     284                 :            :                 PKG_INT,
     285                 :            :                 "DEBUG_LEVEL",
     286                 :            :                 "0",
     287                 :            :                 "Level for debug messages",
     288                 :            :         },
     289                 :            :         {
     290                 :            :                 PKG_OBJECT,
     291                 :            :                 "ALIAS",
     292                 :            :                 NULL,
     293                 :            :                 "Command aliases",
     294                 :            :         },
     295                 :            :         {
     296                 :            :                 PKG_STRING,
     297                 :            :                 "CUDF_SOLVER",
     298                 :            :                 NULL,
     299                 :            :                 "Experimental: tells pkg to use an external CUDF solver",
     300                 :            :         },
     301                 :            :         {
     302                 :            :                 PKG_STRING,
     303                 :            :                 "SAT_SOLVER",
     304                 :            :                 NULL,
     305                 :            :                 "Experimental: tells pkg to use an external SAT solver",
     306                 :            :         },
     307                 :            :         {
     308                 :            :                 PKG_BOOL,
     309                 :            :                 "RUN_SCRIPTS",
     310                 :            :                 "YES",
     311                 :            :                 "Run post/pre actions scripts",
     312                 :            :         },
     313                 :            :         {
     314                 :            :                 PKG_BOOL,
     315                 :            :                 "CASE_SENSITIVE_MATCH",
     316                 :            :                 "NO",
     317                 :            :                 "Match package names case sensitively",
     318                 :            :         },
     319                 :            :         {
     320                 :            :                 PKG_INT,
     321                 :            :                 "LOCK_WAIT",
     322                 :            :                 "1",
     323                 :            :                 "Wait time to regain a lock if it is not available"
     324                 :            :         },
     325                 :            :         {
     326                 :            :                 PKG_INT,
     327                 :            :                 "LOCK_RETRIES",
     328                 :            :                 "5",
     329                 :            :                 "Retries performed to obtain a lock"
     330                 :            :         },
     331                 :            :         {
     332                 :            :                 PKG_BOOL,
     333                 :            :                 "SQLITE_PROFILE",
     334                 :            :                 "NO",
     335                 :            :                 "Profile sqlite queries"
     336                 :            :         },
     337                 :            :         {
     338                 :            :                 PKG_INT,
     339                 :            :                 "WORKERS_COUNT",
     340                 :            :                 "0",
     341                 :            :                 "How many workers are used for pkg-repo (hw.ncpu if 0)"
     342                 :            :         },
     343                 :            :         {
     344                 :            :                 PKG_BOOL,
     345                 :            :                 "READ_LOCK",
     346                 :            :                 "NO",
     347                 :            :                 "Use read locking for query database"
     348                 :            :         },
     349                 :            :         {
     350                 :            :                 PKG_BOOL,
     351                 :            :                 "PLIST_ACCEPT_DIRECTORIES",
     352                 :            :                 "NO",
     353                 :            :                 "Accept directories listed like plain files in plist"
     354                 :            :         },
     355                 :            :         {
     356                 :            :                 PKG_INT,
     357                 :            :                 "IP_VERSION",
     358                 :            :                 "0",
     359                 :            :                 "Restrict network access to IPv4 or IPv6 only"
     360                 :            :         },
     361                 :            :         {
     362                 :            :                 PKG_BOOL,
     363                 :            :                 "AUTOMERGE",
     364                 :            :                 "YES",
     365                 :            :                 "Automatically merge configuration files"
     366                 :            :         },
     367                 :            :         {
     368                 :            :                 PKG_STRING,
     369                 :            :                 "VERSION_SOURCE",
     370                 :            :                 NULL,
     371                 :            :                 "Version source for pkg-version (I, P, R), default is auto detect"
     372                 :            :         },
     373                 :            :         {
     374                 :            :                 PKG_BOOL,
     375                 :            :                 "CONSERVATIVE_UPGRADE",
     376                 :            :                 "YES",
     377                 :            :                 "Prefer repos with higher priority during upgrade"
     378                 :            :         },
     379                 :            :         {
     380                 :            :                 PKG_BOOL,
     381                 :            :                 "PKG_CREATE_VERBOSE",
     382                 :            :                 "NO",
     383                 :            :                 "Enable verbose mode for 'pkg create'",
     384                 :            :         },
     385                 :            :         {
     386                 :            :                 PKG_BOOL,
     387                 :            :                 "AUTOCLEAN",
     388                 :            :                 "NO",
     389                 :            :                 "Always cleanup the cache directory after install/upgrade",
     390                 :            :         },
     391                 :            :         {
     392                 :            :                 PKG_STRING,
     393                 :            :                 "DOT_FILE",
     394                 :            :                 NULL,
     395                 :            :                 "Save SAT problem to the specified dot file"
     396                 :            :         },
     397                 :            :         {
     398                 :            :                 PKG_OBJECT,
     399                 :            :                 "REPOSITORIES",
     400                 :            :                 NULL,
     401                 :            :                 "Repository config in pkg.conf"
     402                 :            :         },
     403                 :            :         {
     404                 :            :                 PKG_ARRAY,
     405                 :            :                 "VALID_URL_SCHEME",
     406                 :            :                 "pkg+http,pkg+https,https,http,file,ssh,ftp,ftps,pkg+ssh,pkg+ftp,pkg+ftps",
     407                 :            :         },
     408                 :            :         {
     409                 :            :                 PKG_BOOL,
     410                 :            :                 "ALLOW_BASE_SHLIBS",
     411                 :            :                 "NO",
     412                 :            :                 "Enable base libraries analysis",
     413                 :            :         },
     414                 :            :         {
     415                 :            :                 PKG_INT,
     416                 :            :                 "WARN_SIZE_LIMIT",
     417                 :            :                 "1048576", /* 1 meg */
     418                 :            :                 "Ask user when performing changes for more than this limit"
     419                 :            :         },
     420                 :            :         {
     421                 :            :                 PKG_STRING,
     422                 :            :                 "METALOG",
     423                 :            :                 NULL,
     424                 :            :                 "Write out the METALOG to the specified file",
     425                 :            :         },
     426                 :            : #ifdef __FreeBSD__
     427                 :            :         {
     428                 :            :                 PKG_INT,
     429                 :            :                 "OSVERSION",
     430                 :            :                 myosversion,
     431                 :            :                 "FreeBSD OS version",
     432                 :            :         },
     433                 :            :         {
     434                 :            :                 PKG_BOOL,
     435                 :            :                 "IGNORE_OSVERSION",
     436                 :            :                 "NO",
     437                 :            :                 "Ignore FreeBSD OS version check",
     438                 :            :         },
     439                 :            : #endif
     440                 :            :         {
     441                 :            :                 PKG_BOOL,
     442                 :            :                 "BACKUP_LIBRARIES",
     443                 :            :                 "NO",
     444                 :            :                 "Backup old versions of libraries during an upgrade",
     445                 :            :         },
     446                 :            :         {
     447                 :            :                 PKG_STRING,
     448                 :            :                 "BACKUP_LIBRARY_PATH",
     449                 :            :                 PREFIX "/lib/compat/pkg",
     450                 :            :                 "Path where pkg will backup libraries",
     451                 :            :         },
     452                 :            :         {
     453                 :            :                 PKG_STRING,
     454                 :            :                 "PKG_TRIGGERS_DIR",
     455                 :            :                 PREFIX "/share/pkg/triggers",
     456                 :            :                 "Path where the triggers should be installed",
     457                 :            :         },
     458                 :            :         {
     459                 :            :                 PKG_BOOL,
     460                 :            :                 "PKG_TRIGGERS_ENABLE",
     461                 :            :                 "YES",
     462                 :            :                 "Disable triggers",
     463                 :            :         },
     464                 :            :         {
     465                 :            :                 PKG_ARRAY,
     466                 :            :                 "AUDIT_IGNORE_GLOB",
     467                 :            :                 NULL,
     468                 :            :                 "List of glob to ignore while autiditing for vulnerabilities",
     469                 :            :         },
     470                 :            :         {
     471                 :            :                 PKG_ARRAY,
     472                 :            :                 "AUDIT_IGNORE_REGEX",
     473                 :            :                 "NULL",
     474                 :            :                 "List of regex to ignore while autiditing for vulnerabilities",
     475                 :            :         },
     476                 :            :         {
     477                 :            :                 PKG_INT,
     478                 :            :                 "COMPRESSION_LEVEL",
     479                 :            :                 "-1",
     480                 :            :                 "Set the default compression level",
     481                 :            :         },
     482                 :            :         {
     483                 :            :                 PKG_BOOL,
     484                 :            :                 "ARCHIVE_SYMLINK",
     485                 :            :                 "FALSE",
     486                 :            :                 "Create a symlink to legacy extension for backward compatibility",
     487                 :            :         },
     488                 :            :         {
     489                 :            :                 PKG_BOOL,
     490                 :            :                 "REPO_ACCEPT_LEGACY_PKG",
     491                 :            :                 "FALSE",
     492                 :            :                 "Accept legacy package extensions when creating the repository",
     493                 :            :         },
     494                 :            :         {
     495                 :            :                 PKG_ARRAY,
     496                 :            :                 "FILES_IGNORE_GLOB",
     497                 :            :                 "NULL",
     498                 :            :                 "patterns of files to not extract from the package",
     499                 :            :         },
     500                 :            :         {
     501                 :            :                 PKG_ARRAY,
     502                 :            :                 "FILES_IGNORE_REGEX",
     503                 :            :                 "NULL",
     504                 :            :                 "patterns of files to not extract from the package",
     505                 :            :         },
     506                 :            : };
     507                 :            : 
     508                 :            : static bool parsed = false;
     509                 :            : static size_t c_size = NELEM(c);
     510                 :            : 
     511                 :            : static struct pkg_repo* pkg_repo_new(const char *name,
     512                 :            :         const char *url, const char *type);
     513                 :            : static void pkg_repo_overwrite(struct pkg_repo*, const char *name,
     514                 :            :         const char *url, const char *type);
     515                 :            : static void pkg_repo_free(struct pkg_repo *r);
     516                 :            : 
     517                 :            : static void
     518                 :          0 : connect_evpipe(const char *evpipe) {
     519                 :            :         struct stat st;
     520                 :            :         struct sockaddr_un sock;
     521                 :          0 :         int flag = O_WRONLY;
     522                 :            : 
     523         [ #  # ]:          0 :         if (stat(evpipe, &st) != 0) {
     524                 :          0 :                 pkg_emit_error("No such event pipe: %s", evpipe);
     525                 :          0 :                 return;
     526                 :            :         }
     527                 :            : 
     528   [ #  #  #  # ]:          0 :         if (!S_ISFIFO(st.st_mode) && !S_ISSOCK(st.st_mode)) {
     529                 :          0 :                 pkg_emit_error("%s is not a fifo or socket", evpipe);
     530                 :          0 :                 return;
     531                 :            :         }
     532                 :            : 
     533         [ #  # ]:          0 :         if (S_ISFIFO(st.st_mode)) {
     534                 :          0 :                 flag |= O_NONBLOCK;
     535         [ #  # ]:          0 :                 if ((ctx.eventpipe = open(evpipe, flag)) == -1)
     536                 :          0 :                         pkg_emit_errno("open event pipe", evpipe);
     537                 :          0 :                 return;
     538                 :            :         }
     539                 :            : 
     540         [ #  # ]:          0 :         if (S_ISSOCK(st.st_mode)) {
     541         [ #  # ]:          0 :                 if ((ctx.eventpipe = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
     542                 :          0 :                         pkg_emit_errno("Open event pipe", evpipe);
     543                 :          0 :                         return;
     544                 :            :                 }
     545                 :          0 :                 memset(&sock, 0, sizeof(struct sockaddr_un));
     546                 :          0 :                 sock.sun_family = AF_UNIX;
     547         [ #  # ]:          0 :                 if (strlcpy(sock.sun_path, evpipe, sizeof(sock.sun_path)) >=
     548                 :            :                     sizeof(sock.sun_path)) {
     549                 :          0 :                         pkg_emit_error("Socket path too long: %s", evpipe);
     550                 :          0 :                         close(ctx.eventpipe);
     551                 :          0 :                         ctx.eventpipe = -1;
     552                 :          0 :                         return;
     553                 :            :                 }
     554                 :            : 
     555         [ #  # ]:          0 :                 if (connect(ctx.eventpipe, (struct sockaddr *)&sock, SUN_LEN(&sock)) == -1) {
     556                 :          0 :                         pkg_emit_errno("Connect event pipe", evpipe);
     557                 :          0 :                         close(ctx.eventpipe);
     558                 :          0 :                         ctx.eventpipe = -1;
     559                 :          0 :                         return;
     560                 :            :                 }
     561                 :          0 :         }
     562                 :            : 
     563                 :          0 : }
     564                 :            : 
     565                 :            : int
     566                 :        303 : pkg_initialized(void)
     567                 :            : {
     568                 :        303 :         return (parsed);
     569                 :            : }
     570                 :            : 
     571                 :            : const pkg_object *
     572                 :     135471 : pkg_config_get(const char *key) {
     573                 :     135471 :         return (ucl_object_find_key(config, key));
     574                 :            : }
     575                 :            : 
     576                 :            : char *
     577                 :         34 : pkg_config_dump(void)
     578                 :            : {
     579                 :         34 :         return (pkg_object_dump(config));
     580                 :            : }
     581                 :            : 
     582                 :            : static void
     583                 :       3501 : disable_plugins_if_static(void)
     584                 :            : {
     585                 :            :         void *dlh;
     586                 :            : 
     587                 :       3501 :         dlh = dlopen(0, RTLD_NOW);
     588                 :            : 
     589                 :            :         /* if dlh is NULL then we are in static binary */
     590         [ -  + ]:       3501 :         if (dlh == NULL)
     591                 :          0 :                 ucl_object_replace_key(config, ucl_object_frombool(false), "PKG_ENABLE_PLUGINS", 18, false);
     592                 :            :         else
     593                 :       3501 :                 dlclose(dlh);
     594                 :            : 
     595                 :       3501 :         return;
     596                 :            : }
     597                 :            : 
     598                 :            : static void
     599                 :       3370 : add_repo(const ucl_object_t *obj, struct pkg_repo *r, const char *rname, pkg_init_flags flags)
     600                 :            : {
     601                 :            :         const ucl_object_t *cur, *enabled, *env;
     602                 :       3370 :         ucl_object_iter_t it = NULL;
     603                 :            :         struct pkg_kv *kv;
     604                 :       3370 :         bool enable = true;
     605                 :       3370 :         const char *url = NULL, *pubkey = NULL, *mirror_type = NULL;
     606                 :       3370 :         const char *signature_type = NULL, *fingerprints = NULL;
     607                 :            :         const char *key;
     608                 :       3370 :         const char *type = NULL;
     609                 :       3370 :         int use_ipvx = 0;
     610                 :       3370 :         int priority = 0;
     611                 :            : 
     612                 :       3370 :         pkg_debug(1, "PkgConfig: parsing repository object %s", rname);
     613                 :            : 
     614                 :       3370 :         env = NULL;
     615                 :       3370 :         enabled = ucl_object_find_key(obj, "enabled");
     616         [ +  + ]:       3370 :         if (enabled == NULL)
     617                 :        280 :                 enabled = ucl_object_find_key(obj, "ENABLED");
     618         [ +  + ]:       3370 :         if (enabled != NULL) {
     619                 :       3090 :                 enable = ucl_object_toboolean(enabled);
     620   [ -  +  #  # ]:       3090 :                 if (!enable && r != NULL) {
     621                 :            :                         /*
     622                 :            :                          * We basically want to remove the existing repo r and
     623                 :            :                          * forget all stuff parsed
     624                 :            :                          */
     625                 :          0 :                         pkg_debug(1, "PkgConfig: disabling repo %s", rname);
     626   [ #  #  #  #  :          0 :                         LL_DELETE(repos, r);
             #  #  #  # ]
     627                 :          0 :                         pkg_repo_free(r);
     628                 :          0 :                         return;
     629                 :            :                 }
     630                 :       3090 :         }
     631                 :            : 
     632         [ +  + ]:      18284 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     633                 :      14914 :                 key = ucl_object_key(cur);
     634         [ +  - ]:      14914 :                 if (key == NULL)
     635                 :          0 :                         continue;
     636                 :            : 
     637         [ +  + ]:      14914 :                 if (strcasecmp(key, "url") == 0) {
     638         [ +  - ]:       3370 :                         if (cur->type != UCL_STRING) {
     639                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     640                 :            :                                     "'%s' key of the '%s' repo",
     641                 :          0 :                                     key, rname);
     642                 :          0 :                                 return;
     643                 :            :                         }
     644                 :       3370 :                         url = ucl_object_tostring(cur);
     645         [ +  + ]:      14914 :                 } else if (strcasecmp(key, "pubkey") == 0) {
     646         [ +  - ]:          8 :                         if (cur->type != UCL_STRING) {
     647                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     648                 :            :                                     "'%s' key of the '%s' repo",
     649                 :          0 :                                     key, rname);
     650                 :          0 :                                 return;
     651                 :            :                         }
     652                 :          8 :                         pubkey = ucl_object_tostring(cur);
     653         [ +  + ]:      11544 :                 } else if (strcasecmp(key, "mirror_type") == 0) {
     654         [ +  - ]:       2802 :                         if (cur->type != UCL_STRING) {
     655                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     656                 :            :                                     "'%s' key of the '%s' repo",
     657                 :          0 :                                     key, rname);
     658                 :          0 :                                 return;
     659                 :            :                         }
     660                 :       2802 :                         mirror_type = ucl_object_tostring(cur);
     661         [ +  + ]:      11536 :                 } else if (strcasecmp(key, "signature_type") == 0) {
     662         [ +  - ]:       2818 :                         if (cur->type != UCL_STRING) {
     663                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     664                 :            :                                     "'%s' key of the '%s' repo",
     665                 :          0 :                                     key, rname);
     666                 :          0 :                                 return;
     667                 :            :                         }
     668                 :       2818 :                         signature_type = ucl_object_tostring(cur);
     669         [ +  + ]:       8734 :                 } else if (strcasecmp(key, "fingerprints") == 0) {
     670         [ +  - ]:       2810 :                         if (cur->type != UCL_STRING) {
     671                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     672                 :            :                                     "'%s' key of the '%s' repo",
     673                 :          0 :                                     key, rname);
     674                 :          0 :                                 return;
     675                 :            :                         }
     676                 :       2810 :                         fingerprints = ucl_object_tostring(cur);
     677         [ +  - ]:       5916 :                 } else if (strcasecmp(key, "type") == 0) {
     678         [ #  # ]:          0 :                         if (cur->type != UCL_STRING) {
     679                 :          0 :                                 pkg_emit_error("Expecting a string for the "
     680                 :            :                                         "'%s' key of the '%s' repo",
     681                 :          0 :                                         key, rname);
     682                 :          0 :                                 return;
     683                 :            :                         }
     684                 :          0 :                         type = ucl_object_tostring(cur);
     685         [ +  - ]:       3106 :                 } else if (strcasecmp(key, "ip_version") == 0) {
     686         [ #  # ]:          0 :                         if (cur->type != UCL_INT) {
     687                 :          0 :                                 pkg_emit_error("Expecting a integer for the "
     688                 :            :                                         "'%s' key of the '%s' repo",
     689                 :          0 :                                         key, rname);
     690                 :          0 :                                 return;
     691                 :            :                         }
     692                 :          0 :                         use_ipvx = ucl_object_toint(cur);
     693   [ #  #  #  # ]:          0 :                         if (use_ipvx != 4 && use_ipvx != 6)
     694                 :          0 :                                 use_ipvx = 0;
     695         [ +  + ]:       3106 :                 } else if (strcasecmp(key, "priority") == 0) {
     696         [ +  - ]:         16 :                         if (cur->type != UCL_INT) {
     697                 :          0 :                                 pkg_emit_error("Expecting a integer for the "
     698                 :            :                                         "'%s' key of the '%s' repo",
     699                 :          0 :                                         key, rname);
     700                 :          0 :                                 return;
     701                 :            :                         }
     702                 :         16 :                         priority = ucl_object_toint(cur);
     703         [ -  + ]:       3106 :                 } else if (strcasecmp(key, "env") == 0) {
     704         [ #  # ]:          0 :                         if (cur->type != UCL_OBJECT) {
     705                 :          0 :                                 pkg_emit_error("Expecting an object for the "
     706                 :            :                                         "'%s' key of the '%s' repo",
     707                 :          0 :                                         key, rname);
     708                 :          0 :                         }
     709                 :          0 :                         env = cur;
     710                 :          0 :                 }
     711                 :            :         }
     712                 :            : 
     713   [ +  +  -  + ]:       3370 :         if (r == NULL && url == NULL) {
     714                 :          0 :                 pkg_debug(1, "No repo and no url for %s", rname);
     715                 :          0 :                 return;
     716                 :            :         }
     717                 :            : 
     718         [ +  + ]:       3370 :         if (r == NULL)
     719                 :       3350 :                 r = pkg_repo_new(rname, url, type);
     720                 :            :         else
     721                 :         20 :                 pkg_repo_overwrite(r, rname, url, type);
     722                 :            : 
     723         [ +  + ]:       3370 :         if (signature_type != NULL) {
     724         [ +  + ]:       2818 :                 if (strcasecmp(signature_type, "pubkey") == 0)
     725                 :          8 :                         r->signature_type = SIG_PUBKEY;
     726         [ +  - ]:       2810 :                 else if (strcasecmp(signature_type, "fingerprints") == 0)
     727                 :       2810 :                         r->signature_type = SIG_FINGERPRINT;
     728                 :            :                 else
     729                 :          0 :                         r->signature_type = SIG_NONE;
     730                 :       2818 :         }
     731                 :            : 
     732                 :            : 
     733         [ +  + ]:       3370 :         if (fingerprints != NULL) {
     734                 :       2810 :                 free(r->fingerprints);
     735                 :       2810 :                 r->fingerprints = xstrdup(fingerprints);
     736                 :       2810 :         }
     737                 :            : 
     738         [ +  + ]:       3370 :         if (pubkey != NULL) {
     739                 :          8 :                 free(r->pubkey);
     740                 :          8 :                 r->pubkey = xstrdup(pubkey);
     741                 :          8 :         }
     742                 :            : 
     743                 :       3370 :         r->enable = enable;
     744                 :       3370 :         r->priority = priority;
     745                 :            : 
     746         [ +  + ]:       3370 :         if (mirror_type != NULL) {
     747         [ -  + ]:       2802 :                 if (strcasecmp(mirror_type, "srv") == 0)
     748                 :       2802 :                         r->mirror_type = SRV;
     749         [ #  # ]:          0 :                 else if (strcasecmp(mirror_type, "http") == 0)
     750                 :          0 :                         r->mirror_type = HTTP;
     751                 :            :                 else
     752                 :          0 :                         r->mirror_type = NOMIRROR;
     753                 :       2802 :         }
     754                 :            : 
     755         [ -  + ]:       3370 :         if ((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4)
     756                 :          0 :                 use_ipvx = 4;
     757         [ +  - ]:       3370 :         else if ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)
     758                 :          0 :                 use_ipvx = 6;
     759                 :            : 
     760   [ +  -  -  + ]:       3370 :         if (use_ipvx != 4 && use_ipvx != 6)
     761                 :       3370 :                 use_ipvx = pkg_object_int(pkg_config_get("IP_VERSION"));
     762                 :            : 
     763         [ -  + ]:       3370 :         if (use_ipvx == 4)
     764                 :          0 :                 r->flags = REPO_FLAGS_USE_IPV4;
     765         [ +  - ]:       3370 :         else if (use_ipvx == 6)
     766                 :          0 :                 r->flags = REPO_FLAGS_USE_IPV6;
     767                 :            : 
     768         [ -  + ]:       3370 :         if (env != NULL) {
     769                 :          0 :                 it = NULL;
     770         [ #  # ]:          0 :                 while ((cur = ucl_iterate_object(env, &it, true))) {
     771                 :          0 :                         kv = pkg_kv_new(ucl_object_key(cur),
     772                 :          0 :                             ucl_object_tostring_forced(cur));
     773         [ #  # ]:          0 :                         DL_APPEND(r->env, kv);
     774                 :            :                 }
     775                 :          0 :         }
     776                 :       3370 : }
     777                 :            : 
     778                 :            : static void
     779                 :        189 : add_repo_obj(const ucl_object_t *obj, const char *file, pkg_init_flags flags)
     780                 :            : {
     781                 :            :         struct pkg_repo *r;
     782                 :            :         const char *key;
     783                 :            : 
     784                 :        189 :         key = ucl_object_key(obj);
     785                 :        189 :         pkg_debug(1, "PkgConfig: parsing repo key '%s' in file '%s'", key, file);
     786                 :        189 :         r = pkg_repo_find(key);
     787         [ +  + ]:        189 :         if (r != NULL)
     788                 :         20 :                 pkg_debug(1, "PkgConfig: overwriting repository %s", key);
     789                 :        189 :        add_repo(obj, r, key, flags);
     790                 :        189 : }
     791                 :            : 
     792                 :            : static void
     793                 :       5939 : walk_repo_obj(const ucl_object_t *obj, const char *file, pkg_init_flags flags)
     794                 :            : {
     795                 :            :         const ucl_object_t *cur;
     796                 :       5939 :         ucl_object_iter_t it = NULL;
     797                 :            :         struct pkg_repo *r;
     798                 :            :         const char *key;
     799                 :            : 
     800         [ +  + ]:       9120 :         while ((cur = ucl_iterate_object(obj, &it, true))) {
     801                 :       3181 :                 key = ucl_object_key(cur);
     802                 :       3181 :                 pkg_debug(1, "PkgConfig: parsing key '%s'", key);
     803                 :       3181 :                 r = pkg_repo_find(key);
     804         [ +  - ]:       3181 :                 if (r != NULL)
     805                 :          0 :                         pkg_debug(1, "PkgConfig: overwriting repository %s", key);
     806         [ -  + ]:       3181 :                 if (cur->type == UCL_OBJECT)
     807                 :       3181 :                         add_repo(cur, r, key, flags);
     808                 :            :                 else
     809                 :          0 :                         pkg_emit_error("Ignoring bad configuration entry in %s: %s",
     810                 :          0 :                             file, ucl_object_emit(cur, UCL_EMIT_YAML));
     811                 :            :         }
     812                 :       5939 : }
     813                 :            : 
     814                 :            : static void
     815                 :       5939 : load_repo_file(int dfd, const char *repodir, const char *repofile,
     816                 :            :     pkg_init_flags flags, struct os_info *oi)
     817                 :            : {
     818                 :            :         struct ucl_parser *p;
     819                 :       5939 :         ucl_object_t *obj = NULL;
     820                 :       5939 :         const char *myarch = NULL;
     821                 :       5939 :         const char *myarch_legacy = NULL;
     822                 :            :         int fd;
     823                 :            : 
     824                 :       5939 :         p = ucl_parser_new(0);
     825                 :            : 
     826                 :       5939 :         myarch = pkg_object_string(pkg_config_get("ABI"));
     827                 :       5939 :         ucl_parser_register_variable (p, "ABI", myarch);
     828                 :            : 
     829                 :       5939 :         myarch_legacy = pkg_object_string(pkg_config_get("ALTABI"));
     830                 :       5939 :         ucl_parser_register_variable (p, "ALTABI", myarch_legacy);
     831                 :            : #ifdef __FreeBSD__
     832                 :       5939 :         ucl_parser_register_variable(p, "OSVERSION", myosversion);
     833                 :            : #endif
     834         [ -  + ]:       5939 :         if (oi->name != NULL) {
     835                 :       5939 :                 ucl_parser_register_variable(p, "OSNAME", oi->name);
     836                 :       5939 :         }
     837         [ -  + ]:       5939 :         if (oi->version != NULL) {
     838                 :       5939 :                 ucl_parser_register_variable(p, "RELEASE", oi->version);
     839                 :       5939 :         }
     840         [ -  + ]:       5939 :         if (oi->version_major != NULL) {
     841                 :       5939 :                 ucl_parser_register_variable(p, "VERSION_MAJOR", oi->version_major);
     842                 :       5939 :         }
     843         [ -  + ]:       5939 :         if (oi->version_minor != NULL) {
     844                 :       5939 :                 ucl_parser_register_variable(p, "VERSION_MINOR", oi->version_minor);
     845                 :       5939 :         }
     846         [ -  + ]:       5939 :         if (oi->arch != NULL) {
     847                 :       5939 :                 ucl_parser_register_variable(p, "ARCH", oi->arch);
     848                 :       5939 :         }
     849                 :            : 
     850                 :       5939 :         errno = 0;
     851                 :       5939 :         obj = NULL;
     852                 :            : 
     853                 :       5939 :         pkg_debug(1, "PKgConfig: loading %s/%s", repodir, repofile);
     854                 :       5939 :         fd = openat(dfd, repofile, O_RDONLY);
     855         [ +  - ]:       5939 :         if (fd == -1) {
     856                 :          0 :                 pkg_errno("Unable to open '%s/%s'", repodir, repofile);
     857                 :          0 :                 return;
     858                 :            :         }
     859         [ +  - ]:       5939 :         if (!ucl_parser_add_fd(p, fd)) {
     860                 :          0 :                 pkg_emit_error("Error parsing: '%s/%s': %s", repodir,
     861                 :          0 :                     repofile, ucl_parser_get_error(p));
     862                 :          0 :                 ucl_parser_free(p);
     863                 :          0 :                 close(fd);
     864                 :          0 :                 return;
     865                 :            :         }
     866                 :       5939 :         close(fd);
     867                 :            : 
     868                 :       5939 :         obj = ucl_parser_get_object(p);
     869         [ +  - ]:       5939 :         if (obj == NULL) {
     870                 :          0 :                 ucl_parser_free(p);
     871                 :          0 :                 return;
     872                 :            :         }
     873                 :            : 
     874                 :       5939 :         ucl_parser_free(p);
     875         [ +  - ]:       5939 :         if (obj->type == UCL_OBJECT)
     876                 :       5939 :                 walk_repo_obj(obj, repofile, flags);
     877                 :            : 
     878                 :       5939 :         ucl_object_unref(obj);
     879                 :       5939 : }
     880                 :            : 
     881                 :            : static int
     882                 :      18097 : configfile(const struct dirent *dp)
     883                 :            : {
     884                 :            :         const char *p;
     885                 :            :         size_t n;
     886                 :            : 
     887         [ +  + ]:      18097 :         if (dp->d_name[0] == '.')
     888                 :      11794 :                 return (0);
     889                 :            : 
     890                 :       6303 :         n = strlen(dp->d_name);
     891         [ +  + ]:       6303 :         if (n <= 5)
     892                 :         56 :                 return (0);
     893                 :            : 
     894                 :       6247 :         p = &dp->d_name[n - 5];
     895         [ +  + ]:       6247 :         if (strcmp(p, ".conf") != 0)
     896                 :        308 :                 return (0);
     897                 :       5939 :         return (1);
     898                 :      18097 : }
     899                 :            : 
     900                 :            : static void
     901                 :       6166 : load_repo_files(const char *repodir, pkg_init_flags flags, struct os_info *oi)
     902                 :            : {
     903                 :            :         struct dirent **ent;
     904                 :            :         int nents, i, fd;
     905                 :            : 
     906                 :       6166 :         pkg_debug(1, "PkgConfig: loading repositories in %s", repodir);
     907         [ +  + ]:       6166 :         if ((fd = open(repodir, O_DIRECTORY|O_CLOEXEC)) == -1)
     908                 :        269 :                 return;
     909                 :            : 
     910                 :       5897 :         nents = scandir(repodir, &ent, configfile, alphasort);
     911         [ +  + ]:      11836 :         for (i = 0; i < nents; i++) {
     912                 :       5939 :                 load_repo_file(fd, repodir, ent[i]->d_name, flags, oi);
     913                 :       5939 :                 free(ent[i]);
     914                 :       5939 :         }
     915         [ -  + ]:       5897 :         if (nents >= 0)
     916                 :       5897 :                 free(ent);
     917                 :       5897 :         close(fd);
     918                 :       6166 : }
     919                 :            : 
     920                 :            : static void
     921                 :       3501 : load_repositories(const char *repodir, pkg_init_flags flags, struct os_info *oi)
     922                 :            : {
     923                 :            :         const pkg_object *reposlist, *cur;
     924                 :       3501 :         pkg_iter it = NULL;
     925                 :            : 
     926         [ +  + ]:       3501 :         if (repodir != NULL) {
     927                 :         21 :                 load_repo_files(repodir, flags, oi);
     928                 :         21 :                 return;
     929                 :            :         }
     930                 :            : 
     931                 :       3480 :         reposlist = pkg_config_get("REPOS_DIR");
     932         [ +  + ]:       9625 :         while ((cur = pkg_object_iterate(reposlist, &it)))
     933                 :       6145 :                 load_repo_files(pkg_object_string(cur), flags, oi);
     934                 :       3501 : }
     935                 :            : 
     936                 :            : bool
     937                 :       3501 : pkg_compiled_for_same_os_major(void)
     938                 :            : {
     939                 :            : #ifdef OSMAJOR
     940                 :            :         const char      *myabi;
     941                 :            :         int              osmajor;
     942                 :            : 
     943         [ +  + ]:       3501 :         if (getenv("IGNORE_OSMAJOR") != NULL)
     944                 :          4 :                 return (true);
     945                 :            : 
     946                 :       3497 :         myabi = pkg_object_string(pkg_config_get("ABI"));
     947                 :       3497 :         myabi = strchr(myabi,':');
     948         [ -  + ]:       3497 :         if (myabi == NULL) {
     949                 :          0 :                 pkg_emit_error("Invalid ABI");
     950                 :          0 :                 return (false);
     951                 :            :         }
     952                 :       3497 :         myabi++;
     953                 :            : 
     954                 :       3497 :         osmajor = (int) strtol(myabi, NULL, 10);
     955                 :            : 
     956                 :       3497 :         return (osmajor == OSMAJOR);
     957                 :            : #else
     958                 :            :         return (true);          /* Can't tell, so assume yes  */
     959                 :            : #endif
     960                 :       3501 : }
     961                 :            : 
     962                 :            : 
     963                 :            : int
     964                 :          0 : pkg_init(const char *path, const char *reposdir)
     965                 :            : {
     966                 :          0 :         return (pkg_ini(path, reposdir, 0));
     967                 :            : }
     968                 :            : 
     969                 :            : static const char *
     970                 :          0 : type_to_string(int type)
     971                 :            : {
     972         [ #  # ]:          0 :         if (type == UCL_ARRAY)
     973                 :          0 :                 return ("array");
     974         [ #  # ]:          0 :         if (type == UCL_OBJECT)
     975                 :          0 :                 return ("object");
     976         [ #  # ]:          0 :         if (type == UCL_STRING)
     977                 :          0 :                 return ("string");
     978         [ #  # ]:          0 :         if (type == UCL_INT)
     979                 :          0 :                 return ("integer");
     980         [ #  # ]:          0 :         if (type == UCL_BOOLEAN)
     981                 :          0 :                 return ("boolean");
     982                 :          0 :         return ("unknown");
     983                 :          0 : }
     984                 :            : int
     985                 :       3501 : pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
     986                 :            : {
     987                 :       3501 :         struct ucl_parser *p = NULL;
     988                 :            :         size_t i;
     989                 :       3501 :         const char *val = NULL;
     990                 :            :         const char *buf, *walk, *value, *key, *k;
     991                 :       3501 :         const char *evkey = NULL;
     992                 :       3501 :         const char *nsname = NULL;
     993                 :       3501 :         const char *metalog = NULL;
     994                 :       3501 :         const char *useragent = NULL;
     995                 :       3501 :         const char *evpipe = NULL;
     996                 :            :         const char *url;
     997                 :       3501 :         struct pkg_repo *repo = NULL;
     998                 :            :         const ucl_object_t *cur, *object;
     999                 :       3501 :         ucl_object_t *obj = NULL, *o, *ncfg;
    1000                 :       3501 :         ucl_object_iter_t it = NULL;
    1001                 :       3501 :         xstring *ukey = NULL;
    1002                 :       3501 :         bool fatal_errors = false;
    1003                 :       3501 :         int conffd = -1;
    1004                 :       3501 :         char *tmp = NULL;
    1005                 :            :         struct os_info oi;
    1006                 :            :         size_t ukeylen;
    1007                 :       3501 :         int err = EPKG_OK;
    1008                 :            : 
    1009                 :       3501 :         k = NULL;
    1010                 :       3501 :         o = NULL;
    1011   [ +  +  +  - ]:       3501 :         if (ctx.rootfd == -1 && (ctx.rootfd = open("/", O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
    1012                 :          0 :                 pkg_emit_error("Impossible to open /");
    1013                 :            :                 /* Note: Not goto out since oi.arch hasn't been initialized yet. */
    1014                 :          0 :                 return (EPKG_FATAL);
    1015                 :            :         }
    1016                 :            : 
    1017                 :       3501 :         memset(&oi, 0, sizeof(oi));
    1018                 :       3501 :         pkg_get_myarch(myabi, BUFSIZ, &oi);
    1019                 :       3501 :         pkg_get_myarch_legacy(myabi_legacy, BUFSIZ);
    1020                 :            : #ifdef __FreeBSD__
    1021                 :       3501 :         ctx.osversion = oi.osversion;
    1022                 :       3501 :         snprintf(myosversion, sizeof(myosversion), "%d", ctx.osversion);
    1023                 :            : #endif
    1024         [ -  + ]:       3501 :         if (parsed != false) {
    1025                 :          0 :                 pkg_emit_error("pkg_init() must only be called once");
    1026                 :          0 :                 err = EPKG_FATAL;
    1027                 :          0 :                 goto out;
    1028                 :            :         }
    1029                 :            : 
    1030   [ -  +  #  # ]:       3501 :         if (((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4) &&
    1031                 :          0 :             ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)) {
    1032                 :          0 :                 pkg_emit_error("Invalid flags for pkg_init()");
    1033                 :          0 :                 err = EPKG_FATAL;
    1034                 :          0 :                 goto out;
    1035                 :            :         }
    1036                 :            : 
    1037                 :       3501 :         config = ucl_object_typed_new(UCL_OBJECT);
    1038                 :            : 
    1039         [ +  + ]:     241569 :         for (i = 0; i < c_size; i++) {
    1040   [ +  +  +  +  :     238068 :                 switch (c[i].type) {
                   -  + ]
    1041                 :            :                 case PKG_STRING:
    1042                 :      80523 :                         tmp = NULL;
    1043   [ +  +  +  +  :      80523 :                         if (c[i].def != NULL && c[i].def[0] == '/' &&
                   +  + ]
    1044                 :      24507 :                             ctx.pkg_rootdir != NULL) {
    1045                 :       2121 :                                 xasprintf(&tmp, "%s%s", ctx.pkg_rootdir, c[i].def);
    1046                 :       2121 :                         }
    1047                 :      80523 :                         obj = ucl_object_fromstring_common(
    1048   [ +  +  +  + ]:      80523 :                             c[i].def != NULL ? tmp != NULL ? tmp : c[i].def : "", 0, UCL_STRING_TRIM);
    1049                 :      80523 :                         free(tmp);
    1050                 :     161046 :                         ucl_object_insert_key(config, obj,
    1051                 :      80523 :                             c[i].key, strlen(c[i].key), false);
    1052                 :      80523 :                         break;
    1053                 :            :                 case PKG_INT:
    1054                 :      70020 :                         ucl_object_insert_key(config,
    1055                 :      35010 :                             ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT),
    1056                 :      35010 :                             c[i].key, strlen(c[i].key), false);
    1057                 :      35010 :                         break;
    1058                 :            :                 case PKG_BOOL:
    1059                 :     175050 :                         ucl_object_insert_key(config,
    1060                 :      87525 :                             ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN),
    1061                 :      87525 :                             c[i].key, strlen(c[i].key), false);
    1062                 :      87525 :                         break;
    1063                 :            :                 case PKG_OBJECT:
    1064                 :      10503 :                         obj = ucl_object_typed_new(UCL_OBJECT);
    1065         [ +  - ]:      10503 :                         if (c[i].def != NULL) {
    1066                 :          0 :                                 walk = buf = c[i].def;
    1067         [ #  # ]:          0 :                                 while ((buf = strchr(buf, ',')) != NULL) {
    1068                 :          0 :                                         key = walk;
    1069                 :          0 :                                         value = walk;
    1070         [ #  # ]:          0 :                                         while (*value != ',') {
    1071         [ #  # ]:          0 :                                                 if (*value == '=')
    1072                 :          0 :                                                         break;
    1073                 :          0 :                                                 value++;
    1074                 :            :                                         }
    1075                 :          0 :                                         ucl_object_insert_key(obj,
    1076                 :          0 :                                             ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
    1077                 :          0 :                                             key, value - key, false);
    1078                 :          0 :                                         buf++;
    1079                 :          0 :                                         walk = buf;
    1080                 :            :                                 }
    1081                 :          0 :                                 key = walk;
    1082                 :          0 :                                 value = walk;
    1083         [ #  # ]:          0 :                                 while (*value != ',') {
    1084         [ #  # ]:          0 :                                         if (*value == '=')
    1085                 :          0 :                                                 break;
    1086                 :          0 :                                         value++;
    1087                 :            :                                 }
    1088         [ #  # ]:          0 :                                 if (o == NULL)
    1089                 :          0 :                                         o = ucl_object_typed_new(UCL_OBJECT);
    1090                 :          0 :                                 ucl_object_insert_key(o,
    1091                 :          0 :                                     ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
    1092                 :          0 :                                     key, value - key, false);
    1093                 :          0 :                         }
    1094                 :      21006 :                         ucl_object_insert_key(config, obj,
    1095                 :      10503 :                             c[i].key, strlen(c[i].key), false);
    1096                 :      10503 :                         break;
    1097                 :            :                 case PKG_ARRAY:
    1098                 :      24507 :                         obj = ucl_object_typed_new(UCL_ARRAY);
    1099         [ +  + ]:      24507 :                         if (c[i].def != NULL) {
    1100                 :      17505 :                                 walk = buf = c[i].def;
    1101         [ +  + ]:      56016 :                                 while ((buf = strchr(buf, ',')) != NULL) {
    1102                 :      77022 :                                         ucl_array_append(obj,
    1103                 :      38511 :                                             ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
    1104                 :      38511 :                                         buf++;
    1105                 :      38511 :                                         walk = buf;
    1106                 :            :                                 }
    1107                 :      35010 :                                 ucl_array_append(obj,
    1108                 :      17505 :                                     ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
    1109                 :      17505 :                         }
    1110                 :      49014 :                         ucl_object_insert_key(config, obj,
    1111                 :      24507 :                             c[i].key, strlen(c[i].key), false);
    1112                 :      24507 :                         break;
    1113                 :            :                 }
    1114                 :     238068 :         }
    1115                 :            : 
    1116         [ +  + ]:       3501 :         if (path == NULL)
    1117                 :       3086 :                 conffd = openat(ctx.rootfd, &PREFIX"/etc/pkg.conf"[1], 0);
    1118                 :            :         else
    1119                 :        415 :                 conffd = open(path, O_RDONLY);
    1120   [ +  +  +  - ]:       3501 :         if (conffd == -1 && errno != ENOENT) {
    1121         [ #  # ]:          0 :                 pkg_errno("Cannot open %s/%s",
    1122                 :            :                     ctx.pkg_rootdir != NULL ? ctx.pkg_rootdir : "",
    1123                 :            :                     path);
    1124                 :          0 :         }
    1125                 :            : 
    1126                 :       3501 :         p = ucl_parser_new(0);
    1127                 :       3501 :         ucl_parser_register_variable (p, "ABI", myabi);
    1128                 :       3501 :         ucl_parser_register_variable (p, "ALTABI", myabi_legacy);
    1129                 :            : #ifdef __FreeBSD__
    1130                 :       3501 :         ucl_parser_register_variable(p, "OSVERSION", myosversion);
    1131                 :            : #endif
    1132         [ -  + ]:       3501 :         if (oi.name != NULL) {
    1133                 :       3501 :                 ucl_parser_register_variable(p, "OSNAME", oi.name);
    1134                 :       3501 :         }
    1135         [ -  + ]:       3501 :         if (oi.version != NULL) {
    1136                 :       3501 :                 ucl_parser_register_variable(p, "RELEASE", oi.version);
    1137                 :       3501 :         }
    1138         [ -  + ]:       3501 :         if (oi.version_major != NULL) {
    1139                 :       3501 :                 ucl_parser_register_variable(p, "VERSION_MAJOR", oi.version_major);
    1140                 :       3501 :         }
    1141         [ -  + ]:       3501 :         if (oi.version_minor != NULL) {
    1142                 :       3501 :                 ucl_parser_register_variable(p, "VERSION_MINOR", oi.version_minor);
    1143                 :       3501 :         }
    1144         [ -  + ]:       3501 :         if (oi.arch != NULL) {
    1145                 :       3501 :                 ucl_parser_register_variable(p, "ARCH", oi.arch);
    1146                 :       3501 :         }
    1147                 :            : 
    1148                 :       3501 :         errno = 0;
    1149                 :       3501 :         obj = NULL;
    1150         [ +  + ]:       3501 :         if (conffd != -1) {
    1151         [ +  - ]:       3090 :                 if (!ucl_parser_add_fd(p, conffd)) {
    1152                 :          0 :                         pkg_emit_error("Invalid configuration file: %s", ucl_parser_get_error(p));
    1153                 :          0 :                 }
    1154                 :       3090 :                 close(conffd);
    1155                 :       3090 :         }
    1156                 :            : 
    1157                 :       3501 :         obj = ucl_parser_get_object(p);
    1158                 :       3501 :         ncfg = NULL;
    1159                 :       3501 :         ukey = NULL;
    1160   [ +  +  +  + ]:       6947 :         while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) {
    1161         [ +  + ]:       3446 :                 xstring_renew(ukey);
    1162                 :       3446 :                 key = ucl_object_key(cur);
    1163         [ +  + ]:      23775 :                 for (i = 0; key[i] != '\0'; i++)
    1164                 :      20329 :                         fputc(toupper(key[i]), ukey->fp);
    1165                 :       3446 :                 fflush(ukey->fp);
    1166                 :       3446 :                 ukeylen = strlen(ukey->buf);
    1167                 :       3446 :                 object = ucl_object_find_keyl(config, ukey->buf, ukeylen);
    1168                 :            : 
    1169   [ +  -  -  + ]:       6892 :                 if (strncasecmp(ukey->buf, "PACKAGESITE", ukeylen) == 0 ||
    1170         [ +  - ]:       3446 :                     strncasecmp(ukey->buf, "PUBKEY", ukeylen) == 0 ||
    1171                 :       3446 :                     strncasecmp(ukey->buf, "MIRROR_TYPE", ukeylen) == 0) {
    1172                 :          0 :                         pkg_emit_error("%s in pkg.conf is no longer "
    1173                 :            :                             "supported.  Convert to the new repository style."
    1174                 :          0 :                             "  See pkg.conf(5)", ukey->buf);
    1175                 :          0 :                         fatal_errors = true;
    1176                 :          0 :                         continue;
    1177                 :            :                 }
    1178                 :            : 
    1179                 :            :                 /* ignore unknown keys */
    1180         [ +  - ]:       3446 :                 if (object == NULL)
    1181                 :          0 :                         continue;
    1182                 :            : 
    1183         [ -  + ]:       3446 :                 if (object->type != cur->type) {
    1184                 :          0 :                         pkg_emit_error("Malformed key %s, got '%s' expecting "
    1185                 :          0 :                             "'%s', ignoring", key,
    1186                 :          0 :                             type_to_string(cur->type),
    1187                 :          0 :                             type_to_string(object->type));
    1188                 :          0 :                         continue;
    1189                 :            :                 }
    1190                 :            : 
    1191         [ +  + ]:       3446 :                 if (ncfg == NULL)
    1192                 :       3052 :                         ncfg = ucl_object_typed_new(UCL_OBJECT);
    1193                 :       6892 :                 ucl_object_insert_key(ncfg, ucl_object_copy(cur), ukey->buf,
    1194                 :       3446 :                     ukeylen, true);
    1195                 :            :         }
    1196                 :       3501 :         xstring_free(ukey);
    1197                 :            : 
    1198         [ -  + ]:       3501 :         if (fatal_errors) {
    1199                 :          0 :                 ucl_object_unref(ncfg);
    1200                 :          0 :                 ucl_parser_free(p);
    1201                 :          0 :                 err = EPKG_FATAL;
    1202                 :          0 :                 goto out;
    1203                 :            :         }
    1204                 :            : 
    1205         [ +  + ]:       3501 :         if (ncfg != NULL) {
    1206                 :       3052 :                 it = NULL;
    1207         [ +  + ]:       6498 :                 while (( cur = ucl_iterate_object(ncfg, &it, true))) {
    1208                 :       3446 :                         key = ucl_object_key(cur);
    1209                 :       3446 :                         ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true);
    1210                 :            :                 }
    1211                 :       3052 :         }
    1212                 :       3501 :         ucl_object_unref(ncfg);
    1213                 :       3501 :         ncfg = NULL;
    1214                 :       3501 :         it = NULL;
    1215         [ +  + ]:     241569 :         while ((cur = ucl_iterate_object(config, &it, true))) {
    1216                 :     238068 :                 o = NULL;
    1217                 :     238068 :                 key = ucl_object_key(cur);
    1218                 :     238068 :                 val = getenv(key);
    1219         [ +  + ]:     238068 :                 if (val == NULL)
    1220                 :     230379 :                         continue;
    1221   [ -  +  -  +  :       7689 :                 switch (cur->type) {
                   +  + ]
    1222                 :            :                 case UCL_STRING:
    1223                 :       3629 :                         o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM);
    1224                 :       3629 :                         break;
    1225                 :            :                 case UCL_INT:
    1226                 :          0 :                         o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT);
    1227         [ #  # ]:          0 :                         if (o->type != UCL_INT) {
    1228                 :          0 :                                 pkg_emit_error("Invalid type for environment "
    1229                 :            :                                     "variable %s, got %s, while expecting an integer",
    1230                 :          0 :                                     key, val);
    1231                 :          0 :                                 ucl_object_unref(o);
    1232                 :          0 :                                 continue;
    1233                 :            :                         }
    1234                 :          0 :                         break;
    1235                 :            :                 case UCL_BOOLEAN:
    1236                 :       3499 :                         o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN);
    1237         [ -  + ]:       3499 :                         if (o->type != UCL_BOOLEAN) {
    1238                 :          0 :                                 pkg_emit_error("Invalid type for environment "
    1239                 :            :                                     "variable %s, got %s, while expecting a boolean",
    1240                 :          0 :                                     key, val);
    1241                 :          0 :                                 ucl_object_unref(o);
    1242                 :          0 :                                 continue;
    1243                 :            :                         }
    1244                 :       3499 :                         break;
    1245                 :            :                 case UCL_OBJECT:
    1246                 :         52 :                         o = ucl_object_typed_new(UCL_OBJECT);
    1247                 :         52 :                         walk = buf = val;
    1248         [ +  + ]:        104 :                         while ((buf = strchr(buf, ',')) != NULL) {
    1249                 :         52 :                                 k = walk;
    1250                 :         52 :                                 value = walk;
    1251         [ -  + ]:        624 :                                 while (*value != ',') {
    1252         [ +  + ]:        624 :                                         if (*value == '=')
    1253                 :         52 :                                                 break;
    1254                 :        572 :                                         value++;
    1255                 :            :                                 }
    1256                 :        104 :                                 ucl_object_insert_key(o,
    1257                 :         52 :                                     ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
    1258                 :         52 :                                     k, value - k, false);
    1259                 :         52 :                                 buf++;
    1260                 :         52 :                                 walk = buf;
    1261                 :            :                         }
    1262                 :         52 :                         k = walk;
    1263                 :         52 :                         value = walk;
    1264         [ -  + ]:        260 :                         while (*value != '\0') {
    1265         [ +  + ]:        260 :                                 if (*value == '=')
    1266                 :         52 :                                         break;
    1267                 :        208 :                                 value++;
    1268                 :            :                         }
    1269                 :        104 :                         ucl_object_insert_key(o,
    1270                 :         52 :                             ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
    1271                 :         52 :                             k, value - k, false);
    1272                 :         52 :                         break;
    1273                 :            :                 case UCL_ARRAY:
    1274                 :        509 :                         o = ucl_object_typed_new(UCL_ARRAY);
    1275                 :        509 :                         walk = buf = val;
    1276         [ -  + ]:        509 :                         while ((buf = strchr(buf, ',')) != NULL) {
    1277                 :          0 :                                 ucl_array_append(o,
    1278                 :          0 :                                     ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
    1279                 :          0 :                                 buf++;
    1280                 :          0 :                                 walk = buf;
    1281                 :            :                         }
    1282                 :       1018 :                         ucl_array_append(o,
    1283                 :        509 :                             ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
    1284                 :        509 :                         break;
    1285                 :            :                 default:
    1286                 :            :                         /* ignore other types */
    1287                 :          0 :                         break;
    1288                 :            :                 }
    1289         [ -  + ]:       7689 :                 if (o != NULL) {
    1290         [ +  + ]:       7689 :                         if (ncfg == NULL)
    1291                 :       3488 :                                 ncfg = ucl_object_typed_new(UCL_OBJECT);
    1292                 :       7689 :                         ucl_object_insert_key(ncfg, o, key, strlen(key), true);
    1293                 :       7689 :                 }
    1294                 :            :         }
    1295                 :            : 
    1296         [ +  + ]:       3501 :         if (ncfg != NULL) {
    1297                 :       3488 :                 it = NULL;
    1298         [ +  + ]:      11177 :                 while (( cur = ucl_iterate_object(ncfg, &it, true))) {
    1299                 :       7689 :                         key = ucl_object_key(cur);
    1300                 :       7689 :                         ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true);
    1301                 :            :                 }
    1302                 :       3488 :                 ucl_object_unref(ncfg);
    1303                 :       3488 :         }
    1304                 :            : 
    1305                 :       3501 :         disable_plugins_if_static();
    1306                 :            : 
    1307                 :       3501 :         parsed = true;
    1308                 :       3501 :         ucl_object_unref(obj);
    1309                 :       3501 :         ucl_parser_free(p);
    1310                 :            : 
    1311   [ +  -  -  + ]:       3501 :         if (pkg_object_string(pkg_config_get("ABI")) == NULL ||
    1312                 :       3501 :             strcmp(pkg_object_string(pkg_config_get("ABI")), "unknown") == 0) {
    1313                 :          0 :                 pkg_emit_error("Unable to determine ABI");
    1314                 :          0 :                 err = EPKG_FATAL;
    1315                 :          0 :                 goto out;
    1316                 :            :         }
    1317                 :            : 
    1318                 :       3501 :         pkg_debug(1, "%s", "pkg initialized");
    1319                 :            : 
    1320                 :            : #ifdef __FreeBSD__
    1321                 :       3501 :         ctx.osversion = pkg_object_int(pkg_config_get("OSVERSION"));
    1322                 :            : #endif
    1323                 :            :         /* Start the event pipe */
    1324                 :       3501 :         evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE"));
    1325         [ -  + ]:       3501 :         if (evpipe != NULL)
    1326                 :          0 :                 connect_evpipe(evpipe);
    1327                 :            : 
    1328                 :       3501 :         ctx.debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));
    1329                 :       3501 :         ctx.developer_mode = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
    1330                 :       3501 :         ctx.dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
    1331                 :       3501 :         ctx.cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
    1332                 :       3501 :         ctx.backup_libraries = pkg_object_bool(pkg_config_get("BACKUP_LIBRARIES"));
    1333                 :       3501 :         ctx.backup_library_path = pkg_object_string(pkg_config_get("BACKUP_LIBRARY_PATH"));
    1334                 :       3501 :         ctx.triggers = pkg_object_bool(pkg_config_get("PKG_TRIGGERS_ENABLE"));
    1335                 :       3501 :         ctx.triggers_path = pkg_object_string(pkg_config_get("PKG_TRIGGERS_DIR"));
    1336                 :       3501 :         ctx.compression_level = pkg_object_int(pkg_config_get("COMPRESSION_LEVEL"));
    1337                 :       3501 :         ctx.archive_symlink = pkg_object_bool(pkg_config_get("ARCHIVE_SYMLINK"));
    1338                 :       3501 :         ctx.repo_accept_legacy_pkg = pkg_object_bool(pkg_config_get("REPO_ACCEPT_LEGACY_PKG"));
    1339                 :            : 
    1340                 :       3501 :         it = NULL;
    1341                 :       3501 :         object = ucl_object_find_key(config, "PKG_ENV");
    1342         [ -  + ]:       3501 :         while ((cur = ucl_iterate_object(object, &it, true))) {
    1343                 :          0 :                 evkey = ucl_object_key(cur);
    1344                 :          0 :                 pkg_debug(1, "Setting env var: %s", evkey);
    1345   [ #  #  #  # ]:          0 :                 if (evkey != NULL && evkey[0] != '\0')
    1346                 :          0 :                         setenv(evkey, ucl_object_tostring_forced(cur), 1);
    1347                 :            :         }
    1348                 :            : 
    1349                 :            :         /* Set user-agent */
    1350                 :       3501 :         useragent = pkg_object_string(pkg_config_get("HTTP_USER_AGENT"));
    1351         [ +  - ]:       3501 :         if (useragent != NULL)
    1352                 :       3501 :                 setenv("HTTP_USER_AGENT", useragent, 1);
    1353                 :            :         else
    1354                 :          0 :                 setenv("HTTP_USER_AGENT", "pkg/"PKGVERSION, 1);
    1355                 :            : 
    1356                 :            :         /* load the repositories */
    1357                 :       3501 :         load_repositories(reposdir, flags, &oi);
    1358                 :            : 
    1359                 :       3501 :         object = ucl_object_find_key(config, "REPOSITORIES");
    1360         [ +  + ]:       3690 :         while ((cur = ucl_iterate_object(object, &it, true))) {
    1361                 :        189 :                 add_repo_obj(cur, path, flags);
    1362                 :            :         }
    1363                 :            : 
    1364                 :            :         /* validate the different scheme */
    1365         [ +  + ]:       6851 :         while (pkg_repos(&repo) == EPKG_OK) {
    1366                 :       3350 :                 object = ucl_object_find_key(config, "VALID_URL_SCHEME");
    1367                 :       3350 :                 url = pkg_repo_url(repo);
    1368                 :       3350 :                 buf = strstr(url, ":/");
    1369         [ +  - ]:       3350 :                 if (buf == NULL) {
    1370                 :          0 :                         pkg_emit_error("invalid url: %s", url);
    1371                 :          0 :                         err = EPKG_FATAL;
    1372                 :          0 :                         goto out;
    1373                 :            :                 }
    1374                 :       3350 :                 fatal_errors = true;
    1375                 :       3350 :                 it = NULL;
    1376         [ -  + ]:       5526 :                 while ((cur = ucl_iterate_object(object, &it, true))) {
    1377   [ +  +  +  +  :      16578 :                         if (strncmp(url, ucl_object_tostring_forced(cur),
                   +  + ]
    1378                 :      11052 :                             buf - url) == 0) {
    1379                 :       3350 :                                 fatal_errors = false;
    1380                 :       3350 :                                 break;
    1381                 :            :                         }
    1382                 :            :                 }
    1383                 :            : 
    1384         [ +  - ]:       3350 :                 if (fatal_errors) {
    1385                 :          0 :                         pkg_emit_error("invalid scheme %.*s", (int)(buf - url), url);
    1386                 :          0 :                         err = EPKG_FATAL;
    1387                 :          0 :                         goto out;
    1388                 :            :                 }
    1389                 :            :         }
    1390                 :            : 
    1391                 :            :         /* bypass resolv.conf with specified NAMESERVER if any */
    1392                 :       3501 :         nsname = pkg_object_string(pkg_config_get("NAMESERVER"));
    1393   [ +  +  +  + ]:       3501 :         if (nsname != NULL && set_nameserver(nsname) != 0)
    1394                 :          8 :                         pkg_emit_error("Unable to set nameserver, ignoring");
    1395                 :            : 
    1396                 :            :         /* Open metalog */
    1397                 :       3501 :         metalog = pkg_object_string(pkg_config_get("METALOG"));
    1398         [ +  + ]:       3505 :         if (metalog != NULL) {
    1399         [ +  - ]:          4 :                 if(metalog_open(metalog) != EPKG_OK) {
    1400                 :          0 :                         err = EPKG_FATAL;
    1401                 :          0 :                         goto out;
    1402                 :            :                 }
    1403                 :          4 :         }
    1404                 :            : 
    1405                 :            : out:
    1406                 :       3501 :         free(oi.arch);
    1407                 :       3501 :         free(oi.name);
    1408                 :       3501 :         free(oi.version);
    1409                 :       3501 :         free(oi.version_major);
    1410                 :       3501 :         free(oi.version_minor);
    1411                 :       3501 :         return err;
    1412                 :            : 
    1413                 :       3501 : }
    1414                 :            : 
    1415                 :            : static struct pkg_repo_ops*
    1416                 :       6740 : pkg_repo_find_type(const char *type)
    1417                 :            : {
    1418                 :       6740 :         struct pkg_repo_ops *found = NULL, **cur;
    1419                 :            : 
    1420                 :            :         /* Default repo type */
    1421         [ +  + ]:       6740 :         if (type == NULL)
    1422                 :       3370 :                 return (pkg_repo_find_type("binary"));
    1423                 :            : 
    1424                 :       3370 :         cur = &repos_ops[0];
    1425         [ +  + ]:       6740 :         while (*cur != NULL) {
    1426         [ -  + ]:       3370 :                 if (strcasecmp(type, (*cur)->type) == 0) {
    1427                 :       3370 :                         found = *cur;
    1428                 :       3370 :                 }
    1429                 :       3370 :                 cur ++;
    1430                 :            :         }
    1431                 :            : 
    1432         [ -  + ]:       3370 :         if (found == NULL)
    1433                 :          0 :                 return (pkg_repo_find_type("binary"));
    1434                 :            : 
    1435                 :       3370 :         return (found);
    1436                 :       6740 : }
    1437                 :            : 
    1438                 :            : static struct pkg_repo *
    1439                 :       3350 : pkg_repo_new(const char *name, const char *url, const char *type)
    1440                 :            : {
    1441                 :            :         struct pkg_repo *r;
    1442                 :            : 
    1443                 :       3350 :         r = xcalloc(1, sizeof(struct pkg_repo));
    1444                 :       3350 :         r->ops = pkg_repo_find_type(type);
    1445                 :       3350 :         r->url = xstrdup(url);
    1446                 :       3350 :         r->signature_type = SIG_NONE;
    1447                 :       3350 :         r->mirror_type = NOMIRROR;
    1448                 :       3350 :         r->enable = true;
    1449                 :       3350 :         r->meta = pkg_repo_meta_default();
    1450                 :       3350 :         r->name = xstrdup(name);
    1451         [ +  + ]:       3350 :         DL_APPEND(repos, r);
    1452                 :            : 
    1453                 :       3350 :         return (r);
    1454                 :            : }
    1455                 :            : 
    1456                 :            : static void
    1457                 :         20 : pkg_repo_overwrite(struct pkg_repo *r, const char *name, const char *url,
    1458                 :            :     const char *type)
    1459                 :            : {
    1460                 :            : 
    1461                 :         20 :         free(r->name);
    1462                 :         20 :         r->name = xstrdup(name);
    1463         [ +  - ]:         20 :         if (url != NULL) {
    1464                 :         20 :                 free(r->url);
    1465                 :         20 :                 r->url = xstrdup(url);
    1466                 :         20 :         }
    1467                 :         20 :         r->ops = pkg_repo_find_type(type);
    1468                 :         20 : }
    1469                 :            : 
    1470                 :            : static void
    1471                 :       3350 : pkg_repo_free(struct pkg_repo *r)
    1472                 :            : {
    1473                 :            :         struct pkg_kv *kv, *tmp;
    1474                 :            : 
    1475                 :       3350 :         free(r->url);
    1476                 :       3350 :         free(r->name);
    1477                 :       3350 :         free(r->pubkey);
    1478                 :       3350 :         free(r->fingerprints);
    1479                 :       3350 :         pkg_repo_meta_free(r->meta);
    1480         [ -  + ]:       3350 :         if (r->ssh != NULL) {
    1481                 :          0 :                 fprintf(r->ssh, "quit\n");
    1482                 :          0 :                 pclose(r->ssh);
    1483                 :          0 :         }
    1484   [ -  +  +  - ]:       3350 :         LL_FOREACH_SAFE(r->env, kv, tmp) {
    1485   [ #  #  #  #  :          0 :                 LL_DELETE(r->env, kv);
             #  #  #  # ]
    1486                 :          0 :                 pkg_kv_free(kv);
    1487                 :          0 :         }
    1488                 :       3350 :         free(r);
    1489                 :       3350 : }
    1490                 :            : 
    1491                 :            : void
    1492                 :       3501 : pkg_shutdown(void)
    1493                 :            : {
    1494         [ +  - ]:       3501 :         if (!parsed) {
    1495                 :          0 :                 pkg_emit_error("pkg_shutdown() must be called after pkg_init()");
    1496                 :          0 :                 _exit(EXIT_FAILURE);
    1497                 :            :                 /* NOTREACHED */
    1498                 :            :         }
    1499                 :            : 
    1500                 :       3501 :         metalog_close();
    1501                 :       3501 :         ucl_object_unref(config);
    1502   [ +  +  +  +  :       6851 :         LL_FREE(repos, pkg_repo_free);
          -  +  #  #  #  
                #  #  # ]
    1503                 :            : 
    1504         [ -  + ]:       3501 :         if (ctx.rootfd != -1) {
    1505                 :       3501 :                 close(ctx.rootfd);
    1506                 :       3501 :                 ctx.rootfd = -1;
    1507                 :       3501 :         }
    1508         [ +  + ]:       3501 :         if (ctx.cachedirfd != -1) {
    1509                 :          4 :                 close(ctx.cachedirfd);
    1510                 :          4 :                 ctx.cachedirfd = -1;
    1511                 :          4 :         }
    1512         [ +  + ]:       3501 :         if (ctx.pkg_dbdirfd != -1) {
    1513                 :       1756 :                 close(ctx.pkg_dbdirfd);
    1514                 :       1756 :                 ctx.pkg_dbdirfd = -1;
    1515                 :       1756 :         }
    1516                 :            : 
    1517                 :       3501 :         parsed = false;
    1518                 :            : 
    1519                 :       3501 :         return;
    1520                 :            : }
    1521                 :            : 
    1522                 :            : int
    1523                 :       1176 : pkg_repos_total_count(void)
    1524                 :            : {
    1525                 :       1176 :         int cnt = 0;
    1526                 :            :         struct pkg_repo *r;
    1527                 :            : 
    1528         [ +  + ]:       2291 :         LL_COUNT(repos, r, cnt);
    1529                 :       1176 :         return (cnt);
    1530                 :            : }
    1531                 :            : 
    1532                 :            : int
    1533                 :        506 : pkg_repos_activated_count(void)
    1534                 :            : {
    1535                 :        506 :         struct pkg_repo *r = NULL;
    1536                 :        506 :         int count = 0;
    1537                 :            : 
    1538         [ +  + ]:        843 :         LL_FOREACH(repos, r) {
    1539         [ -  + ]:        337 :                 if (r->enable)
    1540                 :        337 :                         count++;
    1541                 :        337 :         }
    1542                 :            : 
    1543                 :        506 :         return (count);
    1544                 :            : }
    1545                 :            : 
    1546                 :            : int
    1547                 :      10202 : pkg_repos(struct pkg_repo **r)
    1548                 :            : {
    1549         [ +  + ]:      10202 :         if (*r == NULL)
    1550                 :       5182 :                 *r = repos;
    1551                 :            :         else
    1552                 :       5020 :                 *r = (*r)->next;
    1553         [ +  + ]:      10202 :         if (*r == NULL)
    1554                 :       5178 :                 return (EPKG_END);
    1555                 :       5024 :         return (EPKG_OK);
    1556                 :      10202 : }
    1557                 :            : 
    1558                 :            : const char *
    1559                 :       6580 : pkg_repo_url(struct pkg_repo *r)
    1560                 :            : {
    1561                 :       6580 :         return (r->url);
    1562                 :            : }
    1563                 :            : 
    1564                 :            : /* The basename of the sqlite DB file and the database name */
    1565                 :            : const char *
    1566                 :       5556 : pkg_repo_name(struct pkg_repo *r)
    1567                 :            : {
    1568                 :       5556 :         return (r->name);
    1569                 :            : }
    1570                 :            : 
    1571                 :            : const char *
    1572                 :         71 : pkg_repo_key(struct pkg_repo *r)
    1573                 :            : {
    1574                 :         71 :         return (r->pubkey);
    1575                 :            : }
    1576                 :            : 
    1577                 :            : const char *
    1578                 :         71 : pkg_repo_fingerprints(struct pkg_repo *r)
    1579                 :            : {
    1580                 :         71 :         return (r->fingerprints);
    1581                 :            : }
    1582                 :            : 
    1583                 :            : signature_t
    1584                 :       1070 : pkg_repo_signature_type(struct pkg_repo *r)
    1585                 :            : {
    1586                 :       1070 :         return (r->signature_type);
    1587                 :            : }
    1588                 :            : 
    1589                 :            : bool
    1590                 :       1716 : pkg_repo_enabled(struct pkg_repo *r)
    1591                 :            : {
    1592                 :       1716 :         return (r->enable);
    1593                 :            : }
    1594                 :            : 
    1595                 :            : mirror_t
    1596                 :        110 : pkg_repo_mirror_type(struct pkg_repo *r)
    1597                 :            : {
    1598                 :        110 :         return (r->mirror_type);
    1599                 :            : }
    1600                 :            : 
    1601                 :            : unsigned int
    1602                 :         55 : pkg_repo_priority(struct pkg_repo *r)
    1603                 :            : {
    1604                 :         55 :         return (r->priority);
    1605                 :            : }
    1606                 :            : 
    1607                 :            : unsigned int
    1608                 :         55 : pkg_repo_ip_version(struct pkg_repo *r)
    1609                 :            : {
    1610         [ -  + ]:         55 :         if ((r->flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4)
    1611                 :          0 :                 return 4;
    1612         [ -  + ]:         55 :         else if ((r->flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)
    1613                 :          0 :                 return 6;
    1614                 :            :         else
    1615                 :         55 :                 return 0;
    1616                 :         55 : }
    1617                 :            : 
    1618                 :            : /* Locate the repo by the file basename / database name */
    1619                 :            : struct pkg_repo *
    1620                 :       3811 : pkg_repo_find(const char *reponame)
    1621                 :            : {
    1622                 :            :         struct pkg_repo *r;
    1623                 :            : 
    1624         [ +  + ]:       4050 :         LL_FOREACH(repos, r) {
    1625         [ +  + ]:        660 :                 if (strcmp(r->name, reponame) == 0)
    1626                 :        421 :                         return (r);
    1627                 :        239 :         }
    1628                 :       3390 :         return (NULL);
    1629                 :       3811 : }
    1630                 :            : 
    1631                 :            : int64_t
    1632                 :       3496 : pkg_set_debug_level(int64_t new_debug_level) {
    1633                 :       3496 :         int64_t old_debug_level = ctx.debug_level;
    1634                 :            : 
    1635                 :       3496 :         ctx.debug_level = new_debug_level;
    1636                 :       3496 :         return old_debug_level;
    1637                 :            : }
    1638                 :            : 
    1639                 :            : int
    1640                 :        303 : pkg_set_rootdir(const char *rootdir) {
    1641         [ -  + ]:        303 :         if (pkg_initialized())
    1642                 :          0 :                 return (EPKG_FATAL);
    1643                 :            : 
    1644         [ +  - ]:        303 :         if (ctx.rootfd != -1)
    1645                 :          0 :                 close(ctx.rootfd);
    1646                 :            : 
    1647         [ -  + ]:        303 :         if ((ctx.rootfd = open(rootdir, O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
    1648                 :          0 :                 pkg_emit_error("Impossible to open %s", rootdir);
    1649                 :          0 :                 return (EPKG_FATAL);
    1650                 :            :         }
    1651                 :        303 :         ctx.pkg_rootdir = rootdir;
    1652                 :        303 :         ctx.defer_triggers = true;
    1653                 :            : 
    1654                 :        303 :         return (EPKG_OK);
    1655                 :        303 : }
    1656                 :            : 
    1657                 :            : const char *
    1658                 :          4 : pkg_get_cachedir(void)
    1659                 :            : {
    1660                 :            : 
    1661                 :          4 :         return (ctx.cachedir);
    1662                 :            : }
    1663                 :            : 
    1664                 :            : int
    1665                 :          4 : pkg_get_cachedirfd(void)
    1666                 :            : {
    1667                 :            : 
    1668         [ +  - ]:          4 :         if (ctx.cachedirfd == -1) {
    1669                 :            :                 /*
    1670                 :            :                  * do not check the value as if we cannot open it means
    1671                 :            :                  * it has not been created yet
    1672                 :            :                  */
    1673                 :          4 :                 ctx.cachedirfd = open(ctx.cachedir, O_DIRECTORY|O_CLOEXEC);
    1674                 :          4 :         }
    1675                 :            : 
    1676                 :          4 :         return (ctx.cachedirfd);
    1677                 :            : }
    1678                 :            : 
    1679                 :            : int
    1680                 :     157469 : pkg_get_dbdirfd(void)
    1681                 :            : {
    1682                 :            : 
    1683         [ +  + ]:     157469 :         if (ctx.pkg_dbdirfd == -1) {
    1684                 :            :                 /*
    1685                 :            :                  * do not check the value as if we cannot open it means
    1686                 :            :                  * it has not been created yet
    1687                 :            :                  */
    1688                 :       1790 :                 ctx.pkg_dbdirfd = open(ctx.dbdir, O_DIRECTORY|O_CLOEXEC);
    1689                 :       1790 :         }
    1690                 :            : 
    1691                 :     157469 :         return (ctx.pkg_dbdirfd);
    1692                 :            : }

Generated by: LCOV version 1.15