Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2024 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
5 : : * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
6 : : * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
7 : : * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
8 : : * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
9 : : * Copyright (c) 2013 Gerald Pfeifer <gerald@pfeifer.com>
10 : : * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
11 : : * Copyright (c) 2023 Serenity Cyber Security, LLC
12 : : * Author: Gleb Popov <arrowd@FreeBSD.org>
13 : : *
14 : : * SPDX-License-Identifier: BSD-2-Clause
15 : : */
16 : :
17 : : #ifdef HAVE_CONFIG_H
18 : : #include "pkg_config.h"
19 : : #endif
20 : :
21 : : #include <bsd_compat.h>
22 : :
23 : : #include <sys/param.h>
24 : : #include <sys/mount.h>
25 : :
26 : : #include <assert.h>
27 : : #include <errno.h>
28 : : #include <regex.h>
29 : : #include <grp.h>
30 : : #ifdef HAVE_LIBUTIL_H
31 : : #include <libutil.h>
32 : : #endif
33 : : #include <stdlib.h>
34 : : #include <stdio.h>
35 : : #include <stdbool.h>
36 : : #include <string.h>
37 : : #include <unistd.h>
38 : : #include <signal.h>
39 : : #include <fcntl.h>
40 : :
41 : : #include <sqlite3.h>
42 : :
43 : : #if defined(HAVE_SYS_STATVFS_H)
44 : : #include <sys/statvfs.h>
45 : : #endif
46 : :
47 : : #include "pkg.h"
48 : : #include "private/event.h"
49 : : #include "private/pkg.h"
50 : : #include "private/pkgdb.h"
51 : : #include "private/utils.h"
52 : : #include "private/pkg_deps.h"
53 : : #include "tllist.h"
54 : : #include "pkgvec.h"
55 : :
56 : : #include "private/db_upgrades.h"
57 : :
58 : : extern struct pkg_ctx ctx;
59 : :
60 : : #define dbg(x, ...) pkg_dbg(PKG_DBG_DB, x, __VA_ARGS__)
61 : :
62 : : /* An application using a libpkg() DBVERSION is assumed to be compatible
63 : : with:
64 : :
65 : : * Any lower schema version of the DB, by updating the schema to DBVERSION
66 : : * Any equal schema version of the DB
67 : : * Any greater schema version of the DB with the same DB_SCHEMA_MAJOR
68 : : -- In general, it is OK to add new tables, but modifying or removing old
69 : : tables must be avoided. If necessary, this may be achieved by creating
70 : : appropriate VIEWS and TRIGGERS to mimic the older structure.
71 : :
72 : : Anyone wishing to make a schema change that necessitates incrementing
73 : : DB_SCHEMA_MAJOR must first present every other pkgng developer with one
74 : : of the Golden Apples of the Hesperides
75 : : */
76 : :
77 : : #define DB_SCHEMA_MAJOR 0
78 : : #define DB_SCHEMA_MINOR 36
79 : :
80 : : #define DBVERSION (DB_SCHEMA_MAJOR * 1000 + DB_SCHEMA_MINOR)
81 : :
82 : : static int pkgdb_upgrade(struct pkgdb *);
83 : : static int prstmt_initialize(struct pkgdb *db);
84 : : /* static int run_prstmt(sql_prstmt_index s, ...); */
85 : : static void prstmt_finalize(struct pkgdb *db);
86 : : static int pkgdb_insert_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s);
87 : : static int pkgdb_insert_lua_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s);
88 : :
89 : : extern int sqlite3_shell(int, char**);
90 : :
91 : : struct sqlite3_stmt *
92 : 15792 : prepare_sql(sqlite3 *s, const char *sql)
93 : : {
94 : : int ret;
95 : : sqlite3_stmt *stmt;
96 : :
97 : 15792 : ret = sqlite3_prepare_v2(s, sql, strlen(sql), &stmt,
98 : : NULL);
99 [ - + ]: 15792 : if (ret != SQLITE_OK) {
100 : 0 : ERROR_SQLITE(s, sql);
101 : 0 : return (NULL);
102 : : }
103 : 15792 : return (stmt);
104 : 15792 : }
105 : :
106 : : void
107 : 25 : pkgdb_regex(sqlite3_context *ctx, int argc, sqlite3_value **argv)
108 : : {
109 : 25 : const unsigned char *regex = NULL;
110 : : const unsigned char *str;
111 : : regex_t *re;
112 : : int ret;
113 : :
114 [ - + ]: 25 : if (argc != 2) {
115 : 0 : sqlite3_result_error(ctx, "SQL function regex() called "
116 : : "with invalid number of arguments.\n", -1);
117 : 0 : return;
118 : : }
119 [ + - ]: 25 : if ((regex = sqlite3_value_text(argv[0])) == NULL) {
120 : 0 : sqlite3_result_error(ctx, "SQL function regex() called "
121 : : "without a regular expression.\n", -1);
122 : 0 : return;
123 : : }
124 : :
125 : 25 : re = (regex_t *)sqlite3_get_auxdata(ctx, 0);
126 [ + + ]: 25 : if (re == NULL) {
127 : : int cflags;
128 : :
129 [ - + ]: 15 : if (pkgdb_case_sensitive())
130 : 0 : cflags = REG_EXTENDED | REG_NOSUB;
131 : : else
132 : 15 : cflags = REG_EXTENDED | REG_NOSUB | REG_ICASE;
133 : :
134 : 15 : re = xmalloc(sizeof(regex_t));
135 [ - + ]: 15 : if (regcomp(re, regex, cflags) != 0) {
136 : 0 : sqlite3_result_error(ctx, "Invalid regex\n", -1);
137 : 0 : free(re);
138 : 0 : return;
139 : : }
140 : :
141 : 15 : sqlite3_set_auxdata(ctx, 0, re, pkgdb_regex_delete);
142 : 15 : }
143 : :
144 [ - + ]: 25 : if ((str = sqlite3_value_text(argv[1])) != NULL) {
145 : 25 : ret = regexec(re, str, 0, NULL, 0);
146 : 25 : sqlite3_result_int(ctx, (ret != REG_NOMATCH));
147 : 25 : }
148 : 25 : }
149 : :
150 : : void
151 : 15 : pkgdb_regex_delete(void *p)
152 : : {
153 : 15 : regex_t *re = (regex_t *)p;
154 : :
155 : 15 : regfree(re);
156 : 15 : free(re);
157 : 15 : }
158 : :
159 : : void
160 : 246 : pkgdb_now(sqlite3_context *ctx, int argc, __unused sqlite3_value **argv)
161 : : {
162 [ - + ]: 246 : if (argc != 0) {
163 : 0 : sqlite3_result_error(ctx, "Invalid usage of now() "
164 : : "no arguments expected\n", -1);
165 : 0 : return;
166 : : }
167 : :
168 : 246 : sqlite3_result_int64(ctx, (int64_t)time(NULL));
169 : 246 : }
170 : :
171 : : static void
172 : 0 : pkgdb_vercmp(sqlite3_context *ctx, int argc, sqlite3_value **argv)
173 : : {
174 : : const char *op_str, *arg1, *arg2;
175 : : enum pkg_dep_version_op op;
176 : : int cmp;
177 : : bool ret;
178 : :
179 [ # # ]: 0 : if (argc != 3) {
180 : 0 : sqlite3_result_error(ctx, "Invalid usage of vercmp\n", -1);
181 : 0 : return;
182 : : }
183 : :
184 : 0 : op_str = sqlite3_value_text(argv[0]);
185 : 0 : arg1 = sqlite3_value_text(argv[1]);
186 : 0 : arg2 = sqlite3_value_text(argv[2]);
187 : :
188 [ # # # # : 0 : if (op_str == NULL || arg1 == NULL || arg2 == NULL) {
# # ]
189 : 0 : sqlite3_result_error(ctx, "Invalid usage of vercmp\n", -1);
190 : 0 : return;
191 : : }
192 : :
193 : 0 : op = pkg_deps_string_toop(op_str);
194 : 0 : cmp = pkg_version_cmp(arg1, arg2);
195 : :
196 [ # # # # : 0 : switch(op) {
# # # # ]
197 : 0 : case VERSION_ANY:
198 : : default:
199 : 0 : ret = true;
200 : 0 : break;
201 : : case VERSION_EQ:
202 : 0 : ret = (cmp == 0);
203 : 0 : break;
204 : : case VERSION_GE:
205 : 0 : ret = (cmp >= 0);
206 : 0 : break;
207 : : case VERSION_LE:
208 : 0 : ret = (cmp <= 0);
209 : 0 : break;
210 : : case VERSION_GT:
211 : 0 : ret = (cmp > 0);
212 : 0 : break;
213 : : case VERSION_LT:
214 : 0 : ret = (cmp < 0);
215 : 0 : break;
216 : : case VERSION_NOT:
217 : 0 : ret = (cmp != 0);
218 : 0 : break;
219 : : }
220 : :
221 : 0 : sqlite3_result_int(ctx, ret);
222 : 0 : }
223 : :
224 : : static int
225 : 380 : pkgdb_upgrade(struct pkgdb *db)
226 : : {
227 : 380 : int64_t db_version = -1;
228 : : const char *sql_upgrade;
229 : : int i, ret;
230 : :
231 [ + - ]: 380 : assert(db != NULL);
232 : :
233 : 380 : ret = get_pragma(db->sqlite, "PRAGMA user_version;", &db_version, false);
234 [ - + ]: 380 : if (ret != EPKG_OK)
235 : 0 : return (EPKG_FATAL);
236 : :
237 [ + - ]: 380 : if (db_version == DBVERSION)
238 : 380 : return (EPKG_OK);
239 [ # # ]: 0 : else if (db_version > DBVERSION) {
240 [ # # ]: 0 : if (db_version / 1000 <= DB_SCHEMA_MAJOR) {
241 : : /* VIEWS and TRIGGERS used as compatibility hack */
242 : 0 : pkg_emit_error("warning: database version %" PRId64
243 : : " is newer than libpkg(3) version %d, but still "
244 : 0 : "compatible", db_version, DBVERSION);
245 : 0 : return (EPKG_OK);
246 : : } else {
247 : 0 : pkg_emit_error("database version %" PRId64 " is newer "
248 : : "than and incompatible with libpkg(3) version %d",
249 : 0 : db_version, DBVERSION);
250 : 0 : return (EPKG_FATAL);
251 : : }
252 : : }
253 : :
254 [ # # ]: 0 : while (db_version < DBVERSION) {
255 : : const char *sql_str;
256 [ # # ]: 0 : if (sqlite3_db_readonly(db->sqlite, "main")) {
257 : 0 : pkg_emit_error("The database is outdated and "
258 : : "opened readonly");
259 : 0 : return (EPKG_FATAL);
260 : : }
261 : 0 : db_version++;
262 : :
263 : 0 : i = 0;
264 : 0 : sql_upgrade = NULL;
265 [ # # ]: 0 : while (db_upgrades[i].version != -1) {
266 [ # # ]: 0 : if (db_upgrades[i].version == db_version) {
267 : 0 : sql_upgrade = db_upgrades[i].sql;
268 : 0 : break;
269 : : }
270 : 0 : i++;
271 : : }
272 : :
273 : : /*
274 : : * We can't find the statements to upgrade to the next version,
275 : : * maybe because the current version is too old and upgrade
276 : : * support has been removed.
277 : : */
278 [ # # ]: 0 : if (sql_upgrade == NULL) {
279 : 0 : pkg_emit_error("can not upgrade to db version %" PRId64,
280 : 0 : db_version);
281 : 0 : return (EPKG_FATAL);
282 : : }
283 : :
284 [ # # ]: 0 : if (pkgdb_transaction_begin_sqlite(db->sqlite, NULL) != EPKG_OK)
285 : 0 : return (EPKG_FATAL);
286 : :
287 [ # # ]: 0 : if (sql_exec(db->sqlite, sql_upgrade) != EPKG_OK) {
288 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
289 : 0 : return (EPKG_FATAL);
290 : : }
291 : :
292 : 0 : sql_str = "PRAGMA user_version = %" PRId64 ";";
293 : 0 : ret = sql_exec(db->sqlite, sql_str, db_version);
294 [ # # ]: 0 : if (ret != EPKG_OK) {
295 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
296 : 0 : return (EPKG_FATAL);
297 : : }
298 : :
299 [ # # ]: 0 : if (pkgdb_transaction_commit_sqlite(db->sqlite, NULL) != EPKG_OK)
300 : 0 : return (EPKG_FATAL);
301 : : }
302 : :
303 : 0 : return (EPKG_OK);
304 : 380 : }
305 : :
306 : : /*
307 : : * in the database :
308 : : * scripts.type can be:
309 : : * - 0: PRE_INSTALL
310 : : * - 1: POST_INSTALL
311 : : * - 2: PRE_DEINSTALL
312 : : * - 3: POST_DEINSTALL
313 : : * - 4: PRE_UPGRADE
314 : : * - 5: POST_UPGRADE
315 : : * - 6: INSTALL
316 : : * - 7: DEINSTALL
317 : : * - 8: UPGRADE
318 : : */
319 : :
320 : : static int
321 : 144 : pkgdb_init(sqlite3 *sdb)
322 : : {
323 : 144 : const char sql[] = ""
324 : : "PRAGMA journal_mode = TRUNCATE;"
325 : : "PRAGMA synchronous = FULL;"
326 : : "BEGIN;"
327 : : "CREATE TABLE packages ("
328 : : "id INTEGER PRIMARY KEY,"
329 : : "origin TEXT NOT NULL,"
330 : : "name TEXT NOT NULL,"
331 : : "version TEXT NOT NULL,"
332 : : "comment TEXT NOT NULL,"
333 : : "desc TEXT NOT NULL,"
334 : : "mtree_id INTEGER, "
335 : : "message TEXT,"
336 : : "arch TEXT NOT NULL,"
337 : : "maintainer TEXT NOT NULL, "
338 : : "www TEXT,"
339 : : "prefix TEXT NOT NULL,"
340 : : "flatsize INTEGER NOT NULL,"
341 : : "automatic INTEGER NOT NULL,"
342 : : "locked INTEGER NOT NULL DEFAULT 0,"
343 : : "licenselogic INTEGER NOT NULL,"
344 : : "time INTEGER, "
345 : : "manifestdigest TEXT NULL, "
346 : : "pkg_format_version INTEGER,"
347 : : "dep_formula TEXT NULL"
348 : : ",vital INTEGER NOT NULL DEFAULT 0"
349 : : ");"
350 : : "CREATE UNIQUE INDEX packages_unique ON packages(name);"
351 : : "CREATE TABLE pkg_script ("
352 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
353 : : " ON UPDATE CASCADE,"
354 : : "type INTEGER,"
355 : : "script_id INTEGER REFERENCES script(script_id)"
356 : : " ON DELETE RESTRICT ON UPDATE CASCADE,"
357 : : "PRIMARY KEY (package_id, type)"
358 : : ");"
359 : : "CREATE TABLE script ("
360 : : "script_id INTEGER PRIMARY KEY,"
361 : : "script TEXT NOT NULL UNIQUE"
362 : : ");"
363 : : "CREATE TABLE option ("
364 : : "option_id INTEGER PRIMARY KEY,"
365 : : "option TEXT NOT NULL UNIQUE"
366 : : ");"
367 : : "CREATE TABLE option_desc ("
368 : : "option_desc_id INTEGER PRIMARY KEY,"
369 : : "option_desc TEXT NOT NULL UNIQUE"
370 : : ");"
371 : : "CREATE TABLE pkg_option ("
372 : : "package_id INTEGER NOT NULL REFERENCES packages(id) "
373 : : "ON DELETE CASCADE ON UPDATE CASCADE,"
374 : : "option_id INTEGER NOT NULL REFERENCES option(option_id) "
375 : : "ON DELETE RESTRICT ON UPDATE CASCADE,"
376 : : "value TEXT NOT NULL,"
377 : : "PRIMARY KEY(package_id, option_id)"
378 : : ");"
379 : : "CREATE TABLE pkg_option_desc ("
380 : : "package_id INTEGER NOT NULL REFERENCES packages(id) "
381 : : "ON DELETE CASCADE ON UPDATE CASCADE,"
382 : : "option_id INTEGER NOT NULL REFERENCES option(option_id) "
383 : : "ON DELETE RESTRICT ON UPDATE CASCADE,"
384 : : "option_desc_id INTEGER NOT NULL "
385 : : "REFERENCES option_desc(option_desc_id) "
386 : : "ON DELETE RESTRICT ON UPDATE CASCADE,"
387 : : "PRIMARY KEY(package_id, option_id)"
388 : : ");"
389 : : "CREATE TABLE pkg_option_default ("
390 : : "package_id INTEGER NOT NULL REFERENCES packages(id) "
391 : : "ON DELETE CASCADE ON UPDATE CASCADE,"
392 : : "option_id INTEGER NOT NULL REFERENCES option(option_id) "
393 : : "ON DELETE RESTRICT ON UPDATE CASCADE,"
394 : : "default_value TEXT NOT NULL,"
395 : : "PRIMARY KEY(package_id, option_id)"
396 : : ");"
397 : : "CREATE TABLE deps ("
398 : : "origin TEXT NOT NULL,"
399 : : "name TEXT NOT NULL,"
400 : : "version TEXT NOT NULL,"
401 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
402 : : " ON UPDATE CASCADE"
403 : : ");"
404 : : "CREATE UNIQUE INDEX deps_unique ON deps(name, version, package_id);"
405 : : "CREATE TABLE files ("
406 : : "path TEXT PRIMARY KEY,"
407 : : "sha256 TEXT,"
408 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
409 : : " ON UPDATE CASCADE"
410 : : ");"
411 : : "CREATE TABLE directories ("
412 : : "id INTEGER PRIMARY KEY,"
413 : : "path TEXT NOT NULL UNIQUE"
414 : : ");"
415 : : "CREATE TABLE pkg_directories ("
416 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
417 : : " ON UPDATE CASCADE,"
418 : : "directory_id INTEGER REFERENCES directories(id) ON DELETE RESTRICT"
419 : : " ON UPDATE RESTRICT,"
420 : : "try INTEGER,"
421 : : "PRIMARY KEY (package_id, directory_id)"
422 : : ");"
423 : : "CREATE TABLE categories ("
424 : : "id INTEGER PRIMARY KEY,"
425 : : "name TEXT NOT NULL UNIQUE"
426 : : ");"
427 : : "CREATE TABLE pkg_categories ("
428 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
429 : : " ON UPDATE CASCADE,"
430 : : "category_id INTEGER REFERENCES categories(id) ON DELETE RESTRICT"
431 : : " ON UPDATE RESTRICT,"
432 : : "PRIMARY KEY (package_id, category_id)"
433 : : ");"
434 : : "CREATE TABLE licenses ("
435 : : "id INTEGER PRIMARY KEY,"
436 : : "name TEXT NOT NULL UNIQUE"
437 : : ");"
438 : : "CREATE TABLE pkg_licenses ("
439 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
440 : : " ON UPDATE CASCADE,"
441 : : "license_id INTEGER REFERENCES licenses(id) ON DELETE RESTRICT"
442 : : " ON UPDATE RESTRICT,"
443 : : "PRIMARY KEY (package_id, license_id)"
444 : : ");"
445 : : "CREATE TABLE users ("
446 : : "id INTEGER PRIMARY KEY,"
447 : : "name TEXT NOT NULL UNIQUE"
448 : : ");"
449 : : "CREATE TABLE pkg_users ("
450 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
451 : : " ON UPDATE CASCADE,"
452 : : "user_id INTEGER REFERENCES users(id) ON DELETE RESTRICT"
453 : : " ON UPDATE RESTRICT,"
454 : : "UNIQUE(package_id, user_id)"
455 : : ");"
456 : : "CREATE TABLE groups ("
457 : : "id INTEGER PRIMARY KEY,"
458 : : "name TEXT NOT NULL UNIQUE"
459 : : ");"
460 : : "CREATE TABLE pkg_groups ("
461 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
462 : : " ON UPDATE CASCADE,"
463 : : "group_id INTEGER REFERENCES groups(id) ON DELETE RESTRICT"
464 : : " ON UPDATE RESTRICT,"
465 : : "UNIQUE(package_id, group_id)"
466 : : ");"
467 : : "CREATE TABLE shlibs ("
468 : : "id INTEGER PRIMARY KEY,"
469 : : "name TEXT NOT NULL UNIQUE"
470 : : ");"
471 : : "CREATE TABLE pkg_shlibs_required ("
472 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
473 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
474 : : "shlib_id INTEGER NOT NULL REFERENCES shlibs(id)"
475 : : " ON DELETE RESTRICT ON UPDATE RESTRICT,"
476 : : "UNIQUE (package_id, shlib_id)"
477 : : ");"
478 : : "CREATE TABLE pkg_shlibs_provided ("
479 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
480 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
481 : : "shlib_id INTEGER NOT NULL REFERENCES shlibs(id)"
482 : : " ON DELETE RESTRICT ON UPDATE RESTRICT,"
483 : : "UNIQUE (package_id, shlib_id)"
484 : : ");"
485 : : "CREATE TABLE annotation ("
486 : : "annotation_id INTEGER PRIMARY KEY,"
487 : : "annotation TEXT NOT NULL UNIQUE"
488 : : ");"
489 : : "CREATE TABLE pkg_annotation ("
490 : : "package_id INTEGER REFERENCES packages(id)"
491 : : " ON DELETE CASCADE ON UPDATE RESTRICT,"
492 : : "tag_id INTEGER NOT NULL REFERENCES annotation(annotation_id)"
493 : : " ON DELETE CASCADE ON UPDATE RESTRICT,"
494 : : "value_id INTEGER NOT NULL REFERENCES annotation(annotation_id)"
495 : : " ON DELETE CASCADE ON UPDATE RESTRICT,"
496 : : "UNIQUE (package_id, tag_id)"
497 : : ");"
498 : : "CREATE TABLE pkg_conflicts ("
499 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
500 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
501 : : "conflict_id INTEGER NOT NULL,"
502 : : "UNIQUE(package_id, conflict_id)"
503 : : ");"
504 : : "CREATE TABLE pkg_lock ("
505 : : "exclusive INTEGER(1),"
506 : : "advisory INTEGER(1),"
507 : : "read INTEGER(8)"
508 : : ");"
509 : : "CREATE TABLE pkg_lock_pid ("
510 : : "pid INTEGER PRIMARY KEY"
511 : : ");"
512 : : "INSERT INTO pkg_lock VALUES(0,0,0);"
513 : : "CREATE TABLE provides("
514 : : " id INTEGER PRIMARY KEY,"
515 : : " provide TEXT NOT NULL"
516 : : ");"
517 : : "CREATE TABLE pkg_provides ("
518 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
519 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
520 : : "provide_id INTEGER NOT NULL REFERENCES provides(id)"
521 : : " ON DELETE RESTRICT ON UPDATE RESTRICT,"
522 : : "UNIQUE(package_id, provide_id)"
523 : : ");"
524 : : "CREATE TABLE config_files ("
525 : : "path TEXT NOT NULL UNIQUE, "
526 : : "content TEXT, "
527 : : "package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
528 : : " ON UPDATE CASCADE"
529 : : ");"
530 : :
531 : : /* Mark the end of the array */
532 : :
533 : : "CREATE INDEX deporigini on deps(origin);"
534 : : "CREATE INDEX pkg_script_package_id ON pkg_script(package_id);"
535 : : "CREATE INDEX deps_package_id ON deps (package_id);"
536 : : "CREATE INDEX files_package_id ON files (package_id);"
537 : : "CREATE INDEX pkg_directories_package_id ON pkg_directories (package_id);"
538 : : "CREATE INDEX pkg_categories_package_id ON pkg_categories (package_id);"
539 : : "CREATE INDEX pkg_licenses_package_id ON pkg_licenses (package_id);"
540 : : "CREATE INDEX pkg_users_package_id ON pkg_users (package_id);"
541 : : "CREATE INDEX pkg_groups_package_id ON pkg_groups (package_id);"
542 : : "CREATE INDEX pkg_shlibs_required_package_id ON pkg_shlibs_required (package_id);"
543 : : "CREATE INDEX pkg_shlibs_provided_package_id ON pkg_shlibs_provided (package_id);"
544 : : "CREATE INDEX pkg_directories_directory_id ON pkg_directories (directory_id);"
545 : : "CREATE INDEX pkg_annotation_package_id ON pkg_annotation(package_id);"
546 : : "CREATE INDEX pkg_digest_id ON packages(origin, manifestdigest);"
547 : : "CREATE INDEX pkg_conflicts_pid ON pkg_conflicts(package_id);"
548 : : "CREATE INDEX pkg_conflicts_cid ON pkg_conflicts(conflict_id);"
549 : : "CREATE INDEX pkg_provides_id ON pkg_provides(package_id);"
550 : : "CREATE INDEX packages_origin ON packages(origin COLLATE NOCASE);"
551 : : "CREATE INDEX packages_name ON packages(name COLLATE NOCASE);"
552 : : "CREATE TABLE requires("
553 : : " id INTEGER PRIMARY KEY,"
554 : : " require TEXT NOT NULL"
555 : : ");"
556 : : "CREATE TABLE pkg_requires ("
557 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
558 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
559 : : "require_id INTEGER NOT NULL REFERENCES requires(id)"
560 : : " ON DELETE RESTRICT ON UPDATE RESTRICT,"
561 : : "UNIQUE(package_id, require_id)"
562 : : ");"
563 : : "CREATE TABLE lua_script("
564 : : " lua_script_id INTEGER PRIMARY KEY,"
565 : : " lua_script TEXT NOT NULL UNIQUE"
566 : : ");"
567 : : "CREATE TABLE pkg_lua_script ("
568 : : "package_id INTEGER NOT NULL REFERENCES packages(id)"
569 : : " ON DELETE CASCADE ON UPDATE CASCADE,"
570 : : "lua_script_id INTEGER NOT NULL REFERENCES lua_script(lua_script_id)"
571 : : " ON DELETE RESTRICT ON UPDATE RESTRICT,"
572 : : "type INTEGER,"
573 : : "UNIQUE(package_id, lua_script_id)"
574 : : ");"
575 : : "PRAGMA user_version = %d;"
576 : : "COMMIT;"
577 : : ;
578 : :
579 : 144 : return (sql_exec(sdb, sql, DBVERSION));
580 : : }
581 : :
582 : : static int
583 : 1149 : pkgdb_is_insecure_mode(int dbdirfd, const char *path, bool install_as_user)
584 : : {
585 : : uid_t fileowner;
586 : : gid_t filegroup;
587 : 1149 : bool bad_perms = false;
588 : 1149 : bool wrong_owner = false;
589 : : struct stat sb;
590 : :
591 [ + + ]: 1149 : if (dbdirfd == -1)
592 : 8 : return (EPKG_ENODB);
593 : :
594 [ + - ]: 1141 : if (install_as_user) {
595 : 1141 : fileowner = geteuid();
596 : 1141 : filegroup = getegid();
597 : 1141 : } else {
598 : 0 : fileowner = 0;
599 : 0 : filegroup = 0;
600 : : }
601 : :
602 [ + + ]: 1141 : if (fstatat(dbdirfd, path, &sb, 0) != 0) {
603 [ - + ]: 282 : if (errno == EACCES)
604 : 0 : return (EPKG_ENOACCESS);
605 [ + - ]: 282 : else if (errno == ENOENT)
606 : 282 : return (EPKG_ENODB);
607 : : else
608 : 0 : return (EPKG_FATAL);
609 : : }
610 : :
611 : : /* if fileowner == 0, root ownership and no group or other
612 : : read access. if fileowner != 0, require no other read
613 : : access and group read access IFF the group ownership ==
614 : : filegroup */
615 : :
616 [ + - ]: 859 : if ( fileowner == 0 ) {
617 [ # # ]: 0 : if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0)
618 : 0 : bad_perms = true;
619 [ # # ]: 0 : if (sb.st_uid != fileowner)
620 : 0 : wrong_owner = true;
621 : 0 : } else {
622 [ + - ]: 859 : if ((sb.st_mode & S_IWOTH) != 0)
623 : 0 : bad_perms = true;
624 [ + - + - ]: 859 : if (sb.st_gid != filegroup && (sb.st_mode & S_IWGRP) != 0)
625 : 0 : bad_perms = true;
626 [ + - + - : 859 : if (sb.st_uid != 0 && sb.st_uid != fileowner && sb.st_gid != filegroup)
# # ]
627 : 0 : wrong_owner = true;
628 : : }
629 : :
630 [ - + ]: 859 : if (bad_perms) {
631 : 0 : pkg_emit_error("%s permissions (%#o) too lax", path,
632 : 0 : (sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)));
633 : 0 : return (EPKG_INSECURE);
634 : : }
635 [ - + ]: 859 : if (wrong_owner) {
636 : 0 : pkg_emit_error("%s wrong user or group ownership"
637 : : " (expected %d/%d versus actual %d/%d)",
638 : 0 : path, fileowner, filegroup, sb.st_uid, sb.st_gid);
639 : 0 : return (EPKG_INSECURE);
640 : : }
641 : :
642 : 859 : return (EPKG_OK);
643 : 1149 : }
644 : :
645 : : int
646 : 1149 : pkgdb_check_access(unsigned mode, const char *dbname)
647 : : {
648 : 1149 : const char *dbpath = ".";
649 : : int retval;
650 : : bool database_exists;
651 : : bool install_as_user;
652 : 1149 : int dbdirfd = pkg_get_dbdirfd();
653 : :
654 [ + + ]: 1149 : if (dbname != NULL)
655 : 618 : dbpath = dbname;
656 : :
657 : 1149 : install_as_user = (getenv("INSTALL_AS_USER") != NULL);
658 : :
659 : 1149 : retval = pkgdb_is_insecure_mode(dbdirfd, dbpath, install_as_user);
660 : :
661 : 1149 : database_exists = (retval != EPKG_ENODB);
662 : :
663 [ + + + - ]: 1149 : if (database_exists && retval != EPKG_OK)
664 : 0 : return (retval);
665 : :
666 [ + + + + ]: 1149 : if (!database_exists && (mode & PKGDB_MODE_CREATE) != 0)
667 : 279 : return (EPKG_OK);
668 : :
669 : 870 : retval = -1;
670 [ - - + + : 870 : switch(mode & (PKGDB_MODE_READ|PKGDB_MODE_WRITE)) {
+ ]
671 : : case 0: /* Existence test */
672 [ # # ]: 0 : if (dbdirfd == -1)
673 : 0 : goto out;
674 : 0 : retval = faccessat(dbdirfd, dbpath, F_OK, AT_EACCESS);
675 : 0 : break;
676 : : case PKGDB_MODE_READ:
677 [ + - ]: 240 : if (dbdirfd == -1)
678 : 0 : goto out;
679 : 240 : retval = faccessat(dbdirfd, dbpath, R_OK, AT_EACCESS);
680 : 240 : break;
681 : : case PKGDB_MODE_WRITE:
682 [ + - ]: 5 : if (dbdirfd == -1) {
683 : 0 : pkg_mkdirs(ctx.dbdir);
684 : 0 : dbdirfd = pkg_get_dbdirfd();
685 [ # # ]: 0 : if (dbdirfd == -1)
686 : 0 : goto out;
687 : 0 : }
688 : 5 : retval = faccessat(dbdirfd, dbpath, W_OK, AT_EACCESS);
689 : 5 : break;
690 : : case PKGDB_MODE_READ|PKGDB_MODE_WRITE:
691 [ + + ]: 625 : if (dbdirfd == -1) {
692 : 8 : pkg_mkdirs(ctx.dbdir);
693 : 8 : dbdirfd = pkg_get_dbdirfd();
694 [ + - ]: 8 : if (dbdirfd == -1)
695 : 0 : goto out;
696 : 8 : }
697 : 625 : retval = faccessat(dbdirfd, dbpath, R_OK|W_OK, AT_EACCESS);
698 : 625 : break;
699 : 870 : }
700 : :
701 : : out:
702 [ + + ]: 870 : if (retval != 0) {
703 [ + - ]: 3 : if (errno == ENOENT)
704 : 3 : return (EPKG_ENODB);
705 [ # # # # ]: 0 : else if (errno == EACCES || errno == EROFS)
706 : 0 : return (EPKG_ENOACCESS);
707 : : else
708 : 0 : return (EPKG_FATAL);
709 : : }
710 : :
711 : 867 : return (EPKG_OK);
712 : 1149 : }
713 : :
714 : : int
715 : 216 : pkgdb_access(unsigned mode, unsigned database)
716 : : {
717 : :
718 : 216 : return (pkgdb_access2(mode, database, NULL));
719 : : }
720 : :
721 : : int
722 : 531 : pkgdb_access2(unsigned mode, unsigned database, c_charv_t *dbs)
723 : : {
724 : 531 : int retval = EPKG_OK;
725 : :
726 : : /*
727 : : * This will return one of:
728 : : *
729 : : * EPKG_ENODB: a database doesn't exist and we don't want to create
730 : : * it, or dbdir doesn't exist
731 : : *
732 : : * EPKG_INSECURE: the dbfile or one of the directories in the
733 : : * path to it are writable by other than root or
734 : : * (if $INSTALL_AS_USER is set) the current euid
735 : : * and egid
736 : : *
737 : : * EPKG_ENOACCESS: we don't have privileges to read or write
738 : : *
739 : : * EPKG_FATAL: Couldn't determine the answer for other reason,
740 : : * like configuration screwed up, invalid argument values,
741 : : * read-only filesystem, etc.
742 : : *
743 : : * EPKG_OK: We can go ahead
744 : : */
745 : :
746 : :
747 [ - + - + ]: 1062 : if ((mode & ~(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE))
748 : 531 : != 0)
749 : 0 : return (EPKG_FATAL); /* EINVAL */
750 : :
751 [ - + ]: 531 : if ((database & ~(PKGDB_DB_LOCAL|PKGDB_DB_REPO)) != 0)
752 : 0 : return (EPKG_FATAL); /* EINVAL */
753 : :
754 : : /* Test the enclosing directory: if we're going to create the
755 : : DB, then we need read and write permissions on the dir.
756 : : Otherwise, just test for read access */
757 : :
758 [ + + ]: 531 : if ((mode & PKGDB_MODE_CREATE) != 0) {
759 : 384 : retval = pkgdb_check_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
760 : : NULL);
761 : 384 : } else
762 : 147 : retval = pkgdb_check_access(PKGDB_MODE_READ, NULL);
763 [ - + ]: 531 : if (retval != EPKG_OK)
764 : 0 : return (retval);
765 : :
766 : : /* Test local.sqlite, if required */
767 : :
768 [ + + ]: 531 : if ((database & PKGDB_DB_LOCAL) != 0) {
769 : 344 : retval = pkgdb_check_access(mode, "local.sqlite");
770 [ + + ]: 344 : if (retval != EPKG_OK)
771 : 2 : return (retval);
772 : 342 : }
773 : :
774 [ + + ]: 529 : if ((database & PKGDB_DB_REPO) != 0) {
775 : 316 : struct pkg_repo *r = NULL;
776 : :
777 [ + + ]: 591 : while (pkg_repos(&r) == EPKG_OK) {
778 : : /* Ignore any repos marked as inactive */
779 [ + - ]: 276 : if (!pkg_repo_enabled(r))
780 : 0 : continue;
781 : :
782 [ + + + + : 276 : if (dbs != NULL && dbs->len > 0 && r->name &&
- + + + ]
783 : 13 : !c_charv_contains(dbs, r->name, true)) {
784 : : /* Skip what is not needed */
785 : 2 : continue;
786 : : }
787 : :
788 : 274 : retval = r->ops->access(r, mode);
789 [ + + ]: 274 : if (retval != EPKG_OK) {
790 [ + - + - ]: 1 : if (retval == EPKG_ENODB &&
791 : 1 : (mode & PKGDB_MODE_READ) != PKGDB_MODE_READ) {
792 : 0 : pkg_emit_error("Repository %s missing."
793 : : " 'pkg update' required",
794 : 0 : r->name);
795 : 0 : }
796 : :
797 : 1 : return (retval);
798 : : }
799 : : }
800 : 315 : }
801 : 528 : return (retval);
802 : 531 : }
803 : :
804 : : static int
805 : 0 : pkgdb_profile_callback(unsigned type __unused, void *ud __unused,
806 : : void *stmt, void *X)
807 : : {
808 : 0 : sqlite3_uint64 nsec = *((sqlite3_uint64*)X);
809 : 0 : const char *req = sqlite3_sql((sqlite3_stmt *)stmt);
810 : : /* According to sqlite3 documentation, nsec has milliseconds accuracy */
811 : 0 : nsec /= 1000000LLU;
812 [ # # ]: 0 : if (nsec > 0)
813 : 0 : dbg(1, "Sqlite request %s was executed in %lu milliseconds",
814 : : req, (unsigned long)nsec);
815 : 0 : return (0);
816 : : }
817 : :
818 : : int
819 : 225 : pkgdb_open(struct pkgdb **db_p, pkgdb_t type)
820 : : {
821 : 225 : return (pkgdb_open_all(db_p, type, NULL));
822 : : }
823 : :
824 : : static int
825 : 94 : pkgdb_open_repos(struct pkgdb *db, const char *reponame)
826 : : {
827 : 94 : struct pkg_repo *r = NULL;
828 : :
829 [ + + ]: 94 : if (reponame != NULL) {
830 : 6 : printf("opening reponame: %s\n", reponame);
831 : 6 : }
832 [ + + ]: 200 : while (pkg_repos(&r) == EPKG_OK) {
833 [ - + # # ]: 106 : if (!r->enable && reponame == NULL) {
834 : 0 : continue;
835 : : }
836 : :
837 [ + + + + ]: 106 : if (reponame == NULL || STRIEQ(r->name, reponame)) {
838 : : /* We need read only access here */
839 [ - + ]: 105 : if (r->ops->open(r, R_OK) == EPKG_OK) {
840 : 105 : r->ops->init(r);
841 [ + + + + : 105 : tll_push_front(db->repos, r);
+ - - + +
+ ]
842 : 105 : } else
843 : 0 : pkg_emit_error("Repository %s cannot be opened."
844 : 0 : " 'pkg update' required", r->name);
845 : 105 : }
846 : : }
847 : :
848 : 94 : return (EPKG_OK);
849 : : }
850 : :
851 : : static const char*
852 : 38568 : _dbdir_trim_path(const char*path)
853 : : {
854 : : static size_t l = 0;
855 : : const char *p;
856 : :
857 [ + + ]: 38568 : if (l == 0)
858 : 407 : l = strlen(ctx.dbdir);
859 : :
860 [ - + ]: 38568 : if (strncmp(ctx.dbdir, path, l) == 0) {
861 : 0 : p = path + l;
862 [ # # ]: 0 : while (*p == '/')
863 : 0 : p++;
864 : 0 : return (p);
865 : : }
866 [ + - ]: 38568 : if (*path == '/')
867 : 38568 : return (path + 1);
868 : 0 : return (path);
869 : 38568 : }
870 : :
871 : : static int
872 : 8786 : _dbdir_open(const char *path, int flags, int mode)
873 : : {
874 : 8786 : int dfd = pkg_get_dbdirfd();
875 : :
876 : 8786 : return (openat(dfd, _dbdir_trim_path(path), flags, mode));
877 : : }
878 : :
879 : : static int
880 : 0 : _dbdir_access(const char *path, int mode)
881 : : {
882 : 0 : int dfd = pkg_get_dbdirfd();
883 : :
884 : 0 : return (faccessat(dfd, _dbdir_trim_path(path), mode, 0));
885 : : }
886 : :
887 : : static int
888 : 25740 : _dbdir_stat(const char * path, struct stat * sb)
889 : : {
890 : 25740 : int dfd = pkg_get_dbdirfd();
891 : :
892 : 25740 : return (fstatat(dfd, _dbdir_trim_path(path), sb, 0));
893 : : }
894 : :
895 : : static int
896 : 1307 : _dbdir_lstat(const char * path, struct stat * sb)
897 : : {
898 : 1307 : int dfd = pkg_get_dbdirfd();
899 : :
900 : 1307 : return (fstatat(dfd, _dbdir_trim_path(path), sb, AT_SYMLINK_NOFOLLOW));
901 : : }
902 : :
903 : : static int
904 : 2735 : _dbdir_unlink(const char *path)
905 : : {
906 : 2735 : int dfd = pkg_get_dbdirfd();
907 : :
908 : 2735 : return (unlinkat(dfd, _dbdir_trim_path(path), 0));
909 : : }
910 : :
911 : : static int
912 : 0 : _dbdir_mkdir(const char *path, mode_t mode)
913 : : {
914 : 0 : int dfd = pkg_get_dbdirfd();
915 : :
916 : 0 : return (mkdirat(dfd, _dbdir_trim_path(path), mode));
917 : : }
918 : :
919 : : static char *
920 : 309 : _dbdir_getcwd(char *path, size_t sz)
921 : : {
922 [ - + ]: 309 : if (0 == sz) {
923 : 0 : errno = EINVAL;
924 [ + - ]: 309 : } else if (sz >= 2) {
925 : 309 : path[0] = '/';
926 : 309 : path[1] = '\0';
927 : 309 : return path;
928 : : } else {
929 : 0 : errno = ERANGE;
930 : : }
931 : 0 : return 0;
932 : 309 : }
933 : :
934 : : void
935 : 763 : pkgdb_syscall_overload(void)
936 : : {
937 : : sqlite3_vfs *vfs;
938 : :
939 : 763 : vfs = sqlite3_vfs_find(NULL);
940 : 763 : vfs->xSetSystemCall(vfs, "open", (sqlite3_syscall_ptr)_dbdir_open);
941 : 763 : vfs->xSetSystemCall(vfs, "access", (sqlite3_syscall_ptr)_dbdir_access);
942 : 763 : vfs->xSetSystemCall(vfs, "stat", (sqlite3_syscall_ptr)_dbdir_stat);
943 : 763 : vfs->xSetSystemCall(vfs, "lstat", (sqlite3_syscall_ptr)_dbdir_lstat);
944 : 763 : vfs->xSetSystemCall(vfs, "unlink", (sqlite3_syscall_ptr)_dbdir_unlink);
945 : 763 : vfs->xSetSystemCall(vfs, "mkdir", (sqlite3_syscall_ptr)_dbdir_mkdir);
946 : 763 : vfs->xSetSystemCall(vfs, "getcwd", (sqlite3_syscall_ptr)_dbdir_getcwd);
947 : 763 : }
948 : :
949 : : void
950 : 0 : pkgdb_nfs_corruption(sqlite3 *db)
951 : : {
952 : :
953 [ # # ]: 0 : if (sqlite3_errcode(db) != SQLITE_CORRUPT)
954 : 0 : return;
955 : :
956 : : /*
957 : : * Fall back on unix-dotfile locking strategy if on a network filesystem
958 : : */
959 : :
960 : : #if defined(HAVE_SYS_STATVFS_H) && defined(ST_LOCAL)
961 : : int dbdirfd = pkg_get_dbdirfd();
962 : : struct statvfs stfs;
963 : :
964 : : if (fstatvfs(dbdirfd, &stfs) == 0) {
965 : : if ((stfs.f_flag & ST_LOCAL) != ST_LOCAL)
966 : : pkg_emit_error("You are running on a remote filesystem,"
967 : : " please make sure, the locking mechanism is "
968 : : " properly setup\n");
969 : : }
970 : : #elif defined(HAVE_FSTATFS) && defined(MNT_LOCAL)
971 : 0 : int dbdirfd = pkg_get_dbdirfd();
972 : : struct statfs stfs;
973 : :
974 [ # # ]: 0 : if (fstatfs(dbdirfd, &stfs) == 0) {
975 [ # # ]: 0 : if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL)
976 : 0 : pkg_emit_error("You are running on a remote filesystem,"
977 : : " please make sure, the locking mechanism is "
978 : : " properly setup\n");
979 : 0 : }
980 : : #endif
981 : :
982 : 0 : }
983 : :
984 : : int
985 : 225 : pkgdb_open_all(struct pkgdb **db_p, pkgdb_t type, const char *reponame)
986 : : {
987 : : c_charv_t r;
988 : : int ret;
989 : :
990 : 225 : pkgvec_init(&r);
991 [ + - ]: 225 : if (reponame != NULL)
992 [ # # # # : 0 : pkgvec_push(&r, reponame);
# # ]
993 : :
994 : 225 : ret = pkgdb_open_all2(db_p, type, &r);
995 : 225 : pkgvec_free(&r);
996 : 225 : return (ret);
997 : : }
998 : : int
999 : 380 : pkgdb_open_all2(struct pkgdb **db_p, pkgdb_t type, c_charv_t *reponames)
1000 : : {
1001 : 380 : struct pkgdb *db = NULL;
1002 : 380 : bool reopen = false;
1003 : 380 : bool profile = false;
1004 : 380 : bool create = false;
1005 : : int ret;
1006 : : int dbdirfd;
1007 : :
1008 [ + - ]: 380 : if (*db_p != NULL) {
1009 : 0 : reopen = true;
1010 : 0 : db = *db_p;
1011 : 0 : }
1012 : :
1013 [ - + ]: 380 : if (!reopen)
1014 : 380 : db = xcalloc(1, sizeof(struct pkgdb));
1015 : 380 : db->prstmt_initialized = false;
1016 : :
1017 [ - + ]: 380 : if (!reopen) {
1018 : : retry:
1019 : 380 : dbdirfd = pkg_get_dbdirfd();
1020 [ + - ]: 380 : if (dbdirfd == -1) {
1021 [ # # ]: 0 : if (errno == ENOENT) {
1022 [ # # ]: 0 : if (pkg_mkdirs(ctx.dbdir) != EPKG_OK) {
1023 : 0 : pkgdb_close(db);
1024 : 0 : return (EPKG_FATAL);
1025 : : }
1026 : 0 : goto retry;
1027 : : }
1028 : 0 : }
1029 [ + + ]: 380 : if (faccessat(dbdirfd, "local.sqlite", R_OK, AT_EACCESS) != 0) {
1030 [ - + ]: 144 : if (errno != ENOENT) {
1031 : 0 : pkg_emit_nolocaldb();
1032 : 0 : pkgdb_close(db);
1033 : 0 : return (EPKG_ENODB);
1034 [ + - ]: 144 : } else if ((faccessat(dbdirfd, ".", W_OK, AT_EACCESS) != 0)) {
1035 : : /*
1036 : : * If we need to create the db but cannot
1037 : : * write to it, fail early
1038 : : */
1039 : 0 : pkg_emit_nolocaldb();
1040 : 0 : pkgdb_close(db);
1041 : 0 : return (EPKG_ENODB);
1042 : : } else {
1043 : 144 : create = true;
1044 : : }
1045 : 144 : }
1046 : :
1047 : 380 : sqlite3_initialize();
1048 : :
1049 : 380 : pkgdb_syscall_overload();
1050 : :
1051 [ - + ]: 380 : if (sqlite3_open("/local.sqlite", &db->sqlite) != SQLITE_OK) {
1052 : 0 : ERROR_SQLITE(db->sqlite, "sqlite open");
1053 : 0 : pkgdb_nfs_corruption(db->sqlite);
1054 : 0 : pkgdb_close(db);
1055 : 0 : return (EPKG_FATAL);
1056 : : }
1057 : :
1058 : : /* Wait up to 5 seconds if database is busy */
1059 : 380 : sqlite3_busy_timeout(db->sqlite, 5000);
1060 : :
1061 : : /* If the database is missing we have to initialize it */
1062 [ + + + - ]: 380 : if (create && pkgdb_init(db->sqlite) != EPKG_OK) {
1063 : 0 : pkgdb_close(db);
1064 : 0 : return (EPKG_FATAL);
1065 : : }
1066 : :
1067 : : /* Create our functions */
1068 : 380 : pkgdb_sqlcmd_init(db->sqlite, NULL, NULL);
1069 : :
1070 [ - + ]: 380 : if (pkgdb_upgrade(db) != EPKG_OK) {
1071 : 0 : pkgdb_close(db);
1072 : 0 : return (EPKG_FATAL);
1073 : : }
1074 : :
1075 : : /*
1076 : : * allow foreign key option which will allow to have
1077 : : * clean support for reinstalling
1078 : : */
1079 : 380 : ret = sql_exec(db->sqlite, "PRAGMA foreign_keys = ON;");
1080 [ + - ]: 380 : if (ret != EPKG_OK) {
1081 : 0 : pkgdb_close(db);
1082 : 0 : return (EPKG_FATAL);
1083 : : }
1084 : 380 : sql_exec(db->sqlite, "PRAGMA mmap_size=268435456;");
1085 : 380 : }
1086 : :
1087 [ + + + + ]: 380 : if (type == PKGDB_REMOTE || type == PKGDB_MAYBE_REMOTE) {
1088 [ + + ]: 156 : if (pkg_repos_activated_count() > 0) {
1089 [ + - + + ]: 94 : if (reponames == NULL || reponames->len == 0) {
1090 : 88 : ret = pkgdb_open_repos(db, NULL);
1091 : 88 : } else {
1092 [ + + ]: 12 : for (size_t i = 0; i < reponames->len; i++)
1093 : 6 : ret = pkgdb_open_repos(db, reponames->d[i]);
1094 : : }
1095 [ - + ]: 94 : if (ret != EPKG_OK) {
1096 : 0 : pkgdb_close(db);
1097 : 0 : return (ret);
1098 : : }
1099 [ - + ]: 156 : } else if (type == PKGDB_REMOTE) {
1100 [ # # ]: 0 : if (*db_p == NULL)
1101 : 0 : pkgdb_close(db);
1102 : 0 : pkg_emit_error("No active remote repositories configured");
1103 : 0 : return (EPKG_FATAL);
1104 : : }
1105 : 156 : }
1106 : :
1107 [ - + ]: 380 : if (prstmt_initialize(db) != EPKG_OK) {
1108 : 0 : pkgdb_close(db);
1109 : 0 : return (EPKG_FATAL);
1110 : : }
1111 : :
1112 : :
1113 : 380 : profile = pkg_object_bool(pkg_config_get("SQLITE_PROFILE"));
1114 [ + - ]: 380 : if (profile) {
1115 : 0 : dbg(1, "pkgdb profiling is enabled");
1116 : 0 : sqlite3_trace_v2(db->sqlite, SQLITE_TRACE_PROFILE,
1117 : : pkgdb_profile_callback, NULL);
1118 : 0 : }
1119 : :
1120 : 380 : *db_p = db;
1121 : 380 : return (EPKG_OK);
1122 : 380 : }
1123 : :
1124 : : static void
1125 : 105 : pkgdb_free_repo(struct pkg_repo *repo)
1126 : : {
1127 : 105 : repo->ops->close(repo, false);
1128 : 105 : }
1129 : :
1130 : : void
1131 : 312 : pkgdb_close(struct pkgdb *db)
1132 : : {
1133 [ + + ]: 312 : if (db == NULL)
1134 : 8 : return;
1135 : :
1136 [ - + ]: 304 : if (db->prstmt_initialized)
1137 : 304 : prstmt_finalize(db);
1138 : :
1139 [ - + ]: 304 : if (db->sqlite != NULL) {
1140 : :
1141 [ + + + + : 409 : tll_free_and_free(db->repos, pkgdb_free_repo);
+ + ]
1142 : :
1143 [ - + ]: 304 : if (!sqlite3_db_readonly(db->sqlite, "main"))
1144 : 304 : pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PKGDB_CLOSE_RW, NULL, db);
1145 : :
1146 [ + - ]: 304 : if (sqlite3_close(db->sqlite) != SQLITE_OK)
1147 : 0 : pkg_emit_error("Package database is busy while closing!");
1148 : 304 : }
1149 : :
1150 : 304 : sqlite3_shutdown();
1151 : 304 : free(db);
1152 : 312 : }
1153 : :
1154 : : /* How many times to try COMMIT or ROLLBACK if the DB is busy */
1155 : : #define BUSY_RETRIES 6
1156 : : #define BUSY_SLEEP 200
1157 : :
1158 : : /* This is a MACRO instead of a function as any sqlite3_* function that
1159 : : * queries the DB can return SQLITE_BUSY. We would need a function to
1160 : : * wrap all sqlite3_* API since we cannot pass anonymous functions/blocks
1161 : : * in C. This can be used to wrap existing code. */
1162 : : #define PKGDB_SQLITE_RETRY_ON_BUSY(ret) \
1163 : : ret = SQLITE_BUSY; \
1164 : : for (int _sqlite_busy_retries = 0; \
1165 : : _sqlite_busy_retries < BUSY_RETRIES && ret == SQLITE_BUSY; \
1166 : : ++_sqlite_busy_retries, ret == SQLITE_BUSY && \
1167 : : sqlite3_sleep(BUSY_SLEEP))
1168 : :
1169 : : static int
1170 : 666 : run_transaction(sqlite3 *sqlite, const char *query, const char *savepoint)
1171 : : {
1172 : : int ret;
1173 : : sqlite3_stmt *stmt;
1174 : 666 : char *sql = NULL;
1175 : :
1176 [ + - ]: 666 : assert(sqlite != NULL);
1177 : :
1178 [ + + ]: 666 : xasprintf(&sql, "%s %s", query, savepoint != NULL ? savepoint : "");
1179 : 666 : ret = sqlite3_prepare_v2(sqlite, sql, strlen(sql) + 1, &stmt, NULL);
1180 : 666 : pkgdb_debug(4, stmt);
1181 : :
1182 [ + - ]: 666 : if (ret == SQLITE_OK) {
1183 [ + - + + : 1332 : PKGDB_SQLITE_RETRY_ON_BUSY(ret)
+ + - + #
# ]
1184 : 666 : ret = sqlite3_step(stmt);
1185 : 666 : }
1186 : :
1187 [ + - + - ]: 666 : if (ret != SQLITE_OK && ret != SQLITE_DONE) {
1188 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
1189 : 0 : }
1190 : 666 : sqlite3_finalize(stmt);
1191 : 666 : free(sql);
1192 [ + - + - ]: 666 : return (ret == SQLITE_OK || ret == SQLITE_DONE ? EPKG_OK : EPKG_FATAL);
1193 : : }
1194 : :
1195 : : int
1196 : 333 : pkgdb_transaction_begin_sqlite(sqlite3 *sqlite, const char *savepoint)
1197 : : {
1198 : :
1199 [ + + - + ]: 333 : if (savepoint == NULL || savepoint[0] == '\0') {
1200 : 259 : return (run_transaction(sqlite, "BEGIN IMMEDIATE TRANSACTION",
1201 : : NULL));
1202 : : }
1203 : 74 : return (run_transaction(sqlite, "SAVEPOINT", savepoint));
1204 : 333 : }
1205 : :
1206 : : int
1207 : 331 : pkgdb_transaction_commit_sqlite(sqlite3 *sqlite, const char *savepoint)
1208 : : {
1209 : :
1210 [ + + - + ]: 331 : if (savepoint == NULL || savepoint[0] == '\0') {
1211 : 257 : return (run_transaction(sqlite, "COMMIT TRANSACTION", NULL));
1212 : : }
1213 : 74 : return (run_transaction(sqlite, "RELEASE SAVEPOINT", savepoint));
1214 : 331 : }
1215 : :
1216 : : int
1217 : 2 : pkgdb_transaction_rollback_sqlite(sqlite3 *sqlite, const char *savepoint)
1218 : : {
1219 : :
1220 [ - + # # ]: 2 : if (savepoint == NULL || savepoint[0] == '\0') {
1221 : 2 : return (run_transaction(sqlite, "ROLLBACK TRANSACTION", NULL));
1222 : : }
1223 : 0 : return (run_transaction(sqlite, "ROLLBACK TO SAVEPOINT", savepoint));
1224 : 2 : }
1225 : :
1226 : : /*
1227 : : * Public API
1228 : : */
1229 : : int
1230 : 6 : pkgdb_transaction_begin(struct pkgdb *db, const char *savepoint)
1231 : : {
1232 : 6 : dbg(2, "new transaction");
1233 : 6 : return (pkgdb_transaction_begin_sqlite(db->sqlite, savepoint));
1234 : : }
1235 : : int
1236 : 6 : pkgdb_transaction_commit(struct pkgdb *db, const char *savepoint)
1237 : : {
1238 : 6 : dbg(2, "end transaction");
1239 : 6 : return (pkgdb_transaction_commit_sqlite(db->sqlite, savepoint));
1240 : : }
1241 : : int
1242 : 0 : pkgdb_transaction_rollback(struct pkgdb *db, const char *savepoint)
1243 : : {
1244 : 0 : dbg(2, "end transaction");
1245 : 0 : return (pkgdb_transaction_rollback_sqlite(db->sqlite, savepoint));
1246 : : }
1247 : :
1248 : :
1249 : : /* By default, MATCH_EXACT and MATCH_REGEX are case sensitive. This
1250 : : * is modified in many actions according to the value of
1251 : : * CASE_SENSITIVE_MATCH in pkg.conf and then possbily reset again in
1252 : : * pkg search et al according to command line flags */
1253 : :
1254 : : static bool _case_sensitive_flag = false;
1255 : :
1256 : : void
1257 : 15 : pkgdb_set_case_sensitivity(bool case_sensitive)
1258 : : {
1259 : 15 : _case_sensitive_flag = case_sensitive;
1260 : 15 : return;
1261 : : }
1262 : :
1263 : : bool
1264 : 160 : pkgdb_case_sensitive(void)
1265 : : {
1266 : 160 : return (_case_sensitive_flag);
1267 : : }
1268 : :
1269 : : typedef enum _sql_prstmt_index {
1270 : : MTREE = 0,
1271 : : PKG,
1272 : : DEPS_UPDATE,
1273 : : DEPS,
1274 : : FILES,
1275 : : FILES_REPLACE,
1276 : : DIRS1,
1277 : : DIRS2,
1278 : : CATEGORY1,
1279 : : CATEGORY2,
1280 : : LICENSES1,
1281 : : LICENSES2,
1282 : : USERS1,
1283 : : USERS2,
1284 : : GROUPS1,
1285 : : GROUPS2,
1286 : : SCRIPT1,
1287 : : SCRIPT2,
1288 : : OPTION1,
1289 : : OPTION2,
1290 : : SHLIBS1,
1291 : : SHLIBS_REQD,
1292 : : SHLIBS_PROV,
1293 : : ANNOTATE1,
1294 : : ANNOTATE2,
1295 : : ANNOTATE_ADD1,
1296 : : ANNOTATE_MOD1,
1297 : : ANNOTATE_DEL1,
1298 : : ANNOTATE_DEL2,
1299 : : CONFLICT,
1300 : : PKG_PROVIDE,
1301 : : PROVIDE,
1302 : : UPDATE_DIGEST,
1303 : : CONFIG_FILES,
1304 : : UPDATE_CONFIG_FILE,
1305 : : PKG_REQUIRE,
1306 : : REQUIRE,
1307 : : LUASCRIPT1,
1308 : : LUASCRIPT2,
1309 : : PRSTMT_LAST,
1310 : : } sql_prstmt_index;
1311 : :
1312 : : static sql_prstmt sql_prepared_statements[PRSTMT_LAST] = {
1313 : : [MTREE] = {
1314 : : NULL,
1315 : : NULL,
1316 : : "T",
1317 : : },
1318 : : [PKG] = {
1319 : : NULL,
1320 : : "INSERT OR REPLACE INTO packages( "
1321 : : "origin, name, version, comment, desc, message, arch, "
1322 : : "maintainer, www, prefix, flatsize, automatic, "
1323 : : "licenselogic, time, manifestdigest, dep_formula, vital)"
1324 : : "VALUES( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, "
1325 : : "?13, NOW(), ?14, ?15, ?16 )",
1326 : : "TTTTTTTTTTIIITTI",
1327 : : },
1328 : : [DEPS_UPDATE] = {
1329 : : NULL,
1330 : : "UPDATE deps SET origin=?1, version=?2 WHERE name=?3;",
1331 : : "TTT",
1332 : : },
1333 : : [DEPS] = {
1334 : : NULL,
1335 : : "INSERT INTO deps (origin, name, version, package_id) "
1336 : : "VALUES (?1, ?2, ?3, ?4)",
1337 : : "TTTI",
1338 : : },
1339 : : [FILES] = {
1340 : : NULL,
1341 : : "INSERT INTO files (path, sha256, package_id) "
1342 : : "VALUES (?1, ?2, ?3)",
1343 : : "TTI",
1344 : : },
1345 : : [FILES_REPLACE] = {
1346 : : NULL,
1347 : : "INSERT OR REPLACE INTO files (path, sha256, package_id) "
1348 : : "VALUES (?1, ?2, ?3)",
1349 : : "TTI",
1350 : : },
1351 : : [DIRS1] = {
1352 : : NULL,
1353 : : "INSERT OR IGNORE INTO directories(path) VALUES(?1)",
1354 : : "T",
1355 : : },
1356 : : [DIRS2] = {
1357 : : NULL,
1358 : : "INSERT INTO pkg_directories(package_id, directory_id, try) "
1359 : : "VALUES (?1, "
1360 : : "(SELECT id FROM directories WHERE path = ?2), ?3)",
1361 : : "ITI",
1362 : : },
1363 : : [CATEGORY1] = {
1364 : : NULL,
1365 : : "INSERT OR IGNORE INTO categories(name) VALUES(?1)",
1366 : : "T",
1367 : : },
1368 : : [CATEGORY2] = {
1369 : : NULL,
1370 : : "INSERT INTO pkg_categories(package_id, category_id) "
1371 : : "VALUES (?1, (SELECT id FROM categories WHERE name = ?2))",
1372 : : "IT",
1373 : : },
1374 : : [LICENSES1] = {
1375 : : NULL,
1376 : : "INSERT OR IGNORE INTO licenses(name) VALUES(?1)",
1377 : : "T",
1378 : : },
1379 : : [LICENSES2] = {
1380 : : NULL,
1381 : : "INSERT INTO pkg_licenses(package_id, license_id) "
1382 : : "VALUES (?1, (SELECT id FROM licenses WHERE name = ?2))",
1383 : : "IT",
1384 : : },
1385 : : [USERS1] = {
1386 : : NULL,
1387 : : "INSERT OR IGNORE INTO users(name) VALUES(?1)",
1388 : : "T",
1389 : : },
1390 : : [USERS2] = {
1391 : : NULL,
1392 : : "INSERT INTO pkg_users(package_id, user_id) "
1393 : : "VALUES (?1, (SELECT id FROM users WHERE name = ?2))",
1394 : : "IT",
1395 : : },
1396 : : [GROUPS1] = {
1397 : : NULL,
1398 : : "INSERT OR IGNORE INTO groups(name) VALUES(?1)",
1399 : : "T",
1400 : : },
1401 : : [GROUPS2] = {
1402 : : NULL,
1403 : : "INSERT INTO pkg_groups(package_id, group_id) "
1404 : : "VALUES (?1, (SELECT id FROM groups WHERE name = ?2))",
1405 : : "IT",
1406 : : },
1407 : : [SCRIPT1] = {
1408 : : NULL,
1409 : : "INSERT OR IGNORE INTO script(script) VALUES (?1)",
1410 : : "T",
1411 : : },
1412 : : [SCRIPT2] = {
1413 : : NULL,
1414 : : "INSERT INTO pkg_script(script_id, package_id, type) "
1415 : : "VALUES ((SELECT script_id FROM script WHERE script = ?1), "
1416 : : "?2, ?3)",
1417 : : "TII",
1418 : : },
1419 : : [OPTION1] = {
1420 : : NULL,
1421 : : "INSERT OR IGNORE INTO option (option) "
1422 : : "VALUES (?1)",
1423 : : "T",
1424 : : },
1425 : : [OPTION2] = {
1426 : : NULL,
1427 : : "INSERT INTO pkg_option(package_id, option_id, value) "
1428 : : "VALUES (?1, "
1429 : : "(SELECT option_id FROM option WHERE option = ?2),"
1430 : : "?3)",
1431 : : "ITT",
1432 : : },
1433 : : [SHLIBS1] = {
1434 : : NULL,
1435 : : "INSERT OR IGNORE INTO shlibs(name) VALUES(?1)",
1436 : : "T",
1437 : : },
1438 : : [SHLIBS_REQD] = {
1439 : : NULL,
1440 : : "INSERT OR IGNORE INTO pkg_shlibs_required(package_id, shlib_id) "
1441 : : "VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
1442 : : "IT",
1443 : : },
1444 : : [SHLIBS_PROV] = {
1445 : : NULL,
1446 : : "INSERT OR IGNORE INTO pkg_shlibs_provided(package_id, shlib_id) "
1447 : : "VALUES (?1, (SELECT id FROM shlibs WHERE name = ?2))",
1448 : : "IT",
1449 : : },
1450 : : [ANNOTATE1] = {
1451 : : NULL,
1452 : : "INSERT OR IGNORE INTO annotation(annotation) "
1453 : : "VALUES (?1)",
1454 : : "T",
1455 : : },
1456 : : [ANNOTATE2] = {
1457 : : NULL,
1458 : : "INSERT OR ROLLBACK INTO pkg_annotation(package_id, tag_id, value_id) "
1459 : : "VALUES (?1,"
1460 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?2),"
1461 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?3))",
1462 : : "ITT",
1463 : : },
1464 : : [ANNOTATE_ADD1] = {
1465 : : NULL,
1466 : : "INSERT OR IGNORE INTO pkg_annotation(package_id, tag_id, value_id) "
1467 : : "VALUES ("
1468 : : " (SELECT id FROM packages WHERE name = ?1 ),"
1469 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?2),"
1470 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?3))",
1471 : : "TTTT", // "TTT"???
1472 : : },
1473 : : [ANNOTATE_MOD1] = {
1474 : : NULL,
1475 : : "INSERT OR REPLACE INTO pkg_annotation(package_id, tag_id, value_id) "
1476 : : "VALUES ("
1477 : : " (SELECT id FROM packages WHERE name = ?1 ),"
1478 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?2),"
1479 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?3))",
1480 : : "TTTT", // "TTT"???
1481 : : },
1482 : : [ANNOTATE_DEL1] = {
1483 : : NULL,
1484 : : "DELETE FROM pkg_annotation WHERE "
1485 : : "package_id IN"
1486 : : " (SELECT id FROM packages WHERE name = ?1) "
1487 : : "AND tag_id IN"
1488 : : " (SELECT annotation_id FROM annotation WHERE annotation = ?2)",
1489 : : "TTT", // "TT"???
1490 : : },
1491 : : [ANNOTATE_DEL2] = {
1492 : : NULL,
1493 : : "DELETE FROM annotation WHERE"
1494 : : " annotation_id NOT IN (SELECT tag_id FROM pkg_annotation) AND"
1495 : : " annotation_id NOT IN (SELECT value_id FROM pkg_annotation)",
1496 : : "",
1497 : : },
1498 : : [CONFLICT] = {
1499 : : NULL,
1500 : : "INSERT INTO pkg_conflicts(package_id, conflict_id) "
1501 : : "VALUES (?1, (SELECT id FROM packages WHERE name = ?2))",
1502 : : "IT",
1503 : : },
1504 : : [PKG_PROVIDE] = {
1505 : : NULL,
1506 : : "INSERT INTO pkg_provides(package_id, provide_id) "
1507 : : "VALUES (?1, (SELECT id FROM provides WHERE provide = ?2))",
1508 : : "IT",
1509 : : },
1510 : : [PROVIDE] = {
1511 : : NULL,
1512 : : "INSERT OR IGNORE INTO provides(provide) VALUES(?1)",
1513 : : "T",
1514 : : },
1515 : : [UPDATE_DIGEST] = {
1516 : : NULL,
1517 : : "UPDATE packages SET manifestdigest=?1 WHERE id=?2;",
1518 : : "TI"
1519 : : },
1520 : : [CONFIG_FILES] = {
1521 : : NULL,
1522 : : "INSERT INTO config_files(path, content, package_id) "
1523 : : "VALUES (?1, ?2, ?3);",
1524 : : "TTI"
1525 : : },
1526 : : [UPDATE_CONFIG_FILE] = {
1527 : : NULL,
1528 : : "UPDATE config_files SET content=?1 WHERE path=?2;",
1529 : : "TT"
1530 : : },
1531 : : [PKG_REQUIRE] = {
1532 : : NULL,
1533 : : "INSERT INTO pkg_requires(package_id, require_id) "
1534 : : "VALUES (?1, (SELECT id FROM requires WHERE require = ?2))",
1535 : : "IT",
1536 : : },
1537 : : [REQUIRE] = {
1538 : : NULL,
1539 : : "INSERT OR IGNORE INTO requires(require) VALUES(?1)",
1540 : : "T"
1541 : : },
1542 : : [LUASCRIPT1] = {
1543 : : NULL,
1544 : : "INSERT OR IGNORE INTO lua_script(lua_script) VALUES (?1)",
1545 : : "T",
1546 : : },
1547 : : [LUASCRIPT2] = {
1548 : : NULL,
1549 : : "INSERT INTO pkg_lua_script(lua_script_id, package_id, type) "
1550 : : "VALUES ((SELECT lua_script_id FROM lua_script WHERE "
1551 : : "lua_script = ?1), ?2, ?3)",
1552 : : "TII",
1553 : : },
1554 : : /* PRSTMT_LAST */
1555 : : };
1556 : :
1557 : : static int
1558 : 380 : prstmt_initialize(struct pkgdb *db)
1559 : : {
1560 : : sql_prstmt_index i;
1561 : : sqlite3 *sqlite;
1562 : :
1563 [ + - ]: 380 : assert(db != NULL);
1564 : :
1565 [ - + ]: 380 : if (!db->prstmt_initialized) {
1566 : 380 : sqlite = db->sqlite;
1567 : :
1568 [ + + ]: 15200 : for (i = 0; i < PRSTMT_LAST; i++) {
1569 [ + + ]: 14820 : if (SQL(i) == NULL)
1570 : 380 : continue;
1571 : 14440 : STMT(i) = prepare_sql(sqlite, SQL(i));
1572 [ + - ]: 14440 : if (STMT(i) == NULL)
1573 : 0 : return (EPKG_FATAL);
1574 : 14440 : }
1575 : 380 : db->prstmt_initialized = true;
1576 : 380 : }
1577 : :
1578 : 380 : return (EPKG_OK);
1579 : 380 : }
1580 : :
1581 : : static int
1582 : 3025 : run_prstmt(sql_prstmt_index s, ...)
1583 : : {
1584 : : int retcode; /* Returns SQLITE error code */
1585 : : va_list ap;
1586 : : sqlite3_stmt *stmt;
1587 : : int i;
1588 : : const char *argtypes;
1589 : :
1590 : 3025 : stmt = STMT(s);
1591 : 3025 : argtypes = sql_prepared_statements[s].argtypes;
1592 : :
1593 : 3025 : sqlite3_reset(stmt);
1594 : :
1595 : 3025 : va_start(ap, s);
1596 : :
1597 [ + + ]: 12555 : for (i = 0; argtypes[i] != '\0'; i++)
1598 : : {
1599 [ - + + ]: 9530 : switch (argtypes[i]) {
1600 : : case 'T':
1601 [ + + ]: 7146 : sqlite3_bind_text(stmt, i + 1, va_arg(ap, const char*),
1602 : : -1, SQLITE_STATIC);
1603 : 7146 : break;
1604 : : case 'I':
1605 [ + + ]: 2384 : sqlite3_bind_int64(stmt, i + 1, va_arg(ap, int64_t));
1606 : 2384 : break;
1607 : : }
1608 : 9530 : }
1609 : :
1610 : 3025 : va_end(ap);
1611 : :
1612 : 3025 : char *debug_sql = sqlite3_expanded_sql(stmt);
1613 : 3025 : dbg(4, "running '%s'", debug_sql);
1614 : 3025 : sqlite3_free(debug_sql);
1615 : :
1616 : 3025 : retcode = sqlite3_step(stmt);
1617 : :
1618 : 3025 : return (retcode);
1619 : : }
1620 : :
1621 : : static void
1622 : 304 : prstmt_finalize(struct pkgdb *db)
1623 : : {
1624 : : sql_prstmt_index i;
1625 : :
1626 [ + + ]: 12160 : for (i = 0; i < PRSTMT_LAST; i++)
1627 : : {
1628 [ + + ]: 11856 : if (STMT(i) != NULL) {
1629 : 11552 : sqlite3_finalize(STMT(i));
1630 : 11552 : STMT(i) = NULL;
1631 : 11552 : }
1632 : 11856 : }
1633 : 304 : db->prstmt_initialized = false;
1634 : 304 : return;
1635 : : }
1636 : :
1637 : : /*
1638 : : * Register a package in the database. If successful, the caller is required to
1639 : : * call pkgdb_register_finale() in order to either commit or roll back the
1640 : : * transaction. Otherwise, the caller does not need to do any extra cleanup.
1641 : : */
1642 : : int
1643 : 246 : pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
1644 : : const char *savepoint)
1645 : : {
1646 : 246 : struct pkg *pkg2 = NULL;
1647 : 246 : struct pkg_dep *dep = NULL;
1648 : 246 : struct pkg_file *file = NULL;
1649 : 246 : struct pkg_dir *dir = NULL;
1650 : 246 : struct pkg_option *option = NULL;
1651 : 246 : struct pkg_conflict *conflict = NULL;
1652 : 246 : struct pkg_config_file *cf = NULL;
1653 : 246 : struct pkgdb_it *it = NULL;
1654 : 246 : char *msg = NULL;
1655 : :
1656 : : sqlite3 *s;
1657 : :
1658 : : int ret;
1659 : 246 : int retcode = EPKG_FATAL;
1660 : : int64_t package_id;
1661 : :
1662 : : const char *arch;
1663 : :
1664 [ + - ]: 246 : assert(db != NULL);
1665 : :
1666 [ - + ]: 246 : if (pkg_is_valid(pkg) != EPKG_OK) {
1667 : 0 : pkg_emit_error("the package is not valid");
1668 : 0 : return (EPKG_FATAL);
1669 : : }
1670 : :
1671 : 246 : s = db->sqlite;
1672 : :
1673 [ - + ]: 246 : if (pkgdb_transaction_begin_sqlite(s, savepoint) != EPKG_OK)
1674 : 0 : return (EPKG_FATAL);
1675 : :
1676 : : /* Prefer new ABI over old one */
1677 [ + - ]: 246 : arch = pkg->abi != NULL ? pkg->abi : pkg->altabi;
1678 : :
1679 : : /*
1680 : : * Insert package record
1681 : : */
1682 : 246 : msg = pkg_message_to_str(pkg);
1683 : 492 : ret = run_prstmt(PKG, pkg->origin, pkg->name, pkg->version,
1684 : 246 : pkg->comment, pkg->desc, msg, arch, pkg->maintainer,
1685 : 246 : pkg->www, pkg->prefix, pkg->flatsize, (int64_t)pkg->automatic,
1686 : 246 : (int64_t)pkg->licenselogic, pkg->digest, pkg->dep_formula, (int64_t)pkg->vital);
1687 [ - + ]: 246 : if (ret != SQLITE_DONE) {
1688 : 0 : ERROR_STMT_SQLITE(s, STMT(PKG));
1689 : 0 : goto cleanup;
1690 : : }
1691 : :
1692 : 246 : package_id = sqlite3_last_insert_rowid(s);
1693 : :
1694 : : /*
1695 : : * Update dep information on packages that depend on the inserted
1696 : : * package
1697 : : */
1698 : :
1699 [ - + - + ]: 738 : if (run_prstmt(DEPS_UPDATE, pkg->origin,
1700 [ + - ]: 246 : pkg->version ? pkg->version : "", pkg->name)
1701 : 246 : != SQLITE_DONE) {
1702 : 0 : ERROR_STMT_SQLITE(s, STMT(DEPS_UPDATE));
1703 : 0 : goto cleanup;
1704 : : }
1705 : :
1706 : : /*
1707 : : * Insert dependencies list
1708 : : */
1709 : :
1710 [ + + ]: 298 : while (pkg_deps(pkg, &dep) == EPKG_OK) {
1711 [ - + - + ]: 156 : if (run_prstmt(DEPS, dep->origin, dep->name,
1712 [ + + ]: 52 : dep->version ? dep->version : "",
1713 : 104 : package_id) != SQLITE_DONE) {
1714 : 0 : ERROR_STMT_SQLITE(s, STMT(DEPS));
1715 : 0 : goto cleanup;
1716 : : }
1717 : : }
1718 : :
1719 : : /*
1720 : : * Insert files.
1721 : : */
1722 : :
1723 [ + + ]: 561 : while (pkg_files(pkg, &file) == EPKG_OK) {
1724 : 316 : bool permissive = false;
1725 [ - + - + ]: 632 : if (match_ucl_lists(file->path,
1726 : 316 : pkg_config_get("FILES_IGNORE_GLOB"),
1727 : 316 : pkg_config_get("FILES_IGNORE_REGEX"))) {
1728 : 0 : continue;
1729 : : printf("matched\n");
1730 : : }
1731 : :
1732 : 316 : ret = run_prstmt(FILES, file->path, file->sum, package_id);
1733 [ + + ]: 316 : if (ret == SQLITE_DONE)
1734 : 315 : continue;
1735 [ + - ]: 1 : if (ret != SQLITE_CONSTRAINT) {
1736 : 0 : ERROR_STMT_SQLITE(s, STMT(FILES));
1737 : 0 : goto cleanup;
1738 : : }
1739 : 1 : it = pkgdb_query_which(db, file->path, false);
1740 [ + - ]: 1 : if (it == NULL) {
1741 : 0 : ERROR_SQLITE(s, "pkg which");
1742 : 0 : goto cleanup;
1743 : : }
1744 : 1 : pkg2 = NULL;
1745 : 1 : ret = pkgdb_it_next(it, &pkg2, PKG_LOAD_BASIC);
1746 [ - + ]: 1 : if (ret == EPKG_END) {
1747 : : /* Stray entry in the files table not related to
1748 : : any known package: overwrite this */
1749 : 0 : ret = run_prstmt(FILES_REPLACE, file->path, file->sum,
1750 : 0 : package_id);
1751 : 0 : pkgdb_it_free(it);
1752 [ # # ]: 0 : if (ret == SQLITE_DONE)
1753 : 0 : continue;
1754 : : else {
1755 : 0 : ERROR_STMT_SQLITE(s, STMT(FILES_REPLACE));
1756 : 0 : goto cleanup;
1757 : : }
1758 : : }
1759 [ - + # # ]: 1 : if (ret != EPKG_OK && ret != EPKG_END) {
1760 : 0 : pkgdb_it_free(it);
1761 : 0 : ERROR_STMT_SQLITE(s, STMT(FILES_REPLACE));
1762 : 0 : goto cleanup;
1763 : : }
1764 [ - + ]: 1 : if (!forced) {
1765 [ - + ]: 1 : if (!ctx.developer_mode)
1766 : 1 : permissive = pkg_object_bool(pkg_config_get("PERMISSIVE"));
1767 : 1 : pkg_emit_error("%s-%s conflicts with %s-%s"
1768 : : " (installs files into the same place). "
1769 : : " Problematic file: %s%s",
1770 : 1 : pkg->name, pkg->version, pkg2->name, pkg2->version, file->path,
1771 : 1 : permissive ? " ignored by permissive mode" : "");
1772 : 1 : pkg_free(pkg2);
1773 [ - + ]: 1 : if (!permissive) {
1774 : 1 : pkgdb_it_free(it);
1775 : 1 : goto cleanup;
1776 : : }
1777 : 0 : } else {
1778 : 0 : pkg_emit_error("%s-%s conflicts with %s-%s"
1779 : : " (installs files into the same place). "
1780 : : " Problematic file: %s ignored by forced mode",
1781 : 0 : pkg->name, pkg->version, pkg2->name, pkg2->version, file->path);
1782 : 0 : pkg_free(pkg2);
1783 : : }
1784 : 0 : pkgdb_it_free(it);
1785 : : }
1786 : :
1787 : : /*
1788 : : * Insert config files
1789 : : */
1790 [ + + ]: 256 : while (pkg_config_files(pkg, &cf) == EPKG_OK) {
1791 [ + - + - ]: 22 : if ((ret = run_prstmt(CONFIG_FILES, cf->path, cf->content, package_id)
1792 : 11 : != SQLITE_DONE)) {
1793 [ # # ]: 0 : if (ret == SQLITE_CONSTRAINT) {
1794 : 0 : pkg_emit_error("Another package already owns :%s",
1795 : 0 : cf->path);
1796 : 0 : } else
1797 : 0 : ERROR_STMT_SQLITE(s, STMT(CONFIG_FILES));
1798 : 0 : goto cleanup;
1799 : : }
1800 : : }
1801 : :
1802 : : /*
1803 : : * Insert dirs.
1804 : : */
1805 : :
1806 [ + + ]: 268 : while (pkg_dirs(pkg, &dir) == EPKG_OK) {
1807 [ - + ]: 23 : if (run_prstmt(DIRS1, dir->path) != SQLITE_DONE) {
1808 : 0 : ERROR_STMT_SQLITE(s, STMT(DIRS1));
1809 : 0 : goto cleanup;
1810 : : }
1811 [ + - + - ]: 46 : if ((ret = run_prstmt(DIRS2, package_id, dir->path,
1812 : 23 : true)) != SQLITE_DONE) {
1813 [ # # ]: 0 : if (ret == SQLITE_CONSTRAINT) {
1814 : 0 : pkg_emit_error("Another package is already "
1815 : : "providing directory: %s",
1816 : 0 : dir->path);
1817 : 0 : } else
1818 : 0 : ERROR_STMT_SQLITE(s, STMT(DIRS2));
1819 : 0 : goto cleanup;
1820 : : }
1821 : : }
1822 : :
1823 : : /*
1824 : : * Insert categories
1825 : : */
1826 : :
1827 [ + + + + : 477 : tll_foreach(pkg->categories, c) {
- + ]
1828 : 232 : ret = run_prstmt(CATEGORY1, c->item);
1829 [ - + ]: 232 : if (ret == SQLITE_DONE)
1830 : 232 : ret = run_prstmt(CATEGORY2, package_id, c->item);
1831 [ - + ]: 232 : if (ret != SQLITE_DONE) {
1832 : 0 : ERROR_STMT_SQLITE(s, STMT(CATEGORY2));
1833 : 0 : goto cleanup;
1834 : : }
1835 : 232 : }
1836 : :
1837 : : /*
1838 : : * Insert licenses
1839 : : */
1840 : :
1841 [ + + + + : 249 : tll_foreach(pkg->licenses, l) {
- + ]
1842 [ - + ]: 4 : if (run_prstmt(LICENSES1, l->item)
1843 : 4 : != SQLITE_DONE
1844 [ + - ]: 4 : ||
1845 : 4 : run_prstmt(LICENSES2, package_id, l->item)
1846 : 4 : != SQLITE_DONE) {
1847 : 0 : ERROR_STMT_SQLITE(s, STMT(LICENSES2));
1848 : 0 : goto cleanup;
1849 : : }
1850 : 4 : }
1851 : :
1852 : : /*
1853 : : * Insert users
1854 : : */
1855 : :
1856 [ - + - + : 245 : tll_foreach(pkg->users, u) {
# # ]
1857 [ # # ]: 0 : if (run_prstmt(USERS1, u->item)
1858 : 0 : != SQLITE_DONE
1859 [ # # ]: 0 : ||
1860 : 0 : run_prstmt(USERS2, package_id, u->item)
1861 : 0 : != SQLITE_DONE) {
1862 : 0 : ERROR_STMT_SQLITE(s, STMT(USERS2));
1863 : 0 : goto cleanup;
1864 : : }
1865 : 0 : }
1866 : :
1867 : : /*
1868 : : * Insert groups
1869 : : */
1870 : :
1871 [ - + - + : 245 : tll_foreach(pkg->groups, g) {
# # ]
1872 [ # # ]: 0 : if (run_prstmt(GROUPS1, g->item)
1873 : 0 : != SQLITE_DONE
1874 [ # # ]: 0 : ||
1875 : 0 : run_prstmt(GROUPS2, package_id, g->item)
1876 : 0 : != SQLITE_DONE) {
1877 : 0 : ERROR_STMT_SQLITE(s, STMT(GROUPS2));
1878 : 0 : goto cleanup;
1879 : : }
1880 : 0 : }
1881 : :
1882 : : /*
1883 : : * Insert scripts
1884 : : */
1885 : :
1886 [ - + ]: 245 : if (pkgdb_insert_scripts(pkg, package_id, s) != EPKG_OK)
1887 : 0 : goto cleanup;
1888 : :
1889 : : /*
1890 : : * Insert lua scripts
1891 : : */
1892 [ - + ]: 245 : if (pkgdb_insert_lua_scripts(pkg, package_id, s) != EPKG_OK)
1893 : 0 : goto cleanup;
1894 : :
1895 : : /*
1896 : : * Insert options
1897 : : */
1898 : :
1899 [ + + ]: 345 : while (pkg_options(pkg, &option) == EPKG_OK) {
1900 [ + - ]: 100 : if (run_prstmt(OPTION1, option->key) != SQLITE_DONE
1901 [ + - ]: 100 : ||
1902 : 100 : run_prstmt(OPTION2, package_id, option->key, option->value)
1903 : 100 : != SQLITE_DONE) {
1904 : 0 : ERROR_STMT_SQLITE(s, STMT(OPTION2));
1905 : 0 : goto cleanup;
1906 : : }
1907 : : }
1908 : :
1909 : : /*
1910 : : * Insert shlibs
1911 : : */
1912 [ - + ]: 245 : if (pkgdb_update_shlibs_required(pkg, package_id, s) != EPKG_OK)
1913 : 0 : goto cleanup;
1914 [ - + ]: 245 : if (pkgdb_update_shlibs_provided(pkg, package_id, s) != EPKG_OK)
1915 : 0 : goto cleanup;
1916 : :
1917 : : /*
1918 : : * Insert annotation
1919 : : */
1920 [ - + ]: 245 : if (pkgdb_insert_annotations(pkg, package_id, s) != EPKG_OK)
1921 : 0 : goto cleanup;
1922 : :
1923 : : /*
1924 : : * Insert conflicts
1925 : : */
1926 [ - + ]: 245 : while (pkg_conflicts(pkg, &conflict) == EPKG_OK) {
1927 [ # # # # ]: 0 : if (run_prstmt(CONFLICT, package_id, conflict->uid)
1928 : 0 : != SQLITE_DONE) {
1929 : 0 : ERROR_STMT_SQLITE(s, STMT(CONFLICT));
1930 : 0 : goto cleanup;
1931 : : }
1932 : : }
1933 : :
1934 : : /*
1935 : : * Insert provides
1936 : : */
1937 [ - + ]: 245 : if (pkgdb_update_provides(pkg, package_id, s) != EPKG_OK)
1938 : 0 : goto cleanup;
1939 [ - + ]: 245 : if (pkgdb_update_requires(pkg, package_id, s) != EPKG_OK)
1940 : 0 : goto cleanup;
1941 : :
1942 : 245 : retcode = EPKG_OK;
1943 : :
1944 : : cleanup:
1945 [ + + ]: 246 : if (retcode != EPKG_OK)
1946 : 1 : (void)pkgdb_transaction_rollback_sqlite(s, savepoint);
1947 : 246 : free(msg);
1948 : :
1949 : 246 : return (retcode);
1950 : 246 : }
1951 : :
1952 : : static int
1953 : 245 : pkgdb_insert_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s)
1954 : : {
1955 : : const char *script;
1956 : : int64_t i;
1957 : :
1958 [ + + ]: 2450 : for (i = 0; i < PKG_NUM_SCRIPTS; i++) {
1959 : 2205 : script = pkg_script_get(pkg, i);
1960 : :
1961 [ + + ]: 2205 : if (script == NULL)
1962 : 2161 : continue;
1963 [ - + ]: 44 : if (run_prstmt(SCRIPT1, script) != SQLITE_DONE
1964 [ + - ]: 44 : ||
1965 : 44 : run_prstmt(SCRIPT2, script, package_id, i) != SQLITE_DONE) {
1966 : 0 : ERROR_STMT_SQLITE(s, STMT(SCRIPT2));
1967 : 0 : return (EPKG_FATAL);
1968 : : }
1969 : 44 : }
1970 : :
1971 : 245 : return (EPKG_OK);
1972 : 245 : }
1973 : :
1974 : : static int
1975 : 245 : pkgdb_insert_lua_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s)
1976 : : {
1977 : : int64_t i;
1978 : :
1979 [ + + ]: 1470 : for (i = 0; i < PKG_NUM_LUA_SCRIPTS; i++) {
1980 [ + + + + : 1250 : tll_foreach(pkg->lua_scripts[i], script) {
+ + ]
1981 [ - + ]: 25 : if (run_prstmt(LUASCRIPT1, script->item) != SQLITE_DONE
1982 [ + - ]: 25 : ||
1983 : 25 : run_prstmt(LUASCRIPT2, script->item, package_id, i) != SQLITE_DONE) {
1984 : 0 : ERROR_STMT_SQLITE(s, STMT(LUASCRIPT2));
1985 : 0 : return (EPKG_FATAL);
1986 : : }
1987 : 25 : }
1988 : 1225 : }
1989 : 245 : return (EPKG_OK);
1990 : 245 : }
1991 : :
1992 : : int
1993 : 245 : pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s)
1994 : : {
1995 [ + + + + : 259 : tll_foreach(pkg->shlibs_required, r) {
+ + ]
1996 [ - + ]: 14 : if (run_prstmt(SHLIBS1, r->item)
1997 : 14 : != SQLITE_DONE
1998 [ + - ]: 14 : ||
1999 : 14 : run_prstmt(SHLIBS_REQD, package_id, r->item)
2000 : 14 : != SQLITE_DONE) {
2001 : 0 : ERROR_STMT_SQLITE(s, STMT(SHLIBS_REQD));
2002 : 0 : return (EPKG_FATAL);
2003 : : }
2004 : 14 : }
2005 : :
2006 : 245 : return (EPKG_OK);
2007 : 245 : }
2008 : :
2009 : : int
2010 : 168 : pkgdb_update_config_file_content(struct pkg *p, sqlite3 *s)
2011 : : {
2012 : 168 : struct pkg_config_file *cf = NULL;
2013 : :
2014 [ + + ]: 179 : while (pkg_config_files(p, &cf) == EPKG_OK) {
2015 [ - + - + ]: 22 : if (run_prstmt(UPDATE_CONFIG_FILE, cf->content, cf->path)
2016 : 11 : != SQLITE_DONE) {
2017 : 0 : ERROR_STMT_SQLITE(s, STMT(SHLIBS_REQD));
2018 : 0 : return (EPKG_FATAL);
2019 : : }
2020 : : }
2021 : :
2022 : 168 : return (EPKG_OK);
2023 : 168 : }
2024 : :
2025 : : int
2026 : 245 : pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s)
2027 : : {
2028 [ + + + + : 260 : tll_foreach(pkg->shlibs_provided, r) {
+ + ]
2029 [ - + ]: 15 : if (run_prstmt(SHLIBS1, r->item)
2030 : 15 : != SQLITE_DONE
2031 [ + - ]: 15 : ||
2032 : 15 : run_prstmt(SHLIBS_PROV, package_id, r->item)
2033 : 15 : != SQLITE_DONE) {
2034 : 0 : ERROR_STMT_SQLITE(s, STMT(SHLIBS_PROV));
2035 : 0 : return (EPKG_FATAL);
2036 : : }
2037 : 15 : }
2038 : :
2039 : 245 : return (EPKG_OK);
2040 : 245 : }
2041 : :
2042 : : int
2043 : 245 : pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s)
2044 : : {
2045 [ + + + + : 249 : tll_foreach(pkg->requires, r) {
- + ]
2046 [ - + ]: 4 : if (run_prstmt(REQUIRE, r->item)
2047 : 4 : != SQLITE_DONE
2048 [ + - ]: 4 : ||
2049 : 4 : run_prstmt(PKG_REQUIRE, package_id, r->item)
2050 : 4 : != SQLITE_DONE) {
2051 : 0 : ERROR_STMT_SQLITE(s, STMT(PKG_REQUIRE));
2052 : 0 : return (EPKG_FATAL);
2053 : : }
2054 : 4 : }
2055 : :
2056 : 245 : return (EPKG_OK);
2057 : 245 : }
2058 : :
2059 : : int
2060 : 245 : pkgdb_update_provides(struct pkg *pkg, int64_t package_id, sqlite3 *s)
2061 : : {
2062 [ + + + + : 248 : tll_foreach(pkg->provides, p) {
- + ]
2063 [ - + ]: 3 : if (run_prstmt(PROVIDE, p->item)
2064 : 3 : != SQLITE_DONE
2065 [ + - ]: 3 : ||
2066 : 3 : run_prstmt(PKG_PROVIDE, package_id, p->item)
2067 : 3 : != SQLITE_DONE) {
2068 : 0 : ERROR_STMT_SQLITE(s, STMT(PKG_PROVIDE));
2069 : 0 : return (EPKG_FATAL);
2070 : : }
2071 : 3 : }
2072 : :
2073 : 245 : return (EPKG_OK);
2074 : 245 : }
2075 : :
2076 : : int
2077 : 245 : pkgdb_insert_annotations(struct pkg *pkg, int64_t package_id, sqlite3 *s)
2078 : : {
2079 : : struct pkg_kv *kv;
2080 : :
2081 [ + + + + : 601 : tll_foreach(pkg->annotations, k) {
+ + ]
2082 : 356 : kv = k->item;
2083 [ - + ]: 712 : if (run_prstmt(ANNOTATE1, kv->key)
2084 : 356 : != SQLITE_DONE
2085 [ + - ]: 356 : ||
2086 : 356 : run_prstmt(ANNOTATE1,kv->value)
2087 : 356 : != SQLITE_DONE
2088 [ - + ]: 356 : ||
2089 : 712 : run_prstmt(ANNOTATE2, package_id,
2090 : 356 : kv->key, kv->value)
2091 : 356 : != SQLITE_DONE) {
2092 : 0 : ERROR_STMT_SQLITE(s, STMT(ANNOTATE2));
2093 : 0 : return (EPKG_FATAL);
2094 : : }
2095 : 356 : }
2096 : 245 : return (EPKG_OK);
2097 : 245 : }
2098 : :
2099 : : int
2100 : 4 : pkgdb_add_annotation(struct pkgdb *db, struct pkg *pkg, const char *tag,
2101 : : const char *value)
2102 : : {
2103 : : int rows_changed;
2104 : :
2105 [ + - ]: 4 : assert(pkg != NULL);
2106 [ + - ]: 4 : assert(tag != NULL);
2107 [ + - ]: 4 : assert(value != NULL);
2108 : :
2109 [ - + ]: 8 : if (run_prstmt(ANNOTATE1, tag) != SQLITE_DONE
2110 [ + - ]: 4 : ||
2111 : 4 : run_prstmt(ANNOTATE1, value) != SQLITE_DONE
2112 [ - + ]: 4 : ||
2113 : 4 : run_prstmt(ANNOTATE_ADD1, pkg->uid, tag, value)
2114 : 4 : != SQLITE_DONE) {
2115 : 0 : ERROR_STMT_SQLITE(db->sqlite, STMT(ANNOTATE_ADD1));
2116 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
2117 : 0 : return (EPKG_FATAL);
2118 : : }
2119 : :
2120 : : /* Expect rows_changed == 1 unless there's already an
2121 : : annotation using the given tag */
2122 : :
2123 : 4 : rows_changed = sqlite3_changes(db->sqlite);
2124 : :
2125 : 4 : return (rows_changed == 1 ? EPKG_OK : EPKG_WARN);
2126 : 4 : }
2127 : :
2128 : : int
2129 : 63 : pkgdb_set_pkg_digest(struct pkgdb *db, struct pkg *pkg)
2130 : : {
2131 : :
2132 [ + - ]: 63 : assert(pkg != NULL);
2133 [ + - ]: 63 : assert(db != NULL);
2134 : :
2135 [ - + ]: 63 : if (run_prstmt(UPDATE_DIGEST, pkg->digest, pkg->id) != SQLITE_DONE) {
2136 : 0 : ERROR_STMT_SQLITE(db->sqlite, STMT(UPDATE_DIGEST));
2137 : 0 : return (EPKG_FATAL);
2138 : : }
2139 : :
2140 : 63 : return (EPKG_OK);
2141 : 63 : }
2142 : :
2143 : : int
2144 : 4 : pkgdb_modify_annotation(struct pkgdb *db, struct pkg *pkg, const char *tag,
2145 : : const char *value)
2146 : : {
2147 : : int rows_changed;
2148 : :
2149 [ + - ]: 4 : assert(pkg!= NULL);
2150 [ + - ]: 4 : assert(tag != NULL);
2151 [ + - ]: 4 : assert(value != NULL);
2152 : :
2153 [ - + ]: 4 : if (pkgdb_transaction_begin_sqlite(db->sqlite, NULL) != EPKG_OK)
2154 : 0 : return (EPKG_FATAL);
2155 : :
2156 [ - + ]: 8 : if (run_prstmt(ANNOTATE1, tag) != SQLITE_DONE
2157 [ + - ]: 4 : ||
2158 : 4 : run_prstmt(ANNOTATE1, value) != SQLITE_DONE
2159 [ - + ]: 4 : ||
2160 : 4 : run_prstmt(ANNOTATE_MOD1, pkg->uid, tag, value) !=
2161 : : SQLITE_DONE) {
2162 : 0 : ERROR_STMT_SQLITE(db->sqlite, STMT(ANNOTATE_MOD1));
2163 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
2164 : :
2165 : 0 : return (EPKG_FATAL);
2166 : : }
2167 : 4 : rows_changed = sqlite3_changes(db->sqlite);
2168 : :
2169 [ - + ]: 4 : if (run_prstmt(ANNOTATE_DEL2) != SQLITE_DONE) {
2170 : 0 : ERROR_STMT_SQLITE(db->sqlite, STMT(ANNOTATE_DEL2));
2171 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
2172 : :
2173 : 0 : return (EPKG_FATAL);
2174 : : }
2175 : :
2176 [ - + ]: 4 : if (pkgdb_transaction_commit_sqlite(db->sqlite, NULL) != EPKG_OK)
2177 : 0 : return (EPKG_FATAL);
2178 : :
2179 : : /* Something has gone very wrong if rows_changed != 1 here */
2180 : 4 : return (rows_changed == 1 ? EPKG_OK : EPKG_WARN);
2181 : 4 : }
2182 : :
2183 : : int
2184 : 5 : pkgdb_delete_annotation(struct pkgdb *db, struct pkg *pkg, const char *tag)
2185 : : {
2186 : : int rows_changed;
2187 : : bool result;
2188 : :
2189 [ + - ]: 5 : assert(pkg != NULL);
2190 [ + - ]: 5 : assert(tag != NULL);
2191 : :
2192 [ - + ]: 5 : if (pkgdb_transaction_begin_sqlite(db->sqlite, NULL) != EPKG_OK)
2193 : 0 : return (EPKG_FATAL);
2194 : :
2195 : 10 : result = (run_prstmt(ANNOTATE_DEL1, pkg->uid, tag)
2196 : 5 : == SQLITE_DONE);
2197 : :
2198 : 5 : rows_changed = sqlite3_changes(db->sqlite);
2199 : :
2200 [ - + ]: 5 : if (!result
2201 [ + - ]: 5 : ||
2202 : 5 : run_prstmt(ANNOTATE_DEL2) != SQLITE_DONE) {
2203 : 0 : ERROR_STMT_SQLITE(db->sqlite, STMT(ANNOTATE_DEL2));
2204 : 0 : pkgdb_transaction_rollback_sqlite(db->sqlite, NULL);
2205 : 0 : return (EPKG_FATAL);
2206 : : }
2207 : :
2208 [ - + ]: 5 : if (pkgdb_transaction_commit_sqlite(db->sqlite, NULL) != EPKG_OK)
2209 : 0 : return (EPKG_FATAL);
2210 : :
2211 : 5 : return (rows_changed == 1 ? EPKG_OK : EPKG_WARN);
2212 : 5 : }
2213 : :
2214 : : /*
2215 : : * Complete a transaction started by pkgdb_register_pkg().
2216 : : */
2217 : : int
2218 : 245 : pkgdb_register_finale(struct pkgdb *db, int retcode, const char *savepoint)
2219 : : {
2220 : 245 : int ret = EPKG_OK;
2221 : :
2222 [ + - ]: 245 : assert(db != NULL);
2223 : :
2224 [ + + ]: 245 : if (retcode == EPKG_OK)
2225 : 244 : ret = pkgdb_transaction_commit_sqlite(db->sqlite, savepoint);
2226 : : else
2227 : 1 : ret = pkgdb_transaction_rollback_sqlite(db->sqlite, savepoint);
2228 : :
2229 : 245 : return (ret);
2230 : : }
2231 : :
2232 : : int
2233 : 44 : pkgdb_unregister_pkg(struct pkgdb *db, int64_t id)
2234 : : {
2235 : : sqlite3_stmt *stmt_del;
2236 : : unsigned int obj;
2237 : : int ret;
2238 : 44 : const char sql[] = ""
2239 : : "DELETE FROM packages WHERE id = ?1;";
2240 : 44 : const char *deletions[] = {
2241 : : "directories WHERE id NOT IN "
2242 : : "(SELECT DISTINCT directory_id FROM pkg_directories)",
2243 : : "categories WHERE id NOT IN "
2244 : : "(SELECT DISTINCT category_id FROM pkg_categories)",
2245 : : "licenses WHERE id NOT IN "
2246 : : "(SELECT DISTINCT license_id FROM pkg_licenses)",
2247 : : /* TODO print the users that are not used anymore */
2248 : : "users WHERE id NOT IN "
2249 : : "(SELECT DISTINCT user_id FROM pkg_users)",
2250 : : /* TODO print the groups that are not used anymore */
2251 : : "groups WHERE id NOT IN "
2252 : : "(SELECT DISTINCT group_id FROM pkg_groups)",
2253 : : "shlibs WHERE id NOT IN "
2254 : : "(SELECT DISTINCT shlib_id FROM pkg_shlibs_required)"
2255 : : "AND id NOT IN "
2256 : : "(SELECT DISTINCT shlib_id FROM pkg_shlibs_provided)",
2257 : : "script WHERE script_id NOT IN "
2258 : : "(SELECT DISTINCT script_id FROM pkg_script)",
2259 : : "lua_script WHERE lua_script_id NOT IN "
2260 : : "(SELECT DISTINCT lua_script_id FROM pkg_lua_script)",
2261 : : };
2262 : :
2263 [ + - ]: 44 : assert(db != NULL);
2264 : :
2265 : 44 : stmt_del = prepare_sql(db->sqlite, sql);
2266 [ + - ]: 44 : if (stmt_del == NULL)
2267 : 0 : return (EPKG_FATAL);
2268 : :
2269 : 44 : sqlite3_bind_int64(stmt_del, 1, id);
2270 : 44 : pkgdb_debug(4, stmt_del);
2271 : :
2272 : 44 : ret = sqlite3_step(stmt_del);
2273 : :
2274 [ - + ]: 44 : if (ret != SQLITE_DONE) {
2275 : 0 : ERROR_STMT_SQLITE(db->sqlite, stmt_del);
2276 : 0 : sqlite3_finalize(stmt_del);
2277 : 0 : return (EPKG_FATAL);
2278 : : }
2279 : 44 : sqlite3_finalize(stmt_del);
2280 : :
2281 [ + + ]: 396 : for (obj = 0 ;obj < NELEM(deletions); obj++) {
2282 : 352 : ret = sql_exec(db->sqlite, "DELETE FROM %s;", deletions[obj]);
2283 [ - + ]: 352 : if (ret != EPKG_OK)
2284 : 0 : return (EPKG_FATAL);
2285 : 352 : }
2286 : 44 : return (EPKG_OK);
2287 : 44 : }
2288 : :
2289 : : int
2290 : 3121 : sql_exec(sqlite3 *s, const char *sql, ...)
2291 : : {
2292 : : va_list ap;
2293 : : const char *sql_to_exec;
2294 : 3121 : char *sqlbuf = NULL;
2295 : : char *errmsg;
2296 : 3121 : int ret = EPKG_FATAL;
2297 : :
2298 [ + - ]: 3121 : assert(s != NULL);
2299 [ + - ]: 3121 : assert(sql != NULL);
2300 : :
2301 [ + + ]: 3121 : if (strchr(sql, '%') != NULL) {
2302 : 640 : va_start(ap, sql);
2303 : 640 : sqlbuf = sqlite3_vmprintf(sql, ap);
2304 : 640 : va_end(ap);
2305 : 640 : sql_to_exec = sqlbuf;
2306 : 640 : } else {
2307 : 2481 : sql_to_exec = sql;
2308 : : }
2309 : :
2310 : 3121 : dbg(4, "executing '%s'", sql_to_exec);
2311 [ - + ]: 3121 : if (sqlite3_exec(s, sql_to_exec, NULL, NULL, &errmsg) != SQLITE_OK) {
2312 : 0 : ERROR_SQLITE(s, sql_to_exec);
2313 : 0 : sqlite3_free(errmsg);
2314 : 0 : goto cleanup;
2315 : : }
2316 : :
2317 : 3121 : ret = EPKG_OK;
2318 : :
2319 : : cleanup:
2320 [ + + ]: 3121 : if (sqlbuf != NULL)
2321 : 640 : sqlite3_free(sqlbuf);
2322 : :
2323 : 3121 : return (ret);
2324 : : }
2325 : :
2326 : : int
2327 : 904 : get_pragma(sqlite3 *s, const char *sql, int64_t *res, bool silence)
2328 : : {
2329 : : sqlite3_stmt *stmt;
2330 : : int ret;
2331 : :
2332 [ + - ]: 904 : assert(s != NULL && sql != NULL);
2333 : :
2334 [ + - ]: 904 : if (sqlite3_prepare_v2(s, sql, -1, &stmt, NULL) != SQLITE_OK) {
2335 [ # # ]: 0 : if (!silence)
2336 : 0 : ERROR_SQLITE(s, sql);
2337 : 0 : return (EPKG_OK);
2338 : : }
2339 : 904 : pkgdb_debug(4, stmt);
2340 : :
2341 [ + - + + : 1808 : PKGDB_SQLITE_RETRY_ON_BUSY(ret)
+ + - + #
# ]
2342 : 904 : ret = sqlite3_step(stmt);
2343 : :
2344 [ - + ]: 904 : if (ret == SQLITE_ROW)
2345 : 904 : *res = sqlite3_column_int64(stmt, 0);
2346 : :
2347 : :
2348 [ - + # # ]: 904 : if (ret != SQLITE_ROW && !silence)
2349 : 0 : ERROR_STMT_SQLITE(s, stmt);
2350 : 904 : sqlite3_finalize(stmt);
2351 : :
2352 : 904 : return (ret == SQLITE_ROW ? EPKG_OK : EPKG_FATAL);
2353 : 904 : }
2354 : :
2355 : : int
2356 : 25 : pkgdb_compact(struct pkgdb *db)
2357 : : {
2358 : 25 : int64_t page_count = 0;
2359 : 25 : int64_t freelist_count = 0;
2360 : : int ret;
2361 : :
2362 [ + - ]: 25 : assert(db != NULL);
2363 : :
2364 : 25 : ret = get_pragma(db->sqlite, "PRAGMA page_count;", &page_count, false);
2365 [ - + ]: 25 : if (ret != EPKG_OK)
2366 : 0 : return (EPKG_FATAL);
2367 : :
2368 : 25 : ret = get_pragma(db->sqlite, "PRAGMA freelist_count;",
2369 : : &freelist_count, false);
2370 [ - + ]: 25 : if (ret != EPKG_OK)
2371 : 0 : return (EPKG_FATAL);
2372 : :
2373 : : /*
2374 : : * Only compact if we will save 25% (or more) of the current
2375 : : * used space.
2376 : : */
2377 : :
2378 [ - + # # ]: 25 : if (freelist_count > 0 && freelist_count / (float)page_count < 0.25)
2379 : 0 : return (EPKG_OK);
2380 : :
2381 : 25 : return (sql_exec(db->sqlite, "VACUUM;"));
2382 : 25 : }
2383 : :
2384 : : static int
2385 : 17 : pkgdb_vset(struct pkgdb *db, int64_t id, va_list ap)
2386 : : {
2387 : : int attr;
2388 : : sqlite3_stmt *stmt;
2389 : : int64_t flatsize;
2390 : : bool automatic, locked, vital;
2391 : : char *oldval;
2392 : : char *newval;
2393 : :
2394 : : /* Ensure there is an entry for each of the pkg_set_attr enum values */
2395 : 17 : const char *sql[PKG_SET_MAX] = {
2396 : : [PKG_SET_FLATSIZE] =
2397 : : "UPDATE packages SET flatsize = ?1 WHERE id = ?2",
2398 : : [PKG_SET_AUTOMATIC] =
2399 : : "UPDATE packages SET automatic = ?1 WHERE id = ?2",
2400 : : [PKG_SET_LOCKED] =
2401 : : "UPDATE packages SET locked = ?1 WHERE id = ?2",
2402 : : [PKG_SET_DEPORIGIN] =
2403 : : "UPDATE deps SET origin = ?1, "
2404 : : "name=(SELECT name FROM packages WHERE origin = ?1), "
2405 : : "version=(SELECT version FROM packages WHERE origin = ?1) "
2406 : : "WHERE package_id = ?2 AND origin = ?3",
2407 : : [PKG_SET_ORIGIN] =
2408 : : "UPDATE packages SET origin=?1 WHERE id=?2",
2409 : : [PKG_SET_DEPNAME] =
2410 : : "UPDATE deps SET name = ?1, "
2411 : : "version=(SELECT version FROM packages WHERE name = ?1) "
2412 : : "WHERE package_id = ?2 AND name = ?3",
2413 : : [PKG_SET_NAME] =
2414 : : "UPDATE packages SET name=?1 WHERE id=?2",
2415 : : [PKG_SET_VITAL] =
2416 : : "UPDATE packages SET vital = ?1 WHERE id = ?2",
2417 : : };
2418 : :
2419 [ + - + + ]: 34 : while ((attr = va_arg(ap, int)) > 0) {
2420 : 17 : stmt = prepare_sql(db->sqlite, sql[attr]);
2421 [ - + ]: 17 : if (stmt == NULL)
2422 : 0 : return (EPKG_FATAL);
2423 : :
2424 [ - - + + : 17 : switch (attr) {
- - + +
+ ]
2425 : : case PKG_SET_FLATSIZE:
2426 [ # # ]: 0 : flatsize = va_arg(ap, int64_t);
2427 : 0 : sqlite3_bind_int64(stmt, 1, flatsize);
2428 : 0 : sqlite3_bind_int64(stmt, 2, id);
2429 : 0 : break;
2430 : : case PKG_SET_AUTOMATIC:
2431 [ + - ]: 2 : automatic = (bool)va_arg(ap, int);
2432 : 2 : sqlite3_bind_int64(stmt, 1, automatic);
2433 : 2 : sqlite3_bind_int64(stmt, 2, id);
2434 : 2 : break;
2435 : : case PKG_SET_LOCKED:
2436 [ + - ]: 11 : locked = (bool)va_arg(ap, int);
2437 : 11 : sqlite3_bind_int64(stmt, 1, locked);
2438 : 11 : sqlite3_bind_int64(stmt, 2, id);
2439 : 11 : break;
2440 : : case PKG_SET_DEPORIGIN:
2441 : : case PKG_SET_DEPNAME:
2442 [ # # ]: 0 : oldval = va_arg(ap, char *);
2443 [ # # ]: 0 : newval = va_arg(ap, char *);
2444 : 0 : sqlite3_bind_text(stmt, 1, newval, -1, SQLITE_STATIC);
2445 : 0 : sqlite3_bind_int64(stmt, 2, id);
2446 : 0 : sqlite3_bind_text(stmt, 3, oldval, -1, SQLITE_STATIC);
2447 : 2 : break;
2448 : : case PKG_SET_ORIGIN:
2449 : : case PKG_SET_NAME:
2450 [ + - ]: 2 : newval = va_arg(ap, char *);
2451 : 2 : sqlite3_bind_text(stmt, 1, newval, -1, SQLITE_STATIC);
2452 : 2 : sqlite3_bind_int64(stmt, 2, id);
2453 : 2 : break;
2454 : : case PKG_SET_VITAL:
2455 [ + - ]: 2 : vital = (bool)va_arg(ap, int);
2456 : 2 : sqlite3_bind_int64(stmt, 1, vital);
2457 : 2 : sqlite3_bind_int64(stmt, 2, id);
2458 : 2 : break;
2459 : : }
2460 : :
2461 : 17 : pkgdb_debug(4, stmt);
2462 [ - + ]: 17 : if (sqlite3_step(stmt) != SQLITE_DONE) {
2463 : 0 : ERROR_STMT_SQLITE(db->sqlite, stmt);
2464 : 0 : sqlite3_finalize(stmt);
2465 : 0 : return (EPKG_FATAL);
2466 : : }
2467 : :
2468 : 17 : sqlite3_finalize(stmt);
2469 : : }
2470 : 17 : return (EPKG_OK);
2471 : 17 : }
2472 : :
2473 : : int
2474 : 17 : pkgdb_set2(struct pkgdb *db, struct pkg *pkg, ...)
2475 : : {
2476 : 17 : int ret = EPKG_OK;
2477 : : va_list ap;
2478 : :
2479 [ + - ]: 17 : assert(pkg != NULL);
2480 : :
2481 : 17 : va_start(ap, pkg);
2482 : 17 : ret = pkgdb_vset(db, pkg->id, ap);
2483 : 17 : va_end(ap);
2484 : :
2485 : 17 : return (ret);
2486 : : }
2487 : :
2488 : : int
2489 : 0 : pkgdb_file_set_cksum(struct pkgdb *db, struct pkg_file *file,
2490 : : const char *sum)
2491 : : {
2492 : 0 : sqlite3_stmt *stmt = NULL;
2493 : 0 : const char sql_file_update[] = ""
2494 : : "UPDATE files SET sha256 = ?1 WHERE path = ?2";
2495 : :
2496 : 0 : stmt = prepare_sql(db->sqlite, sql_file_update);
2497 [ # # ]: 0 : if (stmt == NULL)
2498 : 0 : return (EPKG_FATAL);
2499 : 0 : sqlite3_bind_text(stmt, 1, sum, -1, SQLITE_STATIC);
2500 : 0 : sqlite3_bind_text(stmt, 2, file->path, -1, SQLITE_STATIC);
2501 : 0 : pkgdb_debug(4, stmt);
2502 : :
2503 [ # # ]: 0 : if (sqlite3_step(stmt) != SQLITE_DONE) {
2504 : 0 : ERROR_STMT_SQLITE(db->sqlite, stmt);
2505 : 0 : sqlite3_finalize(stmt);
2506 : 0 : return (EPKG_FATAL);
2507 : : }
2508 : 0 : sqlite3_finalize(stmt);
2509 : 0 : file->sum = xstrdup(sum);
2510 : :
2511 : 0 : return (EPKG_OK);
2512 : 0 : }
2513 : :
2514 : : /*
2515 : : * create our custom functions in the sqlite3 connection.
2516 : : * Used both in the shell and pkgdb_open
2517 : : */
2518 : : int
2519 : 557 : pkgdb_sqlcmd_init(sqlite3 *db, __unused const char **err,
2520 : : __unused const void *noused)
2521 : : {
2522 : 557 : sqlite3_create_function(db, "now", 0, SQLITE_ANY|SQLITE_DETERMINISTIC, NULL,
2523 : : pkgdb_now, NULL, NULL);
2524 : 557 : sqlite3_create_function(db, "regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, NULL,
2525 : : pkgdb_regex, NULL, NULL);
2526 : 557 : sqlite3_create_function(db, "vercmp", 3, SQLITE_ANY|SQLITE_DETERMINISTIC, NULL,
2527 : : pkgdb_vercmp, NULL, NULL);
2528 : :
2529 : 557 : return SQLITE_OK;
2530 : : }
2531 : :
2532 : : void
2533 : 0 : pkgdb_cmd(int argc, char **argv)
2534 : : {
2535 : 0 : sqlite3_shell(argc, argv);
2536 : 0 : }
2537 : :
2538 : : void
2539 : 0 : pkgdb_init_proc(void)
2540 : : {
2541 : 0 : sqlite3_initialize();
2542 : 0 : sqlite3_auto_extension((void(*)(void))pkgdb_sqlcmd_init);
2543 : 0 : }
2544 : :
2545 : :
2546 : : void
2547 : 0 : pkgshell_opendb(const char **reponame)
2548 : : {
2549 : : char localpath[MAXPATHLEN];
2550 : :
2551 : 0 : snprintf(localpath, sizeof(localpath), "%s/local.sqlite", ctx.dbdir);
2552 : 0 : *reponame = xstrdup(localpath);
2553 : 0 : }
2554 : :
2555 : : static int
2556 : 266 : pkgdb_write_lock_pid(struct pkgdb *db)
2557 : : {
2558 : 266 : const char lock_pid_sql[] = ""
2559 : : "INSERT INTO pkg_lock_pid VALUES (?1);";
2560 : 266 : sqlite3_stmt *stmt = NULL;
2561 : :
2562 : 266 : stmt = prepare_sql(db->sqlite, lock_pid_sql);
2563 [ + - ]: 266 : if (stmt == NULL)
2564 : 0 : return (EPKG_FATAL);
2565 : 266 : sqlite3_bind_int64(stmt, 1, (int64_t)getpid());
2566 : :
2567 [ - + ]: 266 : if (sqlite3_step(stmt) != SQLITE_DONE) {
2568 : 0 : ERROR_SQLITE(db->sqlite, lock_pid_sql);
2569 : 0 : sqlite3_finalize(stmt);
2570 : 0 : return (EPKG_FATAL);
2571 : : }
2572 : 266 : sqlite3_finalize(stmt);
2573 : :
2574 : 266 : return (EPKG_OK);
2575 : 266 : }
2576 : :
2577 : : static int
2578 : 407 : pkgdb_remove_lock_pid(struct pkgdb *db, int64_t pid)
2579 : : {
2580 : 407 : const char lock_pid_sql[] = ""
2581 : : "DELETE FROM pkg_lock_pid WHERE pid = ?1;";
2582 : 407 : sqlite3_stmt *stmt = NULL;
2583 : :
2584 : 407 : stmt = prepare_sql(db->sqlite, lock_pid_sql);
2585 [ + - ]: 407 : if (stmt == NULL)
2586 : 0 : return (EPKG_FATAL);
2587 : 407 : sqlite3_bind_int64(stmt, 1, pid);
2588 : :
2589 [ - + ]: 407 : if (sqlite3_step(stmt) != SQLITE_DONE) {
2590 : 0 : ERROR_STMT_SQLITE(db->sqlite, stmt);
2591 : 0 : sqlite3_finalize(stmt);
2592 : 0 : return (EPKG_FATAL);
2593 : : }
2594 : 407 : sqlite3_finalize(stmt);
2595 : :
2596 : 407 : return (EPKG_OK);
2597 : 407 : }
2598 : :
2599 : : static int
2600 : 0 : pkgdb_check_lock_pid(struct pkgdb *db)
2601 : : {
2602 : 0 : sqlite3_stmt *stmt = NULL;
2603 : 0 : int found = 0;
2604 : : int64_t pid, lpid;
2605 : 0 : const char query[] = "SELECT pid FROM pkg_lock_pid;";
2606 : :
2607 : 0 : stmt = prepare_sql(db->sqlite, query);
2608 [ # # ]: 0 : if (stmt == NULL)
2609 : 0 : return (EPKG_FATAL);
2610 : :
2611 : 0 : lpid = getpid();
2612 : :
2613 [ # # ]: 0 : while (sqlite3_step(stmt) != SQLITE_DONE) {
2614 : 0 : pid = sqlite3_column_int64(stmt, 0);
2615 [ # # ]: 0 : if (pid != lpid) {
2616 [ # # ]: 0 : if (kill((pid_t)pid, 0) == -1) {
2617 : 0 : dbg(1, "found stale pid %lld in lock database, my pid is: %lld",
2618 : : (long long)pid, (long long)lpid);
2619 [ # # ]: 0 : if (pkgdb_remove_lock_pid(db, pid) != EPKG_OK){
2620 : 0 : sqlite3_finalize(stmt);
2621 : 0 : return (EPKG_FATAL);
2622 : : }
2623 : 0 : }
2624 : : else {
2625 : 0 : pkg_emit_notice("process with pid %lld still holds the lock",
2626 : 0 : (long long int)pid);
2627 : 0 : found ++;
2628 : : }
2629 : 0 : }
2630 : : }
2631 : :
2632 [ # # ]: 0 : if (found == 0)
2633 : 0 : return (EPKG_END);
2634 : :
2635 : 0 : return (EPKG_OK);
2636 : 0 : }
2637 : :
2638 : : static int
2639 : 0 : pkgdb_reset_lock(struct pkgdb *db)
2640 : : {
2641 : 0 : const char init_sql[] = ""
2642 : : "UPDATE pkg_lock SET exclusive=0, advisory=0, read=0;";
2643 : : int ret;
2644 : :
2645 : 0 : ret = sqlite3_exec(db->sqlite, init_sql, NULL, NULL, NULL);
2646 : :
2647 [ # # ]: 0 : if (ret == SQLITE_OK)
2648 : 0 : return (EPKG_OK);
2649 : :
2650 : 0 : return (EPKG_FATAL);
2651 : 0 : }
2652 : :
2653 : : static int
2654 : 409 : pkgdb_try_lock(struct pkgdb *db, const char *lock_sql, pkgdb_lock_t type,
2655 : : bool upgrade)
2656 : : {
2657 : 409 : unsigned int tries = 0;
2658 : : struct timespec ts;
2659 : 409 : int ret = EPKG_END;
2660 : : const pkg_object *timeout, *max_tries;
2661 : 409 : double num_timeout = 1.0;
2662 : 409 : int64_t num_maxtries = 1;
2663 : 409 : const char reset_lock_sql[] = ""
2664 : : "DELETE FROM pkg_lock; INSERT INTO pkg_lock VALUES (0,0,0);";
2665 : :
2666 : :
2667 : 409 : timeout = pkg_config_get("LOCK_WAIT");
2668 : 409 : max_tries = pkg_config_get("LOCK_RETRIES");
2669 : :
2670 [ - + ]: 409 : if (timeout)
2671 : 409 : num_timeout = pkg_object_int(timeout);
2672 [ - + ]: 409 : if (max_tries)
2673 : 409 : num_maxtries = pkg_object_int(max_tries);
2674 : :
2675 [ - + ]: 409 : while (tries <= num_maxtries) {
2676 : 409 : ret = sqlite3_exec(db->sqlite, lock_sql, NULL, NULL, NULL);
2677 [ + - ]: 409 : if (ret != SQLITE_OK) {
2678 [ # # # # ]: 0 : if (ret == SQLITE_READONLY && type == PKGDB_LOCK_READONLY) {
2679 : 0 : dbg(1, "want read lock but cannot write to database, "
2680 : : "slightly ignore this error for now");
2681 : 0 : return (EPKG_OK);
2682 : : }
2683 : 0 : return (EPKG_FATAL);
2684 : : }
2685 : :
2686 : 409 : ret = EPKG_END;
2687 [ - + ]: 409 : if (sqlite3_changes(db->sqlite) == 0) {
2688 [ # # ]: 0 : if (pkgdb_check_lock_pid(db) == EPKG_END) {
2689 : : /* No live processes found, so we can safely reset lock */
2690 : 0 : dbg(1, "no concurrent processes found, cleanup the lock");
2691 : 0 : pkgdb_reset_lock(db);
2692 : :
2693 [ # # ]: 0 : if (upgrade) {
2694 : : /*
2695 : : * In case of upgrade we should obtain a lock from the beginning,
2696 : : * hence switch upgrade to retain
2697 : : */
2698 : 0 : pkgdb_remove_lock_pid(db, (int64_t)getpid());
2699 : 0 : return pkgdb_obtain_lock(db, type);
2700 : : }
2701 : : else {
2702 : : /*
2703 : : * We might have inconsistent db, or some strange issue, so
2704 : : * just insert new record and go forward
2705 : : */
2706 : 0 : pkgdb_remove_lock_pid(db, (int64_t)getpid());
2707 : 0 : sqlite3_exec(db->sqlite, reset_lock_sql, NULL, NULL, NULL);
2708 : 0 : return pkgdb_obtain_lock(db, type);
2709 : : }
2710 : : }
2711 [ # # ]: 0 : else if (num_timeout > 0) {
2712 : 0 : ts.tv_sec = (int)num_timeout;
2713 : 0 : ts.tv_nsec = (num_timeout - (int)num_timeout) * 1000000000.;
2714 : 0 : dbg(1, "waiting for database lock for %d times, "
2715 : : "next try in %.2f seconds", tries, num_timeout);
2716 : 0 : (void)nanosleep(&ts, NULL);
2717 : 0 : }
2718 : : else {
2719 : 0 : break;
2720 : : }
2721 : 0 : }
2722 [ + + ]: 409 : else if (!upgrade) {
2723 : 266 : ret = pkgdb_write_lock_pid(db);
2724 : 266 : break;
2725 : : }
2726 : : else {
2727 : 143 : ret = EPKG_OK;
2728 : 143 : break;
2729 : : }
2730 : 0 : tries ++;
2731 : : }
2732 : :
2733 : 409 : return (ret);
2734 : 409 : }
2735 : :
2736 : : int
2737 : 354 : pkgdb_obtain_lock(struct pkgdb *db, pkgdb_lock_t type)
2738 : : {
2739 : : int ret;
2740 : :
2741 : 354 : const char readonly_lock_sql[] = ""
2742 : : "UPDATE pkg_lock SET read=read+1 WHERE exclusive=0;";
2743 : 354 : const char advisory_lock_sql[] = ""
2744 : : "UPDATE pkg_lock SET advisory=1 WHERE exclusive=0 AND advisory=0;";
2745 : 354 : const char exclusive_lock_sql[] = ""
2746 : : "UPDATE pkg_lock SET exclusive=1 WHERE exclusive=0 AND advisory=0 AND read=0;";
2747 : 354 : const char *lock_sql = NULL;
2748 : :
2749 [ + - ]: 354 : assert(db != NULL);
2750 : :
2751 [ + - + + ]: 354 : switch (type) {
2752 : : case PKGDB_LOCK_READONLY:
2753 [ - + ]: 88 : if (!ucl_object_toboolean(pkg_config_get("READ_LOCK")))
2754 : 88 : return (EPKG_OK);
2755 : 0 : lock_sql = readonly_lock_sql;
2756 : 0 : dbg(1, "want to get a read only lock on a database");
2757 : 0 : break;
2758 : : case PKGDB_LOCK_ADVISORY:
2759 : 151 : lock_sql = advisory_lock_sql;
2760 : 151 : dbg(1, "want to get an advisory lock on a database");
2761 : 151 : break;
2762 : : case PKGDB_LOCK_EXCLUSIVE:
2763 : 115 : dbg(1, "want to get an exclusive lock on a database");
2764 : 115 : lock_sql = exclusive_lock_sql;
2765 : 115 : break;
2766 : : }
2767 : :
2768 : 266 : ret = pkgdb_try_lock(db, lock_sql, type, false);
2769 : :
2770 [ + - ]: 266 : if (ret != EPKG_OK)
2771 : 0 : dbg(1, "failed to obtain the lock: %s",
2772 : : sqlite3_errmsg(db->sqlite));
2773 : :
2774 : 266 : return (ret);
2775 : 354 : }
2776 : :
2777 : : int
2778 : 143 : pkgdb_upgrade_lock(struct pkgdb *db, pkgdb_lock_t old_type, pkgdb_lock_t new_type)
2779 : : {
2780 : 143 : const char advisory_exclusive_lock_sql[] = ""
2781 : : "UPDATE pkg_lock SET exclusive=1,advisory=1 WHERE exclusive=0 AND advisory=1 AND read=0;";
2782 : 143 : int ret = EPKG_FATAL;
2783 : :
2784 [ + - ]: 143 : assert(db != NULL);
2785 : :
2786 [ + - - + ]: 143 : if (old_type == PKGDB_LOCK_ADVISORY && new_type == PKGDB_LOCK_EXCLUSIVE) {
2787 : 143 : dbg(1, "want to upgrade advisory to exclusive lock");
2788 : 286 : ret = pkgdb_try_lock(db, advisory_exclusive_lock_sql,
2789 : 143 : new_type, true);
2790 : 143 : }
2791 : :
2792 : 143 : return (ret);
2793 : : }
2794 : :
2795 : : int
2796 : 0 : pkgdb_downgrade_lock(struct pkgdb *db, pkgdb_lock_t old_type,
2797 : : pkgdb_lock_t new_type)
2798 : : {
2799 : 0 : const char downgrade_exclusive_lock_sql[] = ""
2800 : : "UPDATE pkg_lock SET exclusive=0,advisory=1 WHERE exclusive=1 "
2801 : : "AND advisory=1 AND read=0;";
2802 : 0 : int ret = EPKG_FATAL;
2803 : :
2804 [ # # ]: 0 : assert(db != NULL);
2805 : :
2806 [ # # # # ]: 0 : if (old_type == PKGDB_LOCK_EXCLUSIVE &&
2807 : 0 : new_type == PKGDB_LOCK_ADVISORY) {
2808 : 0 : dbg(1, "want to downgrade exclusive to advisory lock");
2809 : 0 : ret = pkgdb_try_lock(db, downgrade_exclusive_lock_sql,
2810 : 0 : new_type, true);
2811 : 0 : }
2812 : :
2813 : 0 : return (ret);
2814 : : }
2815 : :
2816 : : int
2817 : 505 : pkgdb_release_lock(struct pkgdb *db, pkgdb_lock_t type)
2818 : : {
2819 : 505 : const char readonly_unlock_sql[] = ""
2820 : : "UPDATE pkg_lock SET read=read-1 WHERE read>0;";
2821 : 505 : const char advisory_unlock_sql[] = ""
2822 : : "UPDATE pkg_lock SET advisory=0 WHERE advisory=1;";
2823 : 505 : const char exclusive_unlock_sql[] = ""
2824 : : "UPDATE pkg_lock SET exclusive=0 WHERE exclusive=1;";
2825 : 505 : const char *unlock_sql = NULL;
2826 : 505 : int ret = EPKG_FATAL;
2827 : :
2828 [ + + ]: 505 : if (db == NULL)
2829 : 8 : return (EPKG_OK);
2830 : :
2831 [ + - + + ]: 497 : switch (type) {
2832 : : case PKGDB_LOCK_READONLY:
2833 [ - + ]: 83 : if (!ucl_object_toboolean(pkg_config_get("READ_LOCK")))
2834 : 83 : return (EPKG_OK);
2835 : :
2836 : 0 : unlock_sql = readonly_unlock_sql;
2837 : 0 : dbg(1, "release a read only lock on a database");
2838 : :
2839 : 0 : break;
2840 : : case PKGDB_LOCK_ADVISORY:
2841 : 151 : unlock_sql = advisory_unlock_sql;
2842 : 151 : dbg(1, "release an advisory lock on a database");
2843 : 151 : break;
2844 : : case PKGDB_LOCK_EXCLUSIVE:
2845 : 263 : dbg(1, "release an exclusive lock on a database");
2846 : 263 : unlock_sql = exclusive_unlock_sql;
2847 : 263 : break;
2848 : : }
2849 : :
2850 : 414 : ret = sqlite3_exec(db->sqlite, unlock_sql, NULL, NULL, NULL);
2851 [ + + ]: 414 : if (ret != SQLITE_OK)
2852 : 2 : return (EPKG_FATAL);
2853 : :
2854 [ + + ]: 412 : if (sqlite3_changes(db->sqlite) == 0)
2855 : 5 : return (EPKG_END);
2856 : :
2857 : 407 : return pkgdb_remove_lock_pid(db, (int64_t)getpid());
2858 : 505 : }
2859 : :
2860 : : int64_t
2861 : 0 : pkgdb_stats(struct pkgdb *db, pkg_stats_t type)
2862 : : {
2863 : 0 : sqlite3_stmt *stmt = NULL;
2864 : 0 : int64_t stats = 0;
2865 : 0 : const char *sql = NULL;
2866 : :
2867 [ # # ]: 0 : assert(db != NULL);
2868 : :
2869 [ # # # # : 0 : switch(type) {
# # # ]
2870 : : case PKG_STATS_LOCAL_COUNT:
2871 : 0 : sql = "SELECT COUNT(id) FROM main.packages;";
2872 : 0 : break;
2873 : : case PKG_STATS_LOCAL_SIZE:
2874 : 0 : sql = "SELECT SUM(flatsize) FROM main.packages;";
2875 : 0 : break;
2876 : : case PKG_STATS_REMOTE_UNIQUE:
2877 : : case PKG_STATS_REMOTE_COUNT:
2878 : : case PKG_STATS_REMOTE_SIZE:
2879 [ # # # # : 0 : tll_foreach(db->repos, rit) {
# # ]
2880 [ # # ]: 0 : if (rit->item->ops->stat != NULL)
2881 : 0 : stats += rit->item->ops->stat(rit->item, type);
2882 : 0 : }
2883 : 0 : return (stats);
2884 : : break;
2885 : : case PKG_STATS_REMOTE_REPOS:
2886 : 0 : return (tll_length(db->repos));
2887 : : break;
2888 : : }
2889 : :
2890 : 0 : stmt = prepare_sql(db->sqlite, sql);
2891 [ # # ]: 0 : if (stmt == NULL)
2892 : 0 : return (-1);
2893 : :
2894 [ # # ]: 0 : while (sqlite3_step(stmt) != SQLITE_DONE) {
2895 : 0 : stats = sqlite3_column_int64(stmt, 0);
2896 : 0 : pkgdb_debug(4, stmt);
2897 : : }
2898 : :
2899 : 0 : sqlite3_finalize(stmt);
2900 : :
2901 : 0 : return (stats);
2902 : 0 : }
2903 : :
2904 : :
2905 : : int
2906 : 178 : pkgdb_begin_solver(struct pkgdb *db)
2907 : : {
2908 : 178 : const char solver_sql[] = ""
2909 : : "BEGIN TRANSACTION;";
2910 : 178 : const char update_digests_sql[] = ""
2911 : : "DROP INDEX IF EXISTS pkg_digest_id;"
2912 : : "BEGIN TRANSACTION;";
2913 : 178 : const char end_update_sql[] = ""
2914 : : "END TRANSACTION;"
2915 : : "CREATE INDEX pkg_digest_id ON packages(name, manifestdigest);";
2916 : : struct pkgdb_it *it;
2917 : 178 : struct pkg *p = NULL;
2918 : 178 : tll(struct pkg *) pkglist = tll_init();
2919 : 178 : int rc = EPKG_OK;
2920 : 178 : int64_t cnt = 0, cur = 0;
2921 : :
2922 : 178 : it = pkgdb_query_cond(db, " WHERE manifestdigest IS NULL OR manifestdigest==''",
2923 : : NULL, MATCH_ALL);
2924 [ + - ]: 178 : if (it != NULL) {
2925 [ + + ]: 224 : while (pkgdb_it_next(it, &p, PKG_LOAD_BASIC|PKG_LOAD_OPTIONS) == EPKG_OK) {
2926 : 46 : pkg_checksum_calculate(p, NULL, false, true, false);
2927 [ + + + + : 46 : tll_push_front(pkglist, p);
+ - - + +
+ ]
2928 : 46 : p = NULL;
2929 : 46 : cnt ++;
2930 : : }
2931 : 178 : pkgdb_it_free(it);
2932 : :
2933 [ + + ]: 178 : if (tll_length(pkglist) > 0) {
2934 : 28 : rc = sql_exec(db->sqlite, update_digests_sql);
2935 [ - + ]: 28 : if (rc != EPKG_OK) {
2936 : 0 : ERROR_SQLITE(db->sqlite, update_digests_sql);
2937 : 0 : }
2938 : : else {
2939 : 28 : pkg_emit_progress_start("Updating database digests format");
2940 [ + - + + : 74 : tll_foreach(pkglist, pit) {
+ + ]
2941 : 46 : p = pit->item;
2942 : 46 : pkg_emit_progress_tick(cur++, cnt);
2943 : 46 : rc = run_prstmt(UPDATE_DIGEST, p->digest, p->id);
2944 [ + - ]: 46 : if (rc != SQLITE_DONE) {
2945 : 0 : assert(0);
2946 : : ERROR_STMT_SQLITE(db->sqlite, STMT(UPDATE_DIGEST));
2947 : : }
2948 : 46 : }
2949 : :
2950 : 28 : pkg_emit_progress_tick(cnt, cnt);
2951 [ - + ]: 28 : if (rc == SQLITE_DONE)
2952 : 28 : rc = sql_exec(db->sqlite, end_update_sql);
2953 : :
2954 [ + - ]: 28 : if (rc != SQLITE_OK)
2955 : 0 : ERROR_SQLITE(db->sqlite, end_update_sql);
2956 : : }
2957 : 28 : }
2958 : :
2959 [ - + ]: 178 : if (rc == EPKG_OK)
2960 : 178 : rc = sql_exec(db->sqlite, solver_sql);
2961 : :
2962 [ + + + + : 224 : tll_free_and_free(pkglist, pkg_free);
+ + ]
2963 : 178 : } else {
2964 : 0 : rc = sql_exec(db->sqlite, solver_sql);
2965 : : }
2966 : :
2967 : 178 : return (rc);
2968 : : }
2969 : :
2970 : : int
2971 : 178 : pkgdb_end_solver(struct pkgdb *db)
2972 : : {
2973 : 178 : const char solver_sql[] = ""
2974 : : "END TRANSACTION;";
2975 : :
2976 : 178 : return (sql_exec(db->sqlite, solver_sql));
2977 : : }
2978 : :
2979 : : int
2980 : 9 : pkgdb_is_dir_used(struct pkgdb *db, struct pkg *p, const char *dir, int64_t *res)
2981 : : {
2982 : : sqlite3_stmt *stmt;
2983 : : int ret;
2984 : :
2985 : 9 : const char sql[] = ""
2986 : : "SELECT count(package_id) FROM pkg_directories, directories "
2987 : : "WHERE directory_id = directories.id AND directories.path = ?1 "
2988 : : "AND package_id != ?2;";
2989 : :
2990 : 9 : stmt = prepare_sql(db->sqlite, sql);
2991 [ + - ]: 9 : if (stmt == NULL)
2992 : 0 : return (EPKG_FATAL);
2993 : :
2994 : 9 : sqlite3_bind_text(stmt, 1, dir, -1, SQLITE_TRANSIENT);
2995 : 9 : sqlite3_bind_int64(stmt, 2, p->id);
2996 : :
2997 : 9 : ret = sqlite3_step(stmt);
2998 : :
2999 [ - + ]: 9 : if (ret == SQLITE_ROW)
3000 : 9 : *res = sqlite3_column_int64(stmt, 0);
3001 : :
3002 : 9 : sqlite3_finalize(stmt);
3003 : :
3004 [ - + ]: 9 : if (ret != SQLITE_ROW) {
3005 : 0 : ERROR_SQLITE(db->sqlite, sql);
3006 : 0 : return (EPKG_FATAL);
3007 : : }
3008 : :
3009 : 9 : return (EPKG_OK);
3010 : 9 : }
3011 : :
3012 : : void
3013 : 7966 : pkgdb_debug(int level, sqlite3_stmt *stmt)
3014 : : {
3015 : : char *str;
3016 : :
3017 [ + - ]: 7966 : if (ctx.debug_level < level)
3018 : 7966 : return;
3019 : :
3020 : 0 : str = sqlite3_expanded_sql(stmt);
3021 : 0 : dbg(level, "running: '%s'", str);
3022 : 0 : sqlite3_free(str);
3023 : 7966 : }
|