LCOV - code coverage report
Current view: top level - libpkg/repo/binary - update.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 148 316 46.8 %
Date: 2015-08-15 Functions: 5 8 62.5 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014, Vsevolod Stakhov
       3             :  * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org>
       4             :  * Copyright (c) 2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       5             :  * All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions are met:
       9             :  *       * Redistributions of source code must retain the above copyright
      10             :  *         notice, this list of conditions and the following disclaimer.
      11             :  *       * Redistributions in binary form must reproduce the above copyright
      12             :  *         notice, this list of conditions and the following disclaimer in the
      13             :  *         documentation and/or other materials provided with the distribution.
      14             :  *
      15             :  * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
      16             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      17             :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      18             :  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
      19             :  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      20             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      21             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      22             :  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      23             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      24             :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      25             :  */
      26             : 
      27             : #include <sys/stat.h>
      28             : #include <sys/param.h>
      29             : #include <sys/mman.h>
      30             : #include <sys/time.h>
      31             : 
      32             : #define _WITH_GETLINE
      33             : #include <stdio.h>
      34             : #include <stdlib.h>
      35             : #include <string.h>
      36             : #include <unistd.h>
      37             : #include <errno.h>
      38             : #include <limits.h>
      39             : 
      40             : #include <archive.h>
      41             : #include <archive_entry.h>
      42             : 
      43             : #include "pkg.h"
      44             : #include "private/event.h"
      45             : #include "private/utils.h"
      46             : #include "private/pkgdb.h"
      47             : #include "private/pkg.h"
      48             : #include "binary.h"
      49             : #include "binary_private.h"
      50             : 
      51             : static int
      52           7 : pkg_repo_binary_init_update(struct pkg_repo *repo, const char *name)
      53             : {
      54             :         sqlite3 *sqlite;
      55           7 :         const char update_check_sql[] = ""
      56             :                                         "INSERT INTO repo_update VALUES(1);";
      57           7 :         const char update_start_sql[] = ""
      58             :                                         "CREATE TABLE IF NOT EXISTS repo_update (n INT);";
      59             : 
      60             :         /* [Re]create repo */
      61           7 :         unlink(name);
      62           7 :         if (repo->ops->create(repo) != EPKG_OK) {
      63           0 :                 pkg_emit_notice("Unable to create repository %s", repo->name);
      64           0 :                 return (EPKG_FATAL);
      65             :         }
      66           7 :         if (repo->ops->open(repo, R_OK|W_OK) != EPKG_OK) {
      67           0 :                 pkg_emit_notice("Unable to open created repository %s", repo->name);
      68           0 :                 return (EPKG_FATAL);
      69             :         }
      70             : 
      71           7 :         repo->ops->init(repo);
      72             : 
      73           7 :         sqlite = PRIV_GET(repo);
      74             : 
      75           7 :         if(sqlite3_exec(sqlite, update_check_sql, NULL, NULL, NULL) == SQLITE_OK) {
      76           0 :                 pkg_emit_notice("Previous update has not been finished, restart it");
      77           0 :                 return (EPKG_END);
      78             :         }
      79             :         else {
      80           7 :                 sql_exec(sqlite, update_start_sql);
      81             :         }
      82             : 
      83           7 :         return (EPKG_OK);
      84             : }
      85             : 
      86             : static int
      87           0 : pkg_repo_binary_delete_conflicting(const char *origin, const char *version,
      88             :                          const char *pkg_path, bool forced)
      89             : {
      90           0 :         int ret = EPKG_FATAL;
      91             :         const char *oversion;
      92             : 
      93           0 :         if (pkg_repo_binary_run_prstatement(REPO_VERSION, origin) != SQLITE_ROW) {
      94           0 :                 ret = EPKG_FATAL;
      95           0 :                 goto cleanup;
      96             :         }
      97           0 :         oversion = sqlite3_column_text(pkg_repo_binary_stmt_prstatement(REPO_VERSION), 0);
      98           0 :         if (!forced) {
      99           0 :                 switch(pkg_version_cmp(oversion, version)) {
     100             :                 case -1:
     101           0 :                         pkg_emit_error("duplicate package origin: replacing older "
     102             :                                         "version %s in repo with package %s for "
     103             :                                         "origin %s", oversion, pkg_path, origin);
     104             : 
     105           0 :                         if (pkg_repo_binary_run_prstatement(DELETE, origin, origin) !=
     106             :                                                         SQLITE_DONE)
     107           0 :                                 ret = EPKG_FATAL;
     108             :                         else
     109           0 :                                 ret = EPKG_OK;  /* conflict cleared */
     110             : 
     111           0 :                         break;
     112             :                 case 0:
     113             :                 case 1:
     114           0 :                         pkg_emit_error("duplicate package origin: package %s is not "
     115             :                                         "newer than version %s already in repo for "
     116             :                                         "origin %s", pkg_path, oversion, origin);
     117           0 :                         ret = EPKG_END; /* keep what is already in the repo */
     118           0 :                         break;
     119             :                 }
     120             :         }
     121             :         else {
     122           0 :                 if (pkg_repo_binary_run_prstatement(DELETE, origin, origin) != SQLITE_DONE)
     123           0 :                         ret = EPKG_FATAL;
     124             : 
     125           0 :                 ret = EPKG_OK;
     126             :         }
     127             : 
     128             : cleanup:
     129           0 :         sqlite3_reset(pkg_repo_binary_stmt_prstatement(REPO_VERSION));
     130             : 
     131           0 :         return (ret);
     132             : }
     133             : 
     134             : static int
     135          24 : pkg_repo_binary_add_pkg(struct pkg *pkg, const char *pkg_path,
     136             :                 sqlite3 *sqlite, bool forced)
     137             : {
     138             :         int                      ret;
     139          24 :         struct pkg_dep          *dep      = NULL;
     140          24 :         struct pkg_option       *option   = NULL;
     141             :         char                    *buf;
     142             :         struct pkg_strel        *el;
     143             :         struct pkg_kv           *kv;
     144             :         const char              *arch;
     145             :         int64_t                  package_id;
     146             : 
     147          24 :         arch = pkg->abi != NULL ? pkg->abi : pkg->arch;
     148             : 
     149             : try_again:
     150          48 :         if ((ret = pkg_repo_binary_run_prstatement(PKG,
     151             :             pkg->origin, pkg->name, pkg->version, pkg->comment, pkg->desc,
     152             :             arch, pkg->maintainer, pkg->www, pkg->prefix, pkg->pkgsize,
     153          24 :             pkg->flatsize, (int64_t)pkg->licenselogic, pkg->sum, pkg->repopath,
     154             :             pkg->digest, pkg->old_digest)) != SQLITE_DONE) {
     155           0 :                 if (ret == SQLITE_CONSTRAINT) {
     156           0 :                         ERROR_SQLITE(sqlite, "grmbl");
     157           0 :                         switch(pkg_repo_binary_delete_conflicting(pkg->origin,
     158           0 :                             pkg->version, pkg_path, forced)) {
     159             :                         case EPKG_FATAL: /* sqlite error */
     160           0 :                                 ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
     161           0 :                                 return (EPKG_FATAL);
     162             :                                 break;
     163             :                         case EPKG_END: /* repo already has newer */
     164           0 :                                 return (EPKG_END);
     165             :                                 break;
     166             :                         default: /* conflict cleared, try again */
     167           0 :                                 goto try_again;
     168             :                                 break;
     169             :                         }
     170             :                 } else {
     171           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
     172           0 :                         return (EPKG_FATAL);
     173             :                 }
     174             :         }
     175          24 :         package_id = sqlite3_last_insert_rowid(sqlite);
     176             : 
     177             : /*      if (pkg_repo_binary_run_prstatement (FTS_APPEND, package_id,
     178             :                         name, version, origin) != SQLITE_DONE) {
     179             :                 ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(FTS_APPEND));
     180             :                 return (EPKG_FATAL);
     181             :         }*/
     182             : 
     183          24 :         dep = NULL;
     184          72 :         while (pkg_deps(pkg, &dep) == EPKG_OK) {
     185          48 :                 if (pkg_repo_binary_run_prstatement(DEPS, dep->origin,
     186          48 :                     dep->name, dep->version, package_id) != SQLITE_DONE) {
     187           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(DEPS));
     188           0 :                         return (EPKG_FATAL);
     189             :                 }
     190             :         }
     191             : 
     192          48 :         LL_FOREACH(pkg->categories, el) {
     193          24 :                 ret = pkg_repo_binary_run_prstatement(CAT1, el->value);
     194          24 :                 if (ret == SQLITE_DONE)
     195          24 :                         ret = pkg_repo_binary_run_prstatement(CAT2, package_id,
     196             :                             el->value);
     197          24 :                 if (ret != SQLITE_DONE) {
     198           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(CAT2));
     199           0 :                         return (EPKG_FATAL);
     200             :                 }
     201             :         }
     202             : 
     203          24 :         LL_FOREACH(pkg->licenses, el) {
     204           0 :                 ret = pkg_repo_binary_run_prstatement(LIC1, el->value);
     205           0 :                 if (ret == SQLITE_DONE)
     206           0 :                         ret = pkg_repo_binary_run_prstatement(LIC2, package_id,
     207             :                             el->value);
     208           0 :                 if (ret != SQLITE_DONE) {
     209           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(LIC2));
     210           0 :                         return (EPKG_FATAL);
     211             :                 }
     212             :         }
     213             : 
     214          24 :         option = NULL;
     215          48 :         while (pkg_options(pkg, &option) == EPKG_OK) {
     216           0 :                 ret = pkg_repo_binary_run_prstatement(OPT1, option->key);
     217           0 :                 if (ret == SQLITE_DONE)
     218           0 :                     ret = pkg_repo_binary_run_prstatement(OPT2, option->key,
     219           0 :                                 option->value, package_id);
     220           0 :                 if(ret != SQLITE_DONE) {
     221           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(OPT2));
     222           0 :                         return (EPKG_FATAL);
     223             :                 }
     224             :         }
     225             : 
     226          24 :         buf = NULL;
     227          48 :         while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) {
     228           0 :                 ret = pkg_repo_binary_run_prstatement(SHLIB1, buf);
     229           0 :                 if (ret == SQLITE_DONE)
     230           0 :                         ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id,
     231             :                             buf);
     232           0 :                 if (ret != SQLITE_DONE) {
     233           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD));
     234           0 :                         return (EPKG_FATAL);
     235             :                 }
     236             :         }
     237             : 
     238          24 :         buf = NULL;
     239          48 :         while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) {
     240           0 :                 ret = pkg_repo_binary_run_prstatement(SHLIB1, buf);
     241           0 :                 if (ret == SQLITE_DONE)
     242           0 :                         ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id,
     243             :                             buf);
     244           0 :                 if (ret != SQLITE_DONE) {
     245           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV));
     246           0 :                         return (EPKG_FATAL);
     247             :                 }
     248             :         }
     249             : 
     250          24 :         buf = NULL;
     251          51 :         while (pkg_provides(pkg, &buf) == EPKG_OK) {
     252           3 :                 ret = pkg_repo_binary_run_prstatement(PROVIDE, buf);
     253           3 :                 if (ret == SQLITE_DONE)
     254           3 :                         ret = pkg_repo_binary_run_prstatement(PROVIDES, package_id,
     255             :                             buf);
     256           3 :                 if (ret != SQLITE_DONE) {
     257           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PROVIDES));
     258           0 :                         return (EPKG_FATAL);
     259             :                 }
     260             :         }
     261             : 
     262          24 :         buf = NULL;
     263          54 :         while (pkg_requires(pkg, &buf) == EPKG_OK) {
     264           6 :                 ret = pkg_repo_binary_run_prstatement(REQUIRE, buf);
     265           6 :                 if (ret == SQLITE_DONE)
     266           6 :                         ret = pkg_repo_binary_run_prstatement(REQUIRES, package_id,
     267             :                             buf);
     268           6 :                 if (ret != SQLITE_DONE) {
     269           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(REQUIRES));
     270           0 :                         return (EPKG_FATAL);
     271             :                 }
     272             :         }
     273             : 
     274          24 :         LL_FOREACH(pkg->annotations, kv) {
     275           0 :                 ret = pkg_repo_binary_run_prstatement(ANNOTATE1, kv->key);
     276           0 :                 if (ret == SQLITE_DONE)
     277           0 :                         ret = pkg_repo_binary_run_prstatement(ANNOTATE1, kv->value);
     278           0 :                 if (ret == SQLITE_DONE)
     279           0 :                         ret = pkg_repo_binary_run_prstatement(ANNOTATE2, package_id,
     280             :                                   kv->key, kv->value);
     281           0 :                 if (ret != SQLITE_DONE) {
     282           0 :                         ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(ANNOTATE2));
     283           0 :                         return (EPKG_FATAL);
     284             :                 }
     285             :         }
     286             : 
     287          24 :         return (EPKG_OK);
     288             : }
     289             : 
     290             : static int
     291           0 : pkg_repo_binary_register_conflicts(const char *origin, char **conflicts,
     292             :                 int conflicts_num, sqlite3 *sqlite)
     293             : {
     294           0 :         const char clean_conflicts_sql[] = ""
     295             :                         "DELETE FROM pkg_conflicts "
     296             :                         "WHERE package_id = ?1;";
     297           0 :         const char select_id_sql[] = ""
     298             :                         "SELECT id FROM packages "
     299             :                         "WHERE origin = ?1;";
     300           0 :         const char insert_conflict_sql[] = ""
     301             :                         "INSERT INTO pkg_conflicts "
     302             :                         "(package_id, conflict_id) "
     303             :                         "VALUES (?1, ?2);";
     304           0 :         sqlite3_stmt *stmt = NULL;
     305             :         int ret, i;
     306             :         int64_t origin_id, conflict_id;
     307             : 
     308           0 :         pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", select_id_sql);
     309           0 :         if (sqlite3_prepare_v2(sqlite, select_id_sql, -1, &stmt, NULL) != SQLITE_OK) {
     310           0 :                 ERROR_SQLITE(sqlite, select_id_sql);
     311           0 :                 return (EPKG_FATAL);
     312             :         }
     313             : 
     314           0 :         sqlite3_bind_text(stmt, 1, origin, -1, SQLITE_TRANSIENT);
     315           0 :         ret = sqlite3_step(stmt);
     316             : 
     317           0 :         if (ret == SQLITE_ROW) {
     318           0 :                 origin_id = sqlite3_column_int64(stmt, 0);
     319             :         }
     320             :         else {
     321           0 :                 ERROR_SQLITE(sqlite, select_id_sql);
     322           0 :                 return (EPKG_FATAL);
     323             :         }
     324           0 :         sqlite3_finalize(stmt);
     325             : 
     326           0 :         pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", clean_conflicts_sql);
     327           0 :         if (sqlite3_prepare_v2(sqlite, clean_conflicts_sql, -1, &stmt, NULL) != SQLITE_OK) {
     328           0 :                 ERROR_SQLITE(sqlite, clean_conflicts_sql);
     329           0 :                 return (EPKG_FATAL);
     330             :         }
     331             : 
     332           0 :         sqlite3_bind_int64(stmt, 1, origin_id);
     333             :         /* Ignore cleanup result */
     334           0 :         (void)sqlite3_step(stmt);
     335             : 
     336           0 :         sqlite3_finalize(stmt);
     337             : 
     338           0 :         for (i = 0; i < conflicts_num; i ++) {
     339             :                 /* Select a conflict */
     340           0 :                 pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", select_id_sql);
     341           0 :                 if (sqlite3_prepare_v2(sqlite, select_id_sql, -1, &stmt, NULL) != SQLITE_OK) {
     342           0 :                         ERROR_SQLITE(sqlite, select_id_sql);
     343           0 :                         return (EPKG_FATAL);
     344             :                 }
     345             : 
     346           0 :                 sqlite3_bind_text(stmt, 1, conflicts[i], -1, SQLITE_TRANSIENT);
     347           0 :                 ret = sqlite3_step(stmt);
     348             : 
     349           0 :                 if (ret == SQLITE_ROW) {
     350           0 :                         conflict_id = sqlite3_column_int64(stmt, 0);
     351             :                 }
     352             :                 else {
     353           0 :                         ERROR_SQLITE(sqlite, select_id_sql);
     354           0 :                         return (EPKG_FATAL);
     355             :                 }
     356             : 
     357           0 :                 sqlite3_finalize(stmt);
     358             : 
     359             :                 /* Insert a pair */
     360           0 :                 pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", insert_conflict_sql);
     361           0 :                 if (sqlite3_prepare_v2(sqlite, insert_conflict_sql, -1, &stmt, NULL) != SQLITE_OK) {
     362           0 :                         ERROR_SQLITE(sqlite, insert_conflict_sql);
     363           0 :                         return (EPKG_FATAL);
     364             :                 }
     365             : 
     366           0 :                 sqlite3_bind_int64(stmt, 1, origin_id);
     367           0 :                 sqlite3_bind_int64(stmt, 2, conflict_id);
     368           0 :                 ret = sqlite3_step(stmt);
     369             : 
     370           0 :                 if (ret != SQLITE_DONE) {
     371           0 :                         ERROR_SQLITE(sqlite, insert_conflict_sql);
     372           0 :                         return (EPKG_FATAL);
     373             :                 }
     374             : 
     375           0 :                 sqlite3_finalize(stmt);
     376             :         }
     377             : 
     378           0 :         return (EPKG_OK);
     379             : }
     380             : 
     381             : static int
     382          24 : pkg_repo_binary_add_from_manifest(char *buf, sqlite3 *sqlite, size_t len,
     383             :                 struct pkg_manifest_key **keys, struct pkg **p __unused,
     384             :                 struct pkg_repo *repo)
     385             : {
     386          24 :         int rc = EPKG_OK;
     387             :         struct pkg *pkg;
     388             : 
     389          24 :         rc = pkg_new(&pkg, PKG_REMOTE);
     390          24 :         if (rc != EPKG_OK)
     391           0 :                 return (EPKG_FATAL);
     392             : 
     393          24 :         pkg_manifest_keys_new(keys);
     394          24 :         rc = pkg_parse_manifest(pkg, buf, len, *keys);
     395          24 :         if (rc != EPKG_OK) {
     396           0 :                 goto cleanup;
     397             :         }
     398             : 
     399          24 :         if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest, strlen(pkg->digest)))
     400          24 :                 pkg_checksum_calculate(pkg, NULL);
     401          24 :         if (pkg->arch == NULL || !is_valid_abi(pkg->arch, true)) {
     402           0 :                 rc = EPKG_FATAL;
     403           0 :                 pkg_emit_error("repository %s contains packages with wrong ABI: %s",
     404           0 :                         repo->name, pkg->arch);
     405           0 :                 goto cleanup;
     406             :         }
     407             : 
     408          24 :         free(pkg->reponame);
     409          24 :         pkg->reponame = strdup(repo->name);
     410             : 
     411          24 :         rc = pkg_repo_binary_add_pkg(pkg, NULL, sqlite, true);
     412             : 
     413             : cleanup:
     414          24 :         pkg_free(pkg);
     415             : 
     416          24 :         return (rc);
     417             : }
     418             : 
     419             : static void __unused
     420           0 : pkg_repo_binary_parse_conflicts(FILE *f, sqlite3 *sqlite)
     421             : {
     422           0 :         size_t linecap = 0;
     423             :         ssize_t linelen;
     424           0 :         char *linebuf = NULL, *p, **deps;
     425             :         const char *origin, *pdep;
     426             :         int ndep, i;
     427           0 :         const char conflicts_clean_sql[] = ""
     428             :                         "DELETE FROM pkg_conflicts;";
     429             : 
     430           0 :         pkg_debug(4, "pkg_parse_conflicts_file: running '%s'", conflicts_clean_sql);
     431           0 :         (void)sql_exec(sqlite, conflicts_clean_sql);
     432             : 
     433           0 :         while ((linelen = getline(&linebuf, &linecap, f)) > 0) {
     434           0 :                 p = linebuf;
     435           0 :                 origin = strsep(&p, ":");
     436             :                 /* Check dependencies number */
     437           0 :                 pdep = p;
     438           0 :                 ndep = 1;
     439           0 :                 while (*pdep != '\0') {
     440           0 :                         if (*pdep == ',')
     441           0 :                                 ndep ++;
     442           0 :                         pdep ++;
     443             :                 }
     444           0 :                 deps = malloc(sizeof(char *) * ndep);
     445           0 :                 for (i = 0; i < ndep; i ++) {
     446           0 :                         deps[i] = strsep(&p, ",\n");
     447             :                 }
     448           0 :                 pkg_repo_binary_register_conflicts(origin, deps, ndep, sqlite);
     449           0 :                 free(deps);
     450             :         }
     451             : 
     452           0 :         free(linebuf);
     453           0 : }
     454             : 
     455             : static int
     456           8 : pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
     457             :         time_t *mtime, bool force)
     458             : {
     459           8 :         struct pkg *pkg = NULL;
     460             :         unsigned char *walk;
     461           8 :         int rc = EPKG_FATAL;
     462           8 :         sqlite3 *sqlite = NULL;
     463           8 :         int cnt = 0;
     464             :         time_t local_t;
     465           8 :         struct pkg_manifest_key *keys = NULL;
     466           8 :         unsigned char *map = MAP_FAILED;
     467           8 :         size_t len = 0;
     468           8 :         bool in_trans = false;
     469             : 
     470           8 :         pkg_debug(1, "Pkgrepo, begin update of '%s'", name);
     471             : 
     472             :         /* In forced mode, ignore mtime */
     473           8 :         if (force)
     474           7 :                 *mtime = 0;
     475             : 
     476             :         /* Fetch meta */
     477           8 :         local_t = *mtime;
     478           8 :         if (pkg_repo_fetch_meta(repo, &local_t) == EPKG_FATAL)
     479           0 :                 pkg_emit_notice("repository %s has no meta file, using "
     480             :                     "default settings", repo->name);
     481             : 
     482             :         /* Fetch packagesite */
     483           8 :         local_t = *mtime;
     484           8 :         map = pkg_repo_fetch_remote_extract_mmap(repo,
     485           8 :                 repo->meta->manifests, &local_t, &rc, &len);
     486           8 :         if (map == NULL || map == MAP_FAILED)
     487             :                 goto cleanup;
     488             : 
     489           7 :         *mtime = local_t;
     490             :         /*fconflicts = repo_fetch_remote_extract_tmp(repo,
     491             :                         repo_conflicts_archive, "txz", &local_t,
     492             :                         &rc, repo_conflicts_file);*/
     493             : 
     494             :         /* Load local repository data */
     495           7 :         rc = pkg_repo_binary_init_update(repo, name);
     496           7 :         if (rc != EPKG_OK) {
     497           0 :                 rc = EPKG_FATAL;
     498           0 :                 goto cleanup;
     499             :         }
     500             : 
     501             :         /* Here sqlite is initialized */
     502           7 :         sqlite = PRIV_GET(repo);
     503             : 
     504           7 :         pkg_debug(1, "Pkgrepo, reading new packagesite.yaml for '%s'", name);
     505             : 
     506           7 :         pkg_emit_progress_start("Processing entries");
     507             : 
     508             :         /* 200MB should be enough */
     509           7 :         sql_exec(sqlite, "PRAGMA mmap_size = 209715200;");
     510           7 :         sql_exec(sqlite, "PRAGMA page_size = %d;", getpagesize());
     511           7 :         sql_exec(sqlite, "PRAGMA foreign_keys = OFF;");
     512           7 :         sql_exec(sqlite, "PRAGMA synchronous = OFF;");
     513             : 
     514           7 :         rc = pkgdb_transaction_begin_sqlite(sqlite, "REPO");
     515           7 :         if (rc != EPKG_OK)
     516           0 :                 goto cleanup;
     517             : 
     518           7 :         in_trans = true;
     519             : 
     520           7 :         walk = map;
     521             :         unsigned char *next;
     522             : 
     523          38 :         while (walk -map < len) {
     524          24 :                 cnt++;
     525          24 :                 next = strchr(walk, '\n');
     526          24 :                 if ((cnt % 10 ) == 0)
     527           0 :                         pkg_emit_progress_tick(next - map, len);
     528          24 :                 rc = pkg_repo_binary_add_from_manifest(walk, sqlite, next - walk,
     529             :                     &keys, &pkg, repo);
     530          24 :                 if (rc != EPKG_OK) {
     531           0 :                         pkg_emit_progress_tick(len, len);
     532           0 :                         break;
     533             :                 }
     534          24 :                 walk = next + 1;
     535             :         }
     536           7 :         pkg_emit_progress_tick(len, len);
     537             : 
     538           7 :         if (rc == EPKG_OK)
     539           7 :                 pkg_emit_incremental_update(repo->name, cnt);
     540             : 
     541           7 :         sql_exec(sqlite, ""
     542             :          "INSERT INTO pkg_search SELECT id, name || '-' || version, origin FROM packages;"
     543             :         "CREATE INDEX packages_origin ON packages(origin COLLATE NOCASE);"
     544             :         "CREATE INDEX packages_name ON packages(name COLLATE NOCASE);"
     545             :         "CREATE INDEX packages_uid_nocase ON packages(name COLLATE NOCASE, origin COLLATE NOCASE);"
     546             :         "CREATE INDEX packages_version_nocase ON packages(name COLLATE NOCASE, version);"
     547             :         "CREATE INDEX packages_uid ON packages(name, origin);"
     548             :         "CREATE INDEX packages_version ON packages(name, version);"
     549             :         "CREATE UNIQUE INDEX packages_digest ON packages(manifestdigest);"
     550             :          );
     551             : 
     552             : cleanup:
     553             : 
     554           8 :         if (in_trans) {
     555           7 :                 if (rc != EPKG_OK)
     556           0 :                         pkgdb_transaction_rollback_sqlite(sqlite, "REPO");
     557             : 
     558           7 :                 if (pkgdb_transaction_commit_sqlite(sqlite, "REPO") != EPKG_OK)
     559           0 :                         rc = EPKG_FATAL;
     560             :         }
     561             : 
     562           8 :         pkg_free(pkg);
     563           8 :         if (map != NULL && map != MAP_FAILED)
     564           7 :                 munmap(map, len);
     565             : 
     566           8 :         return (rc);
     567             : }
     568             : 
     569             : int
     570           8 : pkg_repo_binary_update(struct pkg_repo *repo, bool force)
     571             : {
     572             :         char filepath[MAXPATHLEN];
     573           8 :         const char update_finish_sql[] = ""
     574             :                 "DROP TABLE repo_update;";
     575             :         sqlite3 *sqlite;
     576             : 
     577           8 :         const char *dbdir = NULL;
     578             :         struct stat st;
     579           8 :         time_t t = 0;
     580           8 :         int res = EPKG_FATAL;
     581             : 
     582           8 :         bool got_meta = false;
     583             : 
     584           8 :         sqlite3_initialize();
     585             : 
     586           8 :         if (!pkg_repo_enabled(repo))
     587           0 :                 return (EPKG_OK);
     588             : 
     589           8 :         dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
     590           8 :         pkg_debug(1, "PkgRepo: verifying update for %s", pkg_repo_name(repo));
     591             : 
     592             :         /* First of all, try to open and init repo and check whether it is fine */
     593           8 :         if (repo->ops->open(repo, R_OK|W_OK) != EPKG_OK) {
     594           7 :                 pkg_debug(1, "PkgRepo: need forced update of %s", pkg_repo_name(repo));
     595           7 :                 t = 0;
     596           7 :                 force = true;
     597           7 :                 snprintf(filepath, sizeof(filepath), "%s/%s", dbdir,
     598             :                     pkg_repo_binary_get_filename(pkg_repo_name(repo)));
     599             :         }
     600             :         else {
     601           1 :                 repo->ops->close(repo, false);
     602           1 :                 snprintf(filepath, sizeof(filepath), "%s/%s.meta", dbdir, pkg_repo_name(repo));
     603           1 :                 if (stat(filepath, &st) != -1) {
     604           1 :                         t = force ? 0 : st.st_mtime;
     605           1 :                         got_meta = true;
     606             :                 }
     607             : 
     608           1 :                 snprintf(filepath, sizeof(filepath), "%s/%s", dbdir,
     609             :                         pkg_repo_binary_get_filename(pkg_repo_name(repo)));
     610           1 :                 if (stat(filepath, &st) != -1) {
     611           1 :                         if (!got_meta && !force)
     612           0 :                                 t = st.st_mtime;
     613             :                 }
     614             :         }
     615             : 
     616           8 :         res = pkg_repo_binary_update_proceed(filepath, repo, &t, force);
     617           8 :         if (res != EPKG_OK && res != EPKG_UPTODATE) {
     618           0 :                 pkg_emit_notice("Unable to update repository %s", repo->name);
     619           0 :                 goto cleanup;
     620             :         }
     621             : 
     622             :         /* Finish updated repo */
     623           8 :         if (res == EPKG_OK) {
     624           7 :                 sqlite = PRIV_GET(repo);
     625           7 :                 sql_exec(sqlite, update_finish_sql);
     626             :         }
     627             : 
     628             : cleanup:
     629             :         /* Set mtime from http request if possible */
     630           8 :         if (t != 0 && res == EPKG_OK) {
     631           7 :                 struct timeval ftimes[2] = {
     632             :                         {
     633             :                         .tv_sec = t,
     634             :                         .tv_usec = 0
     635             :                         },
     636             :                         {
     637             :                         .tv_sec = t,
     638             :                         .tv_usec = 0
     639             :                         }
     640             :                 };
     641             : 
     642           7 :                 utimes(filepath, ftimes);
     643           7 :                 if (got_meta) {
     644           0 :                         snprintf(filepath, sizeof(filepath), "%s/%s.meta", dbdir, pkg_repo_name(repo));
     645           0 :                         utimes(filepath, ftimes);
     646             :                 }
     647             :         }
     648             : 
     649           8 :         if (repo->priv != NULL)
     650           7 :                 repo->ops->close(repo, false);
     651             : 
     652           8 :         return (res);
     653             : }

Generated by: LCOV version 1.10