LCOV - code coverage report
Current view: top level - libpkg/repo/binary - init.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 100 229 43.7 %
Date: 2015-08-15 Functions: 7 12 58.3 %

          Line data    Source code
       1             : /* Copyright (c) 2014, Vsevolod Stakhov
       2             :  * All rights reserved.
       3             :  *
       4             :  * Redistribution and use in source and binary forms, with or without
       5             :  * modification, are permitted provided that the following conditions are met:
       6             :  *       * Redistributions of source code must retain the above copyright
       7             :  *         notice, this list of conditions and the following disclaimer.
       8             :  *       * Redistributions in binary form must reproduce the above copyright
       9             :  *         notice, this list of conditions and the following disclaimer in the
      10             :  *         documentation and/or other materials provided with the distribution.
      11             :  *
      12             :  * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
      13             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      14             :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      15             :  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
      16             :  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      17             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      18             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      19             :  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      20             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      21             :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      22             :  */
      23             : 
      24             : #include <sys/param.h>
      25             : #include <sys/mount.h>
      26             : 
      27             : #include <assert.h>
      28             : #include <errno.h>
      29             : #include <regex.h>
      30             : #include <grp.h>
      31             : #include <stdlib.h>
      32             : #include <stdio.h>
      33             : #include <stdbool.h>
      34             : #include <string.h>
      35             : #include <unistd.h>
      36             : #include <libgen.h>
      37             : 
      38             : #include <sqlite3.h>
      39             : 
      40             : #include <bsd_compat.h>
      41             : 
      42             : #ifdef HAVE_SYS_STATFS_H
      43             : #include <sys/statfs.h>
      44             : #elif defined(HAVE_SYS_STATVFS_H)
      45             : #include <sys/statvfs.h>
      46             : #endif
      47             : 
      48             : #include "pkg.h"
      49             : #include "private/event.h"
      50             : #include "private/pkg.h"
      51             : #include "private/pkgdb.h"
      52             : #include "private/utils.h"
      53             : #include "binary.h"
      54             : #include "binary_private.h"
      55             : 
      56             : static void
      57           0 : sqlite_file_exists(sqlite3_context *ctx, int argc, sqlite3_value **argv)
      58             : {
      59             :         char     fpath[MAXPATHLEN];
      60           0 :         sqlite3 *db = sqlite3_context_db_handle(ctx);
      61           0 :         char    *path = bsd_dirname(sqlite3_db_filename(db, "main"));
      62             :         char    *cksum;
      63             : 
      64           0 :         if (argc != 2) {
      65           0 :                 sqlite3_result_error(ctx, "file_exists needs two argument", -1);
      66           0 :                 return;
      67             :         }
      68             : 
      69           0 :         snprintf(fpath, sizeof(fpath), "%s/%s", path, sqlite3_value_text(argv[0]));
      70             : 
      71           0 :         if (access(fpath, R_OK) == 0) {
      72           0 :                 cksum = pkg_checksum_file(fpath, PKG_HASH_TYPE_SHA256_HEX);
      73           0 :                 if (cksum && strcmp(cksum, sqlite3_value_text(argv[1])) == 0)
      74           0 :                         sqlite3_result_int(ctx, 1);
      75             :                 else
      76           0 :                         sqlite3_result_int(ctx, 0);
      77           0 :                 free(cksum);
      78             :         } else {
      79           0 :                 sqlite3_result_int(ctx, 0);
      80             :         }
      81             : }
      82             : 
      83             : static int
      84          16 : pkg_repo_binary_get_user_version(sqlite3 *sqlite, int *reposcver)
      85             : {
      86             :         sqlite3_stmt *stmt;
      87             :         int retcode;
      88          16 :         const char *sql = "PRAGMA user_version;";
      89             : 
      90          16 :         if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
      91           0 :                 ERROR_SQLITE(sqlite, sql);
      92           0 :                 return (EPKG_FATAL);
      93             :         }
      94             : 
      95          16 :         if (sqlite3_step(stmt) == SQLITE_ROW) {
      96          16 :                 *reposcver = sqlite3_column_int64(stmt, 0);
      97          16 :                 retcode = EPKG_OK;
      98             :         } else {
      99           0 :                 *reposcver = -1;
     100           0 :                 retcode = EPKG_FATAL;
     101             :         }
     102          16 :         sqlite3_finalize(stmt);
     103          16 :         return (retcode);
     104             : }
     105             : 
     106             : static int
     107           0 : pkg_repo_binary_set_version(sqlite3 *sqlite, int reposcver)
     108             : {
     109           0 :         const char      *sql = "PRAGMA user_version = %d;";
     110             : 
     111           0 :         if (sql_exec(sqlite, sql, reposcver) != EPKG_OK) {
     112           0 :                 ERROR_SQLITE(sqlite, sql);
     113           0 :                 return (EPKG_FATAL);
     114             :         }
     115             : 
     116           0 :         return (EPKG_OK);
     117             : }
     118             : 
     119             : static int
     120           0 : pkg_repo_binary_apply_change(struct pkg_repo *repo, sqlite3 *sqlite,
     121             :                   const struct repo_changes *repo_changes, const char *updown,
     122             :                   int version, int *next_version)
     123             : {
     124             :         const struct repo_changes       *change;
     125           0 :         bool                     found = false, in_trans = false;
     126           0 :         int                      ret = EPKG_OK;
     127             :         char                    *errmsg;
     128             : 
     129           0 :         for (change = repo_changes; change->version != -1; change++) {
     130           0 :                 if (change->version == version) {
     131           0 :                         found = true;
     132           0 :                         break;
     133             :                 }
     134             :         }
     135           0 :         if (!found) {
     136           0 :                 pkg_emit_error("Unable to %s \"%s\" repo schema "
     137             :                         "version %d (target version %d) "
     138             :                         "-- change not found", updown, repo->name, version,
     139             :                         REPO_SCHEMA_VERSION);
     140           0 :                 return (EPKG_FATAL);
     141             :         }
     142             : 
     143             :         /* begin transaction */
     144           0 :         if ((ret = pkgdb_transaction_begin_sqlite(sqlite, "SCHEMA")) == EPKG_OK)
     145           0 :                 in_trans = true;
     146             : 
     147             :         /* apply change */
     148           0 :         if (ret == EPKG_OK) {
     149           0 :                 pkg_debug(4, "Pkgdb: running '%s'", change->sql);
     150           0 :                 ret = sqlite3_exec(sqlite, change->sql, NULL, NULL, &errmsg);
     151           0 :                 if (ret != SQLITE_OK) {
     152           0 :                         pkg_emit_error("sqlite: %s", errmsg);
     153           0 :                         sqlite3_free(errmsg);
     154           0 :                         ret = EPKG_FATAL;
     155             :                 }
     156             :         }
     157             : 
     158             :         /* update repo user_version */
     159           0 :         if (ret == EPKG_OK) {
     160           0 :                 *next_version = change->next_version;
     161           0 :                 ret = pkg_repo_binary_set_version(sqlite, *next_version);
     162             :         }
     163             : 
     164             :         /* commit or rollback */
     165           0 :         if (in_trans) {
     166           0 :                 if (ret != EPKG_OK)
     167           0 :                         pkgdb_transaction_rollback_sqlite(sqlite, "SCHEMA");
     168             : 
     169           0 :                 if (pkgdb_transaction_commit_sqlite(sqlite, "SCHEMA") != EPKG_OK)
     170           0 :                         ret = EPKG_FATAL;
     171             :         }
     172             : 
     173           0 :         if (ret == EPKG_OK) {
     174           0 :                 pkg_emit_notice("Repo \"%s\" %s schema %d to %d: %s",
     175             :                                 repo->name, updown, version,
     176             :                                 change->next_version, change->message);
     177             :         }
     178             : 
     179           0 :         return (ret);
     180             : }
     181             : 
     182             : static int
     183           0 : pkg_repo_binary_upgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
     184             : {
     185             :         int version;
     186             :         int next_version;
     187           0 :         int ret = EPKG_OK;
     188             : 
     189           0 :         for (version = current_version;
     190             :              version < REPO_SCHEMA_VERSION;
     191           0 :              version = next_version)  {
     192           0 :                 ret = pkg_repo_binary_apply_change(repo, sqlite, repo_upgrades,
     193             :                                         "upgrade", version, &next_version);
     194           0 :                 if (ret != EPKG_OK)
     195           0 :                         break;
     196           0 :                 pkg_debug(1, "Upgrading repo database schema from %d to %d",
     197             :                                 version, next_version);
     198             :         }
     199           0 :         return (ret);
     200             : }
     201             : 
     202             : static int
     203           0 : pkg_repo_binary_downgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
     204             : {
     205             :         int version;
     206             :         int next_version;
     207           0 :         int ret = EPKG_OK;
     208             : 
     209           0 :         for (version = current_version;
     210             :              version > REPO_SCHEMA_VERSION;
     211           0 :              version = next_version)  {
     212             : 
     213           0 :                 ret = pkg_repo_binary_apply_change(repo, sqlite, repo_downgrades,
     214             :                                         "downgrade", version, &next_version);
     215           0 :                 if (ret != EPKG_OK)
     216           0 :                         break;
     217           0 :                 pkg_debug(1, "Downgrading repo database schema from %d to %d",
     218             :                                 version, next_version);
     219             :         }
     220           0 :         return (ret);
     221             : }
     222             : 
     223             : int
     224          16 : pkg_repo_binary_check_version(struct pkg_repo *repo, sqlite3 *sqlite)
     225             : {
     226             :         int reposcver;
     227             :         int repomajor;
     228             :         int ret;
     229             : 
     230          16 :         if ((ret = pkg_repo_binary_get_user_version(sqlite, &reposcver))
     231             :             != EPKG_OK)
     232           0 :                 return (ret);   /* sqlite error */
     233             : 
     234             :         /*
     235             :          * If the local pkgng uses a repo schema behind that used to
     236             :          * create the repo, we may still be able use it for reading
     237             :          * (ie pkg install), but pkg repo can't do an incremental
     238             :          * update unless the actual schema matches the compiled in
     239             :          * schema version.
     240             :          *
     241             :          * Use a major - minor version schema: as the user_version
     242             :          * PRAGMA takes an integer version, encode this as MAJOR *
     243             :          * 1000 + MINOR.
     244             :          *
     245             :          * So long as the major versions are the same, the local pkgng
     246             :          * should be compatible with any repo created by a more recent
     247             :          * pkgng, although it may need some modification of the repo
     248             :          * schema
     249             :          */
     250             : 
     251             :         /* --- Temporary ---- Grandfather in the old repo schema
     252             :            version so this patch doesn't immediately invalidate all
     253             :            the repos out there */
     254             : 
     255          16 :         if (reposcver == 2)
     256           0 :                 reposcver = 2000;
     257          16 :         if (reposcver == 3)
     258           0 :                 reposcver = 2001;
     259             : 
     260          16 :         repomajor = reposcver / 1000;
     261             : 
     262          16 :         if (repomajor < REPO_SCHEMA_MAJOR) {
     263           0 :                 pkg_emit_error("Repo %s (schema version %d) is too old - "
     264             :                     "need at least schema %d", repo->name, reposcver,
     265             :                     REPO_SCHEMA_MAJOR * 1000);
     266           0 :                 return (EPKG_REPOSCHEMA);
     267             :         }
     268             : 
     269          16 :         if (repomajor > REPO_SCHEMA_MAJOR) {
     270           0 :                 pkg_emit_error("Repo %s (schema version %d) is too new - "
     271             :                     "we can accept at most schema %d", repo->name, reposcver,
     272             :                     ((REPO_SCHEMA_MAJOR + 1) * 1000) - 1);
     273           0 :                 return (EPKG_REPOSCHEMA);
     274             :         }
     275             : 
     276             :         /* This is a repo schema version we can work with */
     277             : 
     278          16 :         ret = EPKG_OK;
     279             : 
     280          16 :         if (reposcver < REPO_SCHEMA_VERSION) {
     281           0 :                 if (sqlite3_db_readonly(sqlite, "main")) {
     282           0 :                         pkg_emit_error("Repo %s needs schema upgrade from "
     283             :                             "%d to %d but it is opened readonly", repo->name,
     284             :                             reposcver, REPO_SCHEMA_VERSION);
     285           0 :                         ret = EPKG_FATAL;
     286             :                 } else
     287           0 :                         ret = pkg_repo_binary_upgrade(repo, sqlite, reposcver);
     288          16 :         } else if (reposcver > REPO_SCHEMA_VERSION) {
     289           0 :                 if (sqlite3_db_readonly(sqlite, "main")) {
     290           0 :                         pkg_emit_error("Repo %s needs schema downgrade from "
     291             :                         "%d to %d but it is opened readonly", repo->name,
     292             :                                reposcver, REPO_SCHEMA_VERSION
     293             :                         );
     294           0 :                         ret = EPKG_FATAL;
     295             :                 } else
     296           0 :                         ret = pkg_repo_binary_downgrade(repo, sqlite, reposcver);
     297             :         }
     298             : 
     299          16 :         return (ret);
     300             : }
     301             : 
     302             : int
     303          23 : pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
     304             : {
     305             :         char filepath[MAXPATHLEN];
     306          23 :         const char *dbdir = NULL;
     307          23 :         sqlite3 *sqlite = NULL;
     308             :         int flags;
     309             :         int64_t res;
     310             :         struct pkg_repo_it *it;
     311          23 :         struct pkg *pkg = NULL;
     312             : 
     313          23 :         sqlite3_initialize();
     314          23 :         dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
     315             : 
     316             :         /*
     317             :          * Fall back on unix-dotfile locking strategy if on a network filesystem
     318             :          */
     319             : #if defined(HAVE_SYS_STATVFS_H) && defined(ST_LOCAL)
     320             :         struct statvfs stfs;
     321             : 
     322             :         if (statvfs(dbdir, &stfs) == 0) {
     323             :                 if ((stfs.f_flag & ST_LOCAL) != ST_LOCAL)
     324             :                         sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
     325             :         }
     326             : #elif defined(HAVE_STATFS) && defined(MNT_LOCAL)
     327             :         struct statfs stfs;
     328             : 
     329          23 :         if (statfs(dbdir, &stfs) == 0) {
     330          23 :                 if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL)
     331           0 :                         sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
     332             :         }
     333             : #endif
     334             : 
     335          23 :         snprintf(filepath, sizeof(filepath), "%s/%s.meta",
     336             :                 dbdir, pkg_repo_name(repo));
     337             : 
     338             :         /* Open metafile */
     339          23 :         if (access(filepath, R_OK) != -1) {
     340          16 :                 if (pkg_repo_meta_load(filepath, &repo->meta) != EPKG_OK)
     341           0 :                         return (EPKG_FATAL);
     342             :         }
     343             : 
     344          23 :         snprintf(filepath, sizeof(filepath), "%s/%s",
     345             :                 dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo)));
     346             : 
     347             :         /* Always want read mode here */
     348          23 :         if (access(filepath, R_OK | mode) != 0)
     349           7 :                 return (EPKG_ENOACCESS);
     350             : 
     351          16 :         flags = (mode & W_OK) != 0 ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
     352          16 :         if (sqlite3_open_v2(filepath, &sqlite, flags, NULL) != SQLITE_OK)
     353           0 :                 return (EPKG_FATAL);
     354             : 
     355             :         /* Sanitise sqlite database */
     356          16 :         if (get_pragma(sqlite, "SELECT count(name) FROM sqlite_master "
     357             :                 "WHERE type='table' AND name='repodata';", &res, false) != EPKG_OK) {
     358           0 :                 pkg_emit_error("Unable to query repository");
     359           0 :                 sqlite3_close(sqlite);
     360           0 :                 return (EPKG_FATAL);
     361             :         }
     362             : 
     363          16 :         if (res != 1) {
     364           0 :                 pkg_emit_notice("Repository %s contains no repodata table, "
     365             :                         "need to re-create database", repo->name);
     366           0 :                 sqlite3_close(sqlite);
     367           0 :                 return (EPKG_FATAL);
     368             :         }
     369             : 
     370             :         /* Check package site */
     371          16 :         char *req = sqlite3_mprintf("select count(key) from repodata "
     372             :                 "WHERE key = \"packagesite\" and value = '%q'", pkg_repo_url(repo));
     373             : 
     374          16 :         res = 0;
     375          16 :         get_pragma(sqlite, req, &res, true);
     376          16 :         sqlite3_free(req);
     377          16 :         if (res != 1) {
     378           0 :                 pkg_emit_notice("Repository %s has a wrong packagesite, need to "
     379             :                         "re-create database", repo->name);
     380           0 :                 sqlite3_close(sqlite);
     381           0 :                 return (EPKG_FATAL);
     382             :         }
     383             : 
     384             :         /* Check version */
     385          16 :         if (pkg_repo_binary_check_version(repo, sqlite) != EPKG_OK) {
     386           0 :                 pkg_emit_error("need to re-create repo %s to upgrade schema version",
     387             :                         repo->name);
     388           0 :                 sqlite3_close(sqlite);
     389           0 :                 if (mode & W_OK)
     390           0 :                         unlink(filepath);
     391           0 :                 return (EPKG_REPOSCHEMA);
     392             :         }
     393             : 
     394          16 :         repo->priv = sqlite;
     395             :         /* Check digests format */
     396          16 :         if ((it = pkg_repo_binary_query(repo, NULL, MATCH_ALL)) == NULL)
     397           0 :                 return (EPKG_OK);
     398             : 
     399          16 :         if (it->ops->next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
     400           7 :                 it->ops->free(it);
     401           7 :                 return (EPKG_OK);
     402             :         }
     403           9 :         it->ops->free(it);
     404           9 :         if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest, strlen(pkg->digest))) {
     405           0 :                 pkg_emit_notice("Repository %s has incompatible checksum format, need to "
     406             :                         "re-create database", repo->name);
     407           0 :                 pkg_free(pkg);
     408           0 :                 sqlite3_close(sqlite);
     409           0 :                 repo->priv = NULL;
     410           0 :                 return (EPKG_FATAL);
     411             :         }
     412           9 :         pkg_free(pkg);
     413             : 
     414           9 :         return (EPKG_OK);
     415             : }
     416             : 
     417             : int
     418           7 : pkg_repo_binary_create(struct pkg_repo *repo)
     419             : {
     420             :         char filepath[MAXPATHLEN];
     421           7 :         const char *dbdir = NULL;
     422           7 :         sqlite3 *sqlite = NULL;
     423             :         int retcode;
     424             : 
     425           7 :         sqlite3_initialize();
     426           7 :         dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
     427             : 
     428           7 :         snprintf(filepath, sizeof(filepath), "%s/%s",
     429             :                 dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo)));
     430             :         /* Should never ever happen */
     431           7 :         if (access(filepath, R_OK) == 0)
     432           0 :                 return (EPKG_CONFLICT);
     433             : 
     434             :         /*
     435             :          * Fall back on unix-dotfile locking strategy if on a network filesystem
     436             :          */
     437             : #if defined(HAVE_SYS_STATVFS_H) && defined(ST_LOCAL)
     438             :         struct statvfs stfs;
     439             : 
     440             :         if (statvfs(dbdir, &stfs) == 0) {
     441             :                 if ((stfs.f_flag & ST_LOCAL) != ST_LOCAL)
     442             :                         sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
     443             :         }
     444             : #elif defined(HAVE_STATFS) && defined(MNT_LOCAL)
     445             :         struct statfs stfs;
     446             : 
     447           7 :         if (statfs(dbdir, &stfs) == 0) {
     448           7 :                 if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL)
     449           0 :                         sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
     450             :         }
     451             : #endif
     452             : 
     453             :         /* Open for read/write/create */
     454           7 :         if (sqlite3_open(filepath, &sqlite) != SQLITE_OK)
     455           0 :                 return (EPKG_FATAL);
     456             : 
     457           7 :         retcode = sql_exec(sqlite, binary_repo_initsql, REPO_SCHEMA_VERSION);
     458             : 
     459           7 :         if (retcode == EPKG_OK) {
     460             :                 sqlite3_stmt *stmt;
     461           7 :                 const char sql[] = ""
     462             :                         "INSERT OR REPLACE INTO repodata (key, value) "
     463             :                         "VALUES (\"packagesite\", ?1);";
     464             : 
     465             :                 /* register the packagesite */
     466           7 :                 if (sql_exec(sqlite, "CREATE TABLE IF NOT EXISTS repodata ("
     467             :                         "   key TEXT UNIQUE NOT NULL,"
     468             :                         "   value TEXT NOT NULL"
     469             :                         ");") != EPKG_OK) {
     470           0 :                         pkg_emit_error("Unable to register the packagesite in the "
     471             :                                 "database");
     472           0 :                         retcode = EPKG_FATAL;
     473           0 :                         goto cleanup;
     474             :                 }
     475             : 
     476           7 :                 if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     477           0 :                         ERROR_SQLITE(sqlite, sql);
     478           0 :                         retcode = EPKG_FATAL;
     479           0 :                         goto cleanup;
     480             :                 }
     481             : 
     482           7 :                 sqlite3_bind_text(stmt, 1, pkg_repo_url(repo), -1, SQLITE_STATIC);
     483             : 
     484           7 :                 if (sqlite3_step(stmt) != SQLITE_DONE) {
     485           0 :                         ERROR_SQLITE(sqlite, sql);
     486           0 :                         sqlite3_finalize(stmt);
     487           0 :                         retcode = EPKG_FATAL;
     488           0 :                         goto cleanup;
     489             :                 }
     490             : 
     491           7 :                 sqlite3_finalize(stmt);
     492             :         }
     493             : 
     494             : cleanup:
     495           7 :         sqlite3_close(sqlite);
     496             : 
     497           7 :         return (retcode);
     498             : }
     499             : 
     500             : int
     501          15 : pkg_repo_binary_init(struct pkg_repo *repo)
     502             : {
     503          15 :         int retcode = EPKG_OK;
     504          15 :         sqlite3 *sqlite = PRIV_GET(repo);
     505             : 
     506          15 :         sqlite3_create_function(sqlite, "file_exists", 2, SQLITE_ANY, NULL,
     507             :                     sqlite_file_exists, NULL, NULL);
     508          15 :         retcode = sql_exec(sqlite, "PRAGMA synchronous=default");
     509          15 :         if (retcode != EPKG_OK)
     510           0 :                 return (retcode);
     511             : 
     512          15 :         retcode = sql_exec(sqlite, "PRAGMA foreign_keys=on");
     513          15 :         if (retcode != EPKG_OK)
     514           0 :                 return (retcode);
     515             : 
     516          15 :         pkgdb_sqlcmd_init(sqlite, NULL, NULL);
     517             : 
     518          15 :         retcode = pkg_repo_binary_init_prstatements(sqlite);
     519          15 :         if (retcode != EPKG_OK)
     520           0 :                 return (retcode);
     521             : 
     522          15 :         repo->priv = sqlite;
     523             : 
     524          15 :         return (EPKG_OK);
     525             : }
     526             : 
     527             : int
     528          16 : pkg_repo_binary_close(struct pkg_repo *repo, bool commit)
     529             : {
     530          16 :         int retcode = EPKG_OK;
     531          16 :         sqlite3 *sqlite = PRIV_GET(repo);
     532             : 
     533          16 :         if (sqlite == NULL)
     534           0 :                 return (retcode);
     535             : 
     536          16 :         if (commit) {
     537           0 :                 if (pkgdb_transaction_commit_sqlite(sqlite, NULL) != SQLITE_OK)
     538           0 :                         retcode = EPKG_FATAL;
     539             :         }
     540             : 
     541          16 :         pkg_repo_binary_finalize_prstatements();
     542          16 :         sqlite3_free(sqlite);
     543             : 
     544          16 :         repo->priv = NULL;
     545             : 
     546          16 :         return (retcode);
     547             : }
     548             : 
     549             : int
     550          16 : pkg_repo_binary_access(struct pkg_repo *repo, unsigned mode)
     551             : {
     552             :         const pkg_object        *o;
     553             :         const char              *dbdir;
     554          16 :         int                      ret = EPKG_OK;
     555             : 
     556          16 :         o = pkg_config_get("PKG_DBDIR");
     557          16 :         dbdir = pkg_object_string(o);
     558             : 
     559          16 :         ret = pkgdb_check_access(mode, dbdir,
     560             :                 pkg_repo_binary_get_filename(pkg_repo_name(repo)));
     561             : 
     562          16 :         return (ret);
     563             : }

Generated by: LCOV version 1.10