Branch data 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 <fcntl.h>
30 : : #include <regex.h>
31 : : #include <grp.h>
32 : : #include <stdlib.h>
33 : : #include <stdio.h>
34 : : #include <stdbool.h>
35 : : #include <string.h>
36 : : #include <unistd.h>
37 : : #include <libgen.h>
38 : :
39 : : #include <sqlite3.h>
40 : :
41 : : #include <bsd_compat.h>
42 : :
43 : : #include "pkg.h"
44 : : #include "private/event.h"
45 : : #include "private/pkg.h"
46 : : #include "private/pkgdb.h"
47 : : #include "private/utils.h"
48 : : #include "binary.h"
49 : : #include "binary_private.h"
50 : :
51 : : extern struct pkg_ctx ctx;
52 : :
53 : : static void
54 : 0 : sqlite_file_exists(sqlite3_context *ctx, int argc, sqlite3_value **argv)
55 : : {
56 : : char fpath[MAXPATHLEN];
57 : 0 : sqlite3 *db = sqlite3_context_db_handle(ctx);
58 : 0 : char *path = get_dirname(xstrdup(sqlite3_db_filename(db, "main")));
59 : : char *cksum;
60 : :
61 [ # # ]: 0 : if (argc != 2) {
62 : 0 : sqlite3_result_error(ctx, "file_exists needs two argument", -1);
63 : 0 : return;
64 : : }
65 : :
66 : 0 : snprintf(fpath, sizeof(fpath), "%s/%s", path, sqlite3_value_text(argv[0]));
67 : :
68 [ # # ]: 0 : if (access(fpath, R_OK) == 0) {
69 : 0 : cksum = pkg_checksum_file(fpath, PKG_HASH_TYPE_SHA256_HEX);
70 [ # # # # ]: 0 : if (cksum && strcmp(cksum, sqlite3_value_text(argv[1])) == 0)
71 : 0 : sqlite3_result_int(ctx, 1);
72 : : else
73 : 0 : sqlite3_result_int(ctx, 0);
74 : 0 : free(cksum);
75 : 0 : } else {
76 : 0 : sqlite3_result_int(ctx, 0);
77 : : }
78 : 0 : free(path);
79 : 0 : }
80 : :
81 : : static int
82 : 781 : pkg_repo_binary_get_user_version(sqlite3 *sqlite, int *reposcver)
83 : : {
84 : : sqlite3_stmt *stmt;
85 : : int retcode;
86 : 781 : const char *sql = "PRAGMA user_version;";
87 : :
88 [ - + ]: 781 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
89 : 0 : ERROR_SQLITE(sqlite, sql);
90 : 0 : return (EPKG_FATAL);
91 : : }
92 : :
93 [ + - ]: 781 : if (sqlite3_step(stmt) == SQLITE_ROW) {
94 : 781 : *reposcver = sqlite3_column_int64(stmt, 0);
95 : 781 : retcode = EPKG_OK;
96 : 781 : } else {
97 : 0 : *reposcver = -1;
98 : 0 : retcode = EPKG_FATAL;
99 : : }
100 : 781 : sqlite3_finalize(stmt);
101 : 781 : return (retcode);
102 : 781 : }
103 : :
104 : : static int
105 : 0 : pkg_repo_binary_set_version(sqlite3 *sqlite, int reposcver)
106 : : {
107 : 0 : const char *sql = "PRAGMA user_version = %d;";
108 : :
109 [ # # ]: 0 : if (sql_exec(sqlite, sql, reposcver) != EPKG_OK) {
110 : 0 : ERROR_SQLITE(sqlite, sql);
111 : 0 : return (EPKG_FATAL);
112 : : }
113 : :
114 : 0 : return (EPKG_OK);
115 : 0 : }
116 : :
117 : : static int
118 : 0 : pkg_repo_binary_apply_change(struct pkg_repo *repo, sqlite3 *sqlite,
119 : : const struct repo_changes *repo_changes, const char *updown,
120 : : int version, int *next_version)
121 : : {
122 : : const struct repo_changes *change;
123 : 0 : bool found = false, in_trans = false;
124 : 0 : int ret = EPKG_OK;
125 : : char *errmsg;
126 : :
127 [ # # ]: 0 : for (change = repo_changes; change->version != -1; change++) {
128 [ # # ]: 0 : if (change->version == version) {
129 : 0 : found = true;
130 : 0 : break;
131 : : }
132 : 0 : }
133 [ # # ]: 0 : if (!found) {
134 : 0 : pkg_emit_error("Unable to %s \"%s\" repo schema "
135 : : "version %d (target version %d) "
136 : 0 : "-- change not found", updown, repo->name, version,
137 : : REPO_SCHEMA_VERSION);
138 : 0 : return (EPKG_FATAL);
139 : : }
140 : :
141 : : /* begin transaction */
142 [ # # ]: 0 : if ((ret = pkgdb_transaction_begin_sqlite(sqlite, "SCHEMA")) == EPKG_OK)
143 : 0 : in_trans = true;
144 : :
145 : : /* apply change */
146 [ # # ]: 0 : if (ret == EPKG_OK) {
147 : 0 : pkg_debug(4, "Pkgdb: running '%s'", change->sql);
148 : 0 : ret = sqlite3_exec(sqlite, change->sql, NULL, NULL, &errmsg);
149 [ # # ]: 0 : if (ret != SQLITE_OK) {
150 : 0 : pkg_emit_error("sqlite: %s", errmsg);
151 : 0 : sqlite3_free(errmsg);
152 : 0 : ret = EPKG_FATAL;
153 : 0 : }
154 : 0 : }
155 : :
156 : : /* update repo user_version */
157 [ # # ]: 0 : if (ret == EPKG_OK) {
158 : 0 : *next_version = change->next_version;
159 : 0 : ret = pkg_repo_binary_set_version(sqlite, *next_version);
160 : 0 : }
161 : :
162 : : /* commit or rollback */
163 [ # # ]: 0 : if (in_trans) {
164 [ # # ]: 0 : if (ret != EPKG_OK)
165 : 0 : pkgdb_transaction_rollback_sqlite(sqlite, "SCHEMA");
166 : :
167 [ # # ]: 0 : if (pkgdb_transaction_commit_sqlite(sqlite, "SCHEMA") != EPKG_OK)
168 : 0 : ret = EPKG_FATAL;
169 : 0 : }
170 : :
171 [ # # ]: 0 : if (ret == EPKG_OK) {
172 : 0 : pkg_emit_notice("Repo \"%s\" %s schema %d to %d: %s",
173 : 0 : repo->name, updown, version,
174 : 0 : change->next_version, change->message);
175 : 0 : }
176 : :
177 : 0 : return (ret);
178 : 0 : }
179 : :
180 : : static int
181 : 0 : pkg_repo_binary_upgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
182 : : {
183 : : int version;
184 : : int next_version;
185 : 0 : int ret = EPKG_OK;
186 : :
187 [ # # ]: 0 : for (version = current_version;
188 : 0 : version < REPO_SCHEMA_VERSION;
189 : 0 : version = next_version) {
190 : 0 : ret = pkg_repo_binary_apply_change(repo, sqlite, repo_upgrades,
191 : 0 : "upgrade", version, &next_version);
192 [ # # ]: 0 : if (ret != EPKG_OK)
193 : 0 : break;
194 : 0 : pkg_debug(1, "Upgrading repo database schema from %d to %d",
195 : 0 : version, next_version);
196 : 0 : }
197 : 0 : return (ret);
198 : : }
199 : :
200 : : static int
201 : 0 : pkg_repo_binary_downgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version)
202 : : {
203 : : int version;
204 : : int next_version;
205 : 0 : int ret = EPKG_OK;
206 : :
207 [ # # ]: 0 : for (version = current_version;
208 : 0 : version > REPO_SCHEMA_VERSION;
209 : 0 : version = next_version) {
210 : :
211 : 0 : ret = pkg_repo_binary_apply_change(repo, sqlite, repo_downgrades,
212 : 0 : "downgrade", version, &next_version);
213 [ # # ]: 0 : if (ret != EPKG_OK)
214 : 0 : break;
215 : 0 : pkg_debug(1, "Downgrading repo database schema from %d to %d",
216 : 0 : version, next_version);
217 : 0 : }
218 : 0 : return (ret);
219 : : }
220 : :
221 : : int
222 : 781 : pkg_repo_binary_check_version(struct pkg_repo *repo, sqlite3 *sqlite)
223 : : {
224 : : int reposcver;
225 : : int repomajor;
226 : : int ret;
227 : :
228 [ - + - + ]: 1562 : if ((ret = pkg_repo_binary_get_user_version(sqlite, &reposcver))
229 : 781 : != EPKG_OK)
230 : 0 : return (ret); /* sqlite error */
231 : :
232 : : /*
233 : : * If the local pkgng uses a repo schema behind that used to
234 : : * create the repo, we may still be able use it for reading
235 : : * (ie pkg install), but pkg repo can't do an incremental
236 : : * update unless the actual schema matches the compiled in
237 : : * schema version.
238 : : *
239 : : * Use a major - minor version schema: as the user_version
240 : : * PRAGMA takes an integer version, encode this as MAJOR *
241 : : * 1000 + MINOR.
242 : : *
243 : : * So long as the major versions are the same, the local pkgng
244 : : * should be compatible with any repo created by a more recent
245 : : * pkgng, although it may need some modification of the repo
246 : : * schema
247 : : */
248 : :
249 : : /* --- Temporary ---- Grandfather in the old repo schema
250 : : version so this patch doesn't immediately invalidate all
251 : : the repos out there */
252 : :
253 [ + - ]: 781 : if (reposcver == 2)
254 : 0 : reposcver = 2000;
255 [ + - ]: 781 : if (reposcver == 3)
256 : 0 : reposcver = 2001;
257 : :
258 : 781 : repomajor = reposcver / 1000;
259 : :
260 [ - + ]: 781 : if (repomajor < REPO_SCHEMA_MAJOR) {
261 : 0 : pkg_emit_error("Repo %s (schema version %d) is too old - "
262 : 0 : "need at least schema %d", repo->name, reposcver,
263 : : REPO_SCHEMA_MAJOR * 1000);
264 : 0 : return (EPKG_REPOSCHEMA);
265 : : }
266 : :
267 [ - + ]: 781 : if (repomajor > REPO_SCHEMA_MAJOR) {
268 : 0 : pkg_emit_error("Repo %s (schema version %d) is too new - "
269 : 0 : "we can accept at most schema %d", repo->name, reposcver,
270 : : ((REPO_SCHEMA_MAJOR + 1) * 1000) - 1);
271 : 0 : return (EPKG_REPOSCHEMA);
272 : : }
273 : :
274 : : /* This is a repo schema version we can work with */
275 : :
276 : 781 : ret = EPKG_OK;
277 : :
278 [ - + ]: 781 : if (reposcver < REPO_SCHEMA_VERSION) {
279 [ # # ]: 0 : if (sqlite3_db_readonly(sqlite, "main")) {
280 : 0 : pkg_emit_error("Repo %s needs schema upgrade from "
281 : 0 : "%d to %d but it is opened readonly", repo->name,
282 : 0 : reposcver, REPO_SCHEMA_VERSION);
283 : 0 : ret = EPKG_FATAL;
284 : 0 : } else
285 : 0 : ret = pkg_repo_binary_upgrade(repo, sqlite, reposcver);
286 [ + - ]: 781 : } else if (reposcver > REPO_SCHEMA_VERSION) {
287 [ # # ]: 0 : if (sqlite3_db_readonly(sqlite, "main")) {
288 : 0 : pkg_emit_error("Repo %s needs schema downgrade from "
289 : 0 : "%d to %d but it is opened readonly", repo->name,
290 : 0 : reposcver, REPO_SCHEMA_VERSION
291 : : );
292 : 0 : ret = EPKG_FATAL;
293 : 0 : } else
294 : 0 : ret = pkg_repo_binary_downgrade(repo, sqlite, reposcver);
295 : 0 : }
296 : :
297 : 781 : return (ret);
298 : 781 : }
299 : :
300 : : int
301 : 1011 : pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
302 : : {
303 : : char filepath[MAXPATHLEN];
304 : 1011 : sqlite3 *sqlite = NULL;
305 : : int flags, dbdirfd, fd;
306 : : int64_t res;
307 : : struct pkg_repo_it *it;
308 : 1011 : struct pkg *pkg = NULL;
309 : :
310 : 1011 : sqlite3_initialize();
311 : :
312 : 1011 : pkgdb_syscall_overload();
313 : :
314 : 1011 : dbdirfd = pkg_get_dbdirfd();
315 : 1011 : snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));
316 : :
317 : : /* Open metafile */
318 [ + + ]: 1011 : if ((fd = openat(dbdirfd, filepath, O_RDONLY)) != -1) {
319 [ - + ]: 781 : if (pkg_repo_meta_load(fd, &repo->meta) != EPKG_OK) {
320 : 0 : pkg_emit_error("Repository %s load error: "
321 : 0 : "meta cannot be loaded %s", pkg_repo_name(repo),
322 : 0 : strerror(errno));
323 : 0 : close(fd);
324 : 0 : return (EPKG_FATAL);
325 : : }
326 : 781 : close(fd);
327 : 781 : }
328 : :
329 : 2022 : snprintf(filepath, sizeof(filepath), "%s",
330 : 1011 : pkg_repo_binary_get_filename(pkg_repo_name(repo)));
331 : :
332 : : /* Always want read mode here */
333 [ + + ]: 1011 : if (faccessat(dbdirfd, filepath, R_OK | mode, 0) != 0) {
334 : 230 : return (EPKG_ENOACCESS);
335 : : }
336 : :
337 : 781 : flags = (mode & W_OK) != 0 ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
338 [ - + ]: 781 : if (sqlite3_open_v2(filepath, &sqlite, flags, NULL) != SQLITE_OK) {
339 : 0 : pkgdb_nfs_corruption(sqlite);
340 : 0 : pkg_emit_error("Repository %s load error: "
341 : 0 : "cannot open sqlite3 db: %s", pkg_repo_name(repo),
342 : 0 : strerror(errno));
343 : 0 : return (EPKG_FATAL);
344 : : }
345 : :
346 : : /* Sanitise sqlite database */
347 [ - + - + ]: 1562 : if (get_pragma(sqlite, "SELECT count(name) FROM sqlite_master "
348 : 781 : "WHERE type='table' AND name='repodata';", &res, false) != EPKG_OK) {
349 : 0 : pkg_emit_error("Repository %s load error: "
350 : 0 : "unable to query db: %s", pkg_repo_name(repo),
351 : 0 : strerror(errno));
352 : 0 : sqlite3_close(sqlite);
353 : 0 : return (EPKG_FATAL);
354 : : }
355 : :
356 [ - + ]: 781 : if (res != 1) {
357 : 0 : pkg_emit_error("Repository %s contains no repodata table, "
358 : 0 : "need to re-create database", repo->name);
359 : 0 : sqlite3_close(sqlite);
360 : 0 : return (EPKG_FATAL);
361 : : }
362 : :
363 : : /* Check package site */
364 : 781 : char *req = sqlite3_mprintf("select count(key) from repodata "
365 : 781 : "WHERE key = \"packagesite\" and value = '%q'", pkg_repo_url(repo));
366 : :
367 : 781 : res = 0;
368 : 781 : get_pragma(sqlite, req, &res, true);
369 : 781 : sqlite3_free(req);
370 [ - + ]: 781 : if (res != 1) {
371 : 0 : pkg_emit_error("Repository %s has a wrong packagesite, need to "
372 : 0 : "re-create database", repo->name);
373 : 0 : sqlite3_close(sqlite);
374 : 0 : return (EPKG_FATAL);
375 : : }
376 : :
377 : : /* Check version */
378 [ - + ]: 781 : if (pkg_repo_binary_check_version(repo, sqlite) != EPKG_OK) {
379 : 0 : pkg_emit_error("need to re-create repo %s to upgrade schema version",
380 : 0 : repo->name);
381 : 0 : sqlite3_close(sqlite);
382 [ # # ]: 0 : if (mode & W_OK)
383 : 0 : unlink(filepath);
384 : 0 : return (EPKG_REPOSCHEMA);
385 : : }
386 : :
387 : 781 : repo->priv = sqlite;
388 : : /* Check digests format */
389 [ + - ]: 781 : if ((it = pkg_repo_binary_query(repo, NULL, NULL, MATCH_ALL)) == NULL)
390 : 0 : return (EPKG_OK);
391 : :
392 [ + + ]: 781 : if (it->ops->next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
393 : 244 : it->ops->free(it);
394 : 244 : return (EPKG_OK);
395 : : }
396 : 537 : it->ops->free(it);
397 [ + - - + ]: 537 : if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest, strlen(pkg->digest))) {
398 : 0 : pkg_emit_error("Repository %s has incompatible checksum format, need to "
399 : 0 : "re-create database", repo->name);
400 : 0 : pkg_free(pkg);
401 : 0 : sqlite3_close(sqlite);
402 : 0 : repo->priv = NULL;
403 : 0 : return (EPKG_FATAL);
404 : : }
405 : 537 : pkg_free(pkg);
406 : :
407 : 537 : return (EPKG_OK);
408 : 1011 : }
409 : :
410 : : int
411 : 244 : pkg_repo_binary_create(struct pkg_repo *repo)
412 : : {
413 : : char filepath[MAXPATHLEN];
414 : 244 : sqlite3 *sqlite = NULL;
415 : : int retcode, dbdirfd;
416 : :
417 : 244 : sqlite3_initialize();
418 : :
419 : 244 : dbdirfd = pkg_get_dbdirfd();
420 : 488 : snprintf(filepath, sizeof(filepath), "%s",
421 : 244 : pkg_repo_binary_get_filename(pkg_repo_name(repo)));
422 : : /* Should never ever happen */
423 [ + - ]: 244 : if (faccessat(dbdirfd, filepath, R_OK, 0) == 0)
424 : 0 : return (EPKG_CONFLICT);
425 : :
426 : 244 : pkgdb_syscall_overload();
427 : :
428 : : /* Open for read/write/create */
429 [ - + ]: 244 : if (sqlite3_open(filepath, &sqlite) != SQLITE_OK) {
430 : 0 : pkgdb_nfs_corruption(sqlite);
431 : 0 : return (EPKG_FATAL);
432 : : }
433 : :
434 : 244 : retcode = sql_exec(sqlite, binary_repo_initsql, REPO_SCHEMA_VERSION);
435 : :
436 [ - + ]: 488 : if (retcode == EPKG_OK) {
437 : : sqlite3_stmt *stmt;
438 : 244 : const char sql[] = ""
439 : : "INSERT OR REPLACE INTO repodata (key, value) "
440 : : "VALUES (\"packagesite\", ?1);";
441 : :
442 : : /* register the packagesite */
443 [ - + - + ]: 488 : if (sql_exec(sqlite, "CREATE TABLE IF NOT EXISTS repodata ("
444 : : " key TEXT UNIQUE NOT NULL,"
445 : : " value TEXT NOT NULL"
446 : 244 : ");") != EPKG_OK) {
447 : 0 : pkg_emit_error("Unable to register the packagesite in the "
448 : : "database");
449 : 0 : retcode = EPKG_FATAL;
450 : 0 : goto cleanup;
451 : : }
452 : :
453 [ - + ]: 244 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
454 : 0 : ERROR_SQLITE(sqlite, sql);
455 : 0 : retcode = EPKG_FATAL;
456 : 0 : goto cleanup;
457 : : }
458 : :
459 : 244 : sqlite3_bind_text(stmt, 1, pkg_repo_url(repo), -1, SQLITE_STATIC);
460 : :
461 [ - + ]: 244 : if (sqlite3_step(stmt) != SQLITE_DONE) {
462 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
463 : 0 : sqlite3_finalize(stmt);
464 : 0 : retcode = EPKG_FATAL;
465 : 0 : goto cleanup;
466 : : }
467 : :
468 : 244 : sqlite3_finalize(stmt);
469 : 244 : }
470 : :
471 : : cleanup:
472 : 244 : sqlite3_close(sqlite);
473 : :
474 : 244 : return (retcode);
475 : 244 : }
476 : :
477 : : int
478 : 595 : pkg_repo_binary_init(struct pkg_repo *repo)
479 : : {
480 : 595 : int retcode = EPKG_OK;
481 [ + - ]: 595 : sqlite3 *sqlite = PRIV_GET(repo);
482 : :
483 : 595 : sqlite3_create_function(sqlite, "file_exists", 2, SQLITE_ANY, NULL,
484 : : sqlite_file_exists, NULL, NULL);
485 : 595 : retcode = sql_exec(sqlite, "PRAGMA synchronous=default");
486 [ - + ]: 595 : if (retcode != EPKG_OK)
487 : 0 : return (retcode);
488 : :
489 : 595 : retcode = sql_exec(sqlite, "PRAGMA foreign_keys=on");
490 [ - + ]: 595 : if (retcode != EPKG_OK)
491 : 0 : return (retcode);
492 : 595 : sql_exec(sqlite, "PRAGMA mmap_size=268435456;");
493 : :
494 : :
495 : 595 : pkgdb_sqlcmd_init(sqlite, NULL, NULL);
496 : :
497 : 595 : retcode = pkg_repo_binary_init_prstatements(sqlite);
498 [ - + ]: 595 : if (retcode != EPKG_OK)
499 : 0 : return (retcode);
500 : :
501 : 595 : repo->priv = sqlite;
502 : :
503 : 595 : return (EPKG_OK);
504 : 595 : }
505 : :
506 : : int
507 : 781 : pkg_repo_binary_close(struct pkg_repo *repo, bool commit)
508 : : {
509 : 781 : int retcode = EPKG_OK;
510 [ + - ]: 781 : sqlite3 *sqlite = PRIV_GET(repo);
511 : :
512 [ + - ]: 781 : if (sqlite == NULL)
513 : 0 : return (retcode);
514 : :
515 [ + - ]: 781 : if (commit) {
516 [ # # ]: 0 : if (pkgdb_transaction_commit_sqlite(sqlite, NULL) != SQLITE_OK)
517 : 0 : retcode = EPKG_FATAL;
518 : 0 : }
519 : :
520 : 781 : pkg_repo_binary_finalize_prstatements();
521 : 781 : sqlite3_close(sqlite);
522 : :
523 : 781 : repo->priv = NULL;
524 : :
525 : 781 : return (retcode);
526 : 781 : }
527 : :
528 : : int
529 : 846 : pkg_repo_binary_access(struct pkg_repo *repo, unsigned mode)
530 : : {
531 : 846 : int ret = EPKG_OK;
532 : :
533 : 1692 : ret = pkgdb_check_access(mode,
534 : 846 : pkg_repo_binary_get_filename(pkg_repo_name(repo)));
535 : :
536 : 846 : return (ret);
537 : : }
|