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