Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2023 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-2014 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-2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
11 : : * Copyright (c) 2023 Serenity Cyber Security, LLC
12 : : * Author: Gleb Popov <arrowd@FreeBSD.org>
13 : : * All rights reserved.
14 : : *
15 : : * Redistribution and use in source and binary forms, with or without
16 : : * modification, are permitted provided that the following conditions
17 : : * are met:
18 : : * 1. Redistributions of source code must retain the above copyright
19 : : * notice, this list of conditions and the following disclaimer
20 : : * in this position and unchanged.
21 : : * 2. Redistributions in binary form must reproduce the above copyright
22 : : * notice, this list of conditions and the following disclaimer in the
23 : : * documentation and/or other materials provided with the distribution.
24 : : *
25 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
26 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
29 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 : : */
36 : :
37 : : #ifdef HAVE_CONFIG_H
38 : : #include "pkg_config.h"
39 : : #endif
40 : :
41 : : #define dbg(x, ...) pkg_dbg(PKG_DBG_DATABASE, x, __VA_ARGS__)
42 : :
43 : : #include <assert.h>
44 : : #include <errno.h>
45 : : #include <regex.h>
46 : : #include <grp.h>
47 : : #ifdef HAVE_LIBUTIL_H
48 : : #include <libutil.h>
49 : : #endif
50 : : #include <stdlib.h>
51 : : #include <stdio.h>
52 : : #include <stdbool.h>
53 : : #include <string.h>
54 : : #include <unistd.h>
55 : : #include <signal.h>
56 : :
57 : : #include <sqlite3.h>
58 : :
59 : : #include <bsd_compat.h>
60 : :
61 : : #include "pkg.h"
62 : : #include "private/event.h"
63 : : #include "private/pkg.h"
64 : : #include "private/pkgdb.h"
65 : : #include "private/utils.h"
66 : : #include "private/pkg_deps.h"
67 : :
68 : : /*
69 : : * Keep entries sorted by name!
70 : : */
71 : : static struct column_mapping {
72 : : const char * const name;
73 : : pkg_attr type;
74 : : enum {
75 : : PKG_SQLITE_STRING,
76 : : PKG_SQLITE_INT64,
77 : : PKG_SQLITE_BOOL
78 : : } pkg_type;
79 : : } columns[] = {
80 : : { "arch", PKG_ATTR_ABI, PKG_SQLITE_STRING },
81 : : { "automatic", PKG_ATTR_AUTOMATIC, PKG_SQLITE_BOOL },
82 : : { "cksum", PKG_ATTR_CKSUM, PKG_SQLITE_STRING },
83 : : { "comment", PKG_ATTR_COMMENT, PKG_SQLITE_STRING },
84 : : { "dbname", PKG_ATTR_REPONAME, PKG_SQLITE_STRING },
85 : : { "dep_formula", PKG_ATTR_DEP_FORMULA, PKG_SQLITE_STRING },
86 : : { "desc", PKG_ATTR_DESC, PKG_SQLITE_STRING },
87 : : { "flatsize", PKG_ATTR_FLATSIZE, PKG_SQLITE_INT64 },
88 : : { "id", PKG_ATTR_ROWID, PKG_SQLITE_INT64 },
89 : : { "licenselogic", PKG_ATTR_LICENSE_LOGIC, PKG_SQLITE_INT64 },
90 : : { "locked", PKG_ATTR_LOCKED, PKG_SQLITE_BOOL },
91 : : { "maintainer", PKG_ATTR_MAINTAINER, PKG_SQLITE_STRING },
92 : : { "manifestdigest", PKG_ATTR_DIGEST, PKG_SQLITE_STRING },
93 : : { "message", PKG_ATTR_MESSAGE, PKG_SQLITE_STRING },
94 : : { "name", PKG_ATTR_NAME, PKG_SQLITE_STRING },
95 : : { "oldflatsize", PKG_ATTR_OLD_FLATSIZE, PKG_SQLITE_INT64 },
96 : : { "oldversion", PKG_ATTR_OLD_VERSION, PKG_SQLITE_STRING },
97 : : { "origin", PKG_ATTR_ORIGIN, PKG_SQLITE_STRING },
98 : : { "pkgsize", PKG_ATTR_PKGSIZE, PKG_SQLITE_INT64 },
99 : : { "prefix", PKG_ATTR_PREFIX, PKG_SQLITE_STRING },
100 : : { "repopath", PKG_ATTR_REPOPATH, PKG_SQLITE_STRING },
101 : : { "repourl", PKG_ATTR_REPOURL, PKG_SQLITE_STRING },
102 : : { "rowid", PKG_ATTR_ROWID, PKG_SQLITE_INT64 },
103 : : { "time", PKG_ATTR_TIME, PKG_SQLITE_INT64 },
104 : : { "uniqueid", PKG_ATTR_UNIQUEID, PKG_SQLITE_STRING },
105 : : { "version", PKG_ATTR_VERSION, PKG_SQLITE_STRING },
106 : : { "vital", PKG_ATTR_VITAL, PKG_SQLITE_BOOL },
107 : : { "weight", -1, PKG_SQLITE_INT64 },
108 : : { "www", PKG_ATTR_WWW, PKG_SQLITE_STRING },
109 : : { NULL, -1, PKG_SQLITE_STRING }
110 : : };
111 : :
112 : : static void
113 : 372 : remote_free(struct pkg_repo_it *it)
114 : : {
115 : 372 : it->ops->free(it);
116 : 372 : }
117 : :
118 : : static int
119 : 6 : pkg_addcategory(struct pkg *pkg, const char *data)
120 : : {
121 : 6 : return (pkg_addstring(&pkg->categories, data, "category"));
122 : : }
123 : :
124 : : static int
125 : 6 : pkg_addlicense(struct pkg *pkg, const char *data)
126 : : {
127 : 6 : return (pkg_addstring(&pkg->licenses, data, "license"));
128 : : }
129 : :
130 : : static int
131 : 653 : pkg_addannotation(struct pkg *pkg, const char *k, const char *v)
132 : : {
133 : 653 : return (pkg_kv_add(&pkg->annotations, k, v, "annotation"));
134 : : }
135 : :
136 : : static int
137 : 2227 : load_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
138 : : int (*pkg_adddata)(struct pkg *pkg, const char *data), int list)
139 : : {
140 : : sqlite3_stmt *stmt;
141 : : int ret;
142 : :
143 [ + - ]: 2227 : assert(db != NULL && pkg != NULL);
144 : :
145 [ - + ]: 2227 : if (pkg->flags & flags)
146 : 0 : return (EPKG_OK);
147 : :
148 [ - + ]: 2227 : if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
149 : 0 : ERROR_SQLITE(db, sql);
150 : 0 : return (EPKG_FATAL);
151 : : }
152 : :
153 : 2227 : sqlite3_bind_int64(stmt, 1, pkg->id);
154 : 2227 : pkgdb_debug(4, stmt);
155 [ + + ]: 2321 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
156 : 94 : pkg_adddata(pkg, sqlite3_column_text(stmt, 0));
157 : : }
158 : :
159 [ - + ]: 2227 : if (ret != SQLITE_DONE) {
160 [ # # ]: 0 : if (list != -1)
161 : 0 : pkg_list_free(pkg, list);
162 : 0 : ERROR_STMT_SQLITE(db, stmt);
163 : 0 : sqlite3_finalize(stmt);
164 : 0 : return (EPKG_FATAL);
165 : : }
166 : 2227 : sqlite3_finalize(stmt);
167 : :
168 : 2227 : pkg->flags |= flags;
169 : 2227 : return (EPKG_OK);
170 : 2227 : }
171 : :
172 : : static int
173 : 2046 : load_tag_val(sqlite3 *db, struct pkg *pkg, const char *sql, unsigned flags,
174 : : int (*pkg_addtagval)(struct pkg *pkg, const char *tag, const char *val),
175 : : int list)
176 : : {
177 : : sqlite3_stmt *stmt;
178 : : int ret;
179 : :
180 [ + - ]: 2046 : assert(db != NULL && pkg != NULL);
181 : :
182 [ + + ]: 2046 : if (pkg->flags & flags)
183 : 990 : return (EPKG_OK);
184 : :
185 [ - + ]: 1056 : if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
186 : 0 : ERROR_SQLITE(db, sql);
187 : 0 : return (EPKG_FATAL);
188 : : }
189 : :
190 : 1056 : sqlite3_bind_int64(stmt, 1, pkg->id);
191 : 1056 : pkgdb_debug(4, stmt);
192 : :
193 [ + + ]: 1759 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
194 : 1406 : pkg_addtagval(pkg, sqlite3_column_text(stmt, 0),
195 : 703 : sqlite3_column_text(stmt, 1));
196 : : }
197 : :
198 [ - + ]: 1056 : if (ret != SQLITE_DONE) {
199 [ # # ]: 0 : if (list != -1)
200 : 0 : pkg_list_free(pkg, list);
201 : 0 : ERROR_STMT_SQLITE(db, stmt);
202 : 0 : sqlite3_finalize(stmt);
203 : 0 : return (EPKG_FATAL);
204 : : }
205 : 1056 : sqlite3_finalize(stmt);
206 : :
207 : 1056 : pkg->flags |= flags;
208 : 1056 : return (EPKG_OK);
209 : 2046 : }
210 : :
211 : : static int
212 : 72480 : compare_column_func(const void *pkey, const void *pcolumn)
213 : : {
214 : 72480 : const char *key = (const char*)pkey;
215 : 72480 : const struct column_mapping *column =
216 : 72480 : (const struct column_mapping*)pcolumn;
217 : :
218 : 72480 : return strcmp(key, column->name);
219 : : }
220 : :
221 : : static int
222 : 478 : pkgdb_load_deps(sqlite3 *sqlite, struct pkg *pkg)
223 : : {
224 : 478 : sqlite3_stmt *stmt = NULL, *opt_stmt = NULL;
225 : 478 : int ret = EPKG_OK;
226 : 478 : struct pkg_dep *chain = NULL;
227 : : struct pkg_dep_formula *f;
228 : : struct pkg_dep_formula_item *fit;
229 : : struct pkg_dep_option_item *optit;
230 : : bool options_match;
231 : : char *formula_sql, *clause;
232 : 478 : const char sql[] = ""
233 : : "SELECT DISTINCT d.name, d.origin, p.version, 0"
234 : : " FROM deps AS d"
235 : : " LEFT JOIN packages AS p ON"
236 : : " (p.origin = d.origin AND p.name = d.name)"
237 : : " WHERE d.package_id = ?1"
238 : : " ORDER BY d.origin DESC";
239 : 478 : const char formula_preamble[] = ""
240 : : "SELECT id,name,origin,version,locked FROM packages WHERE ";
241 : 478 : const char options_sql[] = ""
242 : : "SELECT option, value"
243 : : " FROM option"
244 : : " JOIN pkg_option USING(option_id)"
245 : : " WHERE package_id = ?1"
246 : : " ORDER BY option";
247 : :
248 [ + - ]: 478 : assert(pkg != NULL);
249 : :
250 [ - + ]: 478 : if (pkg->flags & PKG_LOAD_DEPS)
251 : 0 : return (EPKG_OK);
252 : :
253 : :
254 : 478 : ret = sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL);
255 : :
256 [ - + ]: 478 : if (ret != SQLITE_OK) {
257 : 0 : ERROR_SQLITE(sqlite, sql);
258 : 0 : return (EPKG_FATAL);
259 : : }
260 : :
261 : 478 : sqlite3_bind_int64(stmt, 1, pkg->id);
262 : 478 : pkgdb_debug(4, stmt);
263 : :
264 : : /* XXX: why we used locked here ? */
265 [ + + ]: 658 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
266 : 360 : pkg_adddep(pkg, sqlite3_column_text(stmt, 0),
267 : 180 : sqlite3_column_text(stmt, 1),
268 : 180 : sqlite3_column_text(stmt, 2),
269 : 180 : sqlite3_column_int64(stmt, 3));
270 : : }
271 : :
272 [ - + ]: 478 : if (ret != SQLITE_DONE) {
273 : 0 : pkg_list_free(pkg, PKG_DEPS);
274 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
275 : 0 : sqlite3_finalize(stmt);
276 : 0 : return (EPKG_FATAL);
277 : : }
278 : 478 : sqlite3_finalize(stmt);
279 : :
280 [ + - ]: 478 : if (pkg->dep_formula) {
281 : 0 : dbg(4, "Pkgdb: reading package formula '%s'", pkg->dep_formula);
282 : :
283 : 0 : f = pkg_deps_parse_formula (pkg->dep_formula);
284 : :
285 [ # # ]: 0 : if (f != NULL) {
286 [ # # ]: 0 : DL_FOREACH(f->items, fit) {
287 : 0 : clause = pkg_deps_formula_tosql(fit);
288 : :
289 [ # # ]: 0 : if (clause) {
290 : 0 : xasprintf(&formula_sql, "%s%s", formula_preamble, clause);
291 : 0 : ret = sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL);
292 [ # # ]: 0 : if (ret != SQLITE_OK) {
293 : 0 : ERROR_SQLITE(sqlite, sql);
294 : 0 : free(clause);
295 : 0 : free(formula_sql);
296 : 0 : pkg_deps_formula_free(f);
297 : 0 : return (EPKG_FATAL);
298 : : }
299 : 0 : pkgdb_debug(4, stmt);
300 : :
301 : : /* Fetch matching packages */
302 : 0 : chain = NULL;
303 : :
304 [ # # ]: 0 : while (sqlite3_step(stmt) == SQLITE_ROW) {
305 : : /*
306 : : * Load options for a package and check
307 : : * if they are compatible
308 : : */
309 : 0 : options_match = true;
310 : :
311 [ # # ]: 0 : if (fit->options) {
312 [ # # # # ]: 0 : if (sqlite3_prepare_v2(sqlite, options_sql, -1,
313 : 0 : &opt_stmt, NULL) != SQLITE_OK) {
314 : 0 : ERROR_SQLITE(sqlite, options_sql);
315 : 0 : return (EPKG_FATAL);
316 : : }
317 : 0 : pkgdb_debug(4, opt_stmt);
318 : :
319 : 0 : sqlite3_bind_int64(opt_stmt, 1,
320 : 0 : sqlite3_column_int64(stmt, 0));
321 : :
322 [ # # ]: 0 : while (sqlite3_step(opt_stmt) == SQLITE_ROW) {
323 [ # # ]: 0 : DL_FOREACH(fit->options, optit) {
324 [ # # ]: 0 : if(STREQ(optit->opt, sqlite3_column_text(opt_stmt, 0))) {
325 [ # # # # ]: 0 : if ((!STREQ(sqlite3_column_text(opt_stmt, 1), "on") && !optit->on)
326 [ # # # # ]: 0 : || (!STREQ(sqlite3_column_text(opt_stmt, 1), "off") && optit->on)) {
327 : 0 : dbg(4, "incompatible option for"
328 : : "%s: %s",
329 : : sqlite3_column_text(opt_stmt, 1),
330 : : optit->opt);
331 : 0 : options_match = false;
332 : 0 : break;
333 : : }
334 : 0 : }
335 : 0 : }
336 : : }
337 : :
338 : 0 : sqlite3_finalize(opt_stmt);
339 : 0 : }
340 : :
341 [ # # ]: 0 : if (options_match) {
342 : 0 : chain = pkg_adddep_chain(chain, pkg,
343 : 0 : sqlite3_column_text(stmt, 1),
344 : 0 : sqlite3_column_text(stmt, 2),
345 : 0 : sqlite3_column_text(stmt, 3),
346 : 0 : sqlite3_column_int64(stmt, 4));
347 : 0 : }
348 : : }
349 : :
350 : 0 : free(clause);
351 : 0 : free(formula_sql);
352 : 0 : sqlite3_finalize(stmt);
353 : 0 : }
354 : :
355 : 0 : }
356 : :
357 : 0 : pkg_deps_formula_free(f);
358 : 0 : }
359 : 0 : }
360 : :
361 : 478 : pkg->flags |= PKG_LOAD_DEPS;
362 : 478 : return (EPKG_OK);
363 : 478 : }
364 : :
365 : : static int
366 : 127 : pkgdb_load_rdeps(sqlite3 *sqlite, struct pkg *pkg)
367 : : {
368 : 127 : sqlite3_stmt *stmt = NULL;
369 : : int ret;
370 : 127 : const char sql[] = ""
371 : : "SELECT p.name, p.origin, p.version, 0"
372 : : " FROM packages AS p"
373 : : " INNER JOIN deps AS d ON (p.id = d.package_id)"
374 : : " WHERE d.name = ?1";
375 : :
376 [ + - ]: 127 : assert(pkg != NULL);
377 : :
378 [ - + ]: 127 : if (pkg->flags & PKG_LOAD_RDEPS)
379 : 0 : return (EPKG_OK);
380 : :
381 : :
382 : 127 : ret = sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL);
383 : :
384 [ - + ]: 127 : if (ret != SQLITE_OK) {
385 : 0 : ERROR_SQLITE(sqlite, sql);
386 : 0 : return (EPKG_FATAL);
387 : : }
388 : :
389 : 127 : sqlite3_bind_text(stmt, 1, pkg->uid, -1, SQLITE_STATIC);
390 : 127 : pkgdb_debug(4, stmt);
391 : :
392 : : /* XXX: why we used locked here ? */
393 [ + + ]: 161 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
394 : 68 : pkg_addrdep(pkg, sqlite3_column_text(stmt, 0),
395 : 34 : sqlite3_column_text(stmt, 1),
396 : 34 : sqlite3_column_text(stmt, 2),
397 : 34 : sqlite3_column_int64(stmt, 3));
398 : : }
399 : :
400 [ - + ]: 127 : if (ret != SQLITE_DONE) {
401 : 0 : pkg_list_free(pkg, PKG_RDEPS);
402 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
403 : 0 : sqlite3_finalize(stmt);
404 : 0 : return (EPKG_FATAL);
405 : : }
406 : 127 : sqlite3_finalize(stmt);
407 : :
408 : 127 : pkg->flags |= PKG_LOAD_RDEPS;
409 : 127 : return (EPKG_OK);
410 : 127 : }
411 : :
412 : : static int
413 : 93 : pkgdb_load_files(sqlite3 *sqlite, struct pkg *pkg)
414 : : {
415 : 93 : sqlite3_stmt *stmt = NULL;
416 : : int ret;
417 : 93 : const char sql[] = ""
418 : : "SELECT path, sha256"
419 : : " FROM files"
420 : : " WHERE package_id = ?1"
421 : : " ORDER BY PATH ASC";
422 : 93 : const char sql2[] = ""
423 : : "SELECT path, content"
424 : : " FROM config_files"
425 : : " WHERE package_id = ?1"
426 : : " ORDER BY PATH ASC";
427 : :
428 [ + - ]: 93 : assert( pkg != NULL);
429 [ + - ]: 93 : assert(pkg->type == PKG_INSTALLED);
430 : :
431 [ - + ]: 93 : if (pkg->flags & PKG_LOAD_FILES)
432 : 0 : return (EPKG_OK);
433 : :
434 [ - + ]: 93 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
435 : 0 : ERROR_SQLITE(sqlite, sql);
436 : 0 : return (EPKG_FATAL);
437 : : }
438 : :
439 : 93 : sqlite3_bind_int64(stmt, 1, pkg->id);
440 : 93 : pkgdb_debug(4, stmt);
441 : :
442 [ + + ]: 169 : while (sqlite3_step(stmt) == SQLITE_ROW) {
443 : 152 : pkg_addfile(pkg, sqlite3_column_text(stmt, 0),
444 : 76 : sqlite3_column_text(stmt, 1), false);
445 : : }
446 : 93 : sqlite3_finalize(stmt);
447 : :
448 [ - + ]: 93 : if (sqlite3_prepare_v2(sqlite, sql2, -1, &stmt, NULL) != SQLITE_OK) {
449 : 0 : ERROR_SQLITE(sqlite, sql2);
450 : 0 : return (EPKG_FATAL);
451 : : }
452 : :
453 : 93 : sqlite3_bind_int64(stmt, 1, pkg->id);
454 : 93 : pkgdb_debug(4, stmt);
455 : :
456 [ + + ]: 97 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
457 : 8 : pkg_addconfig_file(pkg, sqlite3_column_text(stmt, 0),
458 : 4 : sqlite3_column_text(stmt, 1));
459 : : }
460 : :
461 [ - + ]: 93 : if (ret != SQLITE_DONE) {
462 : 0 : pkg_list_free(pkg, PKG_FILES);
463 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
464 : 0 : sqlite3_finalize(stmt);
465 : 0 : return (EPKG_FATAL);
466 : : }
467 : 93 : sqlite3_finalize(stmt);
468 : :
469 : 93 : pkg->flags |= PKG_LOAD_FILES;
470 : 93 : return (EPKG_OK);
471 : 93 : }
472 : :
473 : : static int
474 : 90 : pkgdb_load_dirs(sqlite3 *sqlite, struct pkg *pkg)
475 : : {
476 : 90 : const char sql[] = ""
477 : : "SELECT path, try"
478 : : " FROM pkg_directories, directories"
479 : : " WHERE package_id = ?1"
480 : : " AND directory_id = directories.id"
481 : : " ORDER by path DESC";
482 : : sqlite3_stmt *stmt;
483 : : int ret;
484 : :
485 [ + - ]: 90 : assert(pkg != NULL);
486 [ + - ]: 90 : assert(pkg->type == PKG_INSTALLED);
487 : :
488 [ - + ]: 90 : if (pkg->flags & PKG_LOAD_DIRS)
489 : 0 : return (EPKG_OK);
490 : :
491 [ - + ]: 90 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
492 : 0 : ERROR_SQLITE(sqlite, sql);
493 : 0 : return (EPKG_FATAL);
494 : : }
495 : :
496 : 90 : sqlite3_bind_int64(stmt, 1, pkg->id);
497 : 90 : pkgdb_debug(4, stmt);
498 : :
499 [ + + ]: 91 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
500 : 1 : pkg_adddir(pkg, sqlite3_column_text(stmt, 0), false);
501 : : }
502 : :
503 [ - + ]: 90 : if (ret != SQLITE_DONE) {
504 : 0 : pkg_list_free(pkg, PKG_DIRS);
505 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
506 : 0 : sqlite3_finalize(stmt);
507 : 0 : return (EPKG_FATAL);
508 : : }
509 : 90 : sqlite3_finalize(stmt);
510 : :
511 : 90 : pkg->flags |= PKG_LOAD_DIRS;
512 : :
513 : 90 : return (EPKG_OK);
514 : 90 : }
515 : :
516 : : static int
517 : 6 : pkgdb_load_license(sqlite3 *sqlite, struct pkg *pkg)
518 : : {
519 : 6 : const char sql[] = ""
520 : : "SELECT ifnull(group_concat(name, ', '), '') AS name"
521 : : " FROM pkg_licenses, licenses AS l"
522 : : " WHERE package_id = ?1"
523 : : " AND license_id = l.id"
524 : : " ORDER by name DESC";
525 : :
526 [ + - ]: 6 : assert(pkg != NULL);
527 : :
528 : 6 : return (load_val(sqlite, pkg, sql, PKG_LOAD_LICENSES,
529 : : pkg_addlicense, PKG_ATTR_LICENSES));
530 : : }
531 : :
532 : : static int
533 : 6 : pkgdb_load_category(sqlite3 *sqlite, struct pkg *pkg)
534 : : {
535 : 6 : const char sql[] = ""
536 : : "SELECT name"
537 : : " FROM pkg_categories, categories AS c"
538 : : " WHERE package_id = ?1"
539 : : " AND category_id = c.id"
540 : : " ORDER by name DESC";
541 : :
542 [ + - ]: 6 : assert(pkg != NULL);
543 : :
544 : 6 : return (load_val(sqlite, pkg, sql, PKG_LOAD_CATEGORIES,
545 : : pkg_addcategory, PKG_ATTR_CATEGORIES));
546 : : }
547 : :
548 : : static int
549 : 0 : pkgdb_load_user(sqlite3 *sqlite, struct pkg *pkg)
550 : : {
551 : : int ret;
552 : 0 : const char sql[] = ""
553 : : "SELECT users.name"
554 : : " FROM pkg_users, users"
555 : : " WHERE package_id = ?1"
556 : : " AND user_id = users.id"
557 : : " ORDER by name DESC";
558 : :
559 [ # # ]: 0 : assert(pkg != NULL);
560 [ # # ]: 0 : assert(pkg->type == PKG_INSTALLED);
561 : :
562 : 0 : ret = load_val(sqlite, pkg, sql, PKG_LOAD_USERS,
563 : : pkg_adduser, PKG_ATTR_USERS);
564 : :
565 : 0 : return (ret);
566 : : }
567 : :
568 : : static int
569 : 0 : pkgdb_load_group(sqlite3 *sqlite, struct pkg *pkg)
570 : : {
571 : : int ret;
572 : 0 : const char sql[] = ""
573 : : "SELECT groups.name"
574 : : " FROM pkg_groups, groups"
575 : : " WHERE package_id = ?1"
576 : : " AND group_id = groups.id"
577 : : " ORDER by name DESC";
578 : :
579 [ # # ]: 0 : assert(pkg != NULL);
580 [ # # ]: 0 : assert(pkg->type == PKG_INSTALLED);
581 : :
582 : 0 : ret = load_val(sqlite, pkg, sql, PKG_LOAD_GROUPS,
583 : : pkg_addgroup, PKG_ATTR_GROUPS);
584 : :
585 : 0 : return (ret);
586 : : }
587 : :
588 : : static int
589 : 29 : addshlib_required_raw(struct pkg *pkg, const char *name)
590 : : {
591 [ + + + + : 29 : tll_push_back(pkg->shlibs_required, xstrdup(name));
+ - - + +
+ ]
592 : 29 : return (EPKG_OK);
593 : : }
594 : :
595 : : static int
596 : 448 : pkgdb_load_shlib_required(sqlite3 *sqlite, struct pkg *pkg)
597 : : {
598 : 448 : const char sql[] = ""
599 : : "SELECT name"
600 : : " FROM pkg_shlibs_required, shlibs AS s"
601 : : " WHERE package_id = ?1"
602 : : " AND shlib_id = s.id"
603 : : " ORDER by name DESC";
604 : :
605 [ + - ]: 448 : assert(pkg != NULL);
606 : :
607 : 448 : return (load_val(sqlite, pkg, sql, PKG_LOAD_SHLIBS_REQUIRED,
608 : : addshlib_required_raw, PKG_ATTR_SHLIBS_REQUIRED));
609 : : }
610 : :
611 : : static int
612 : 10 : addshlib_provided_raw(struct pkg *pkg, const char *name)
613 : : {
614 [ - + + - : 10 : tll_push_back(pkg->shlibs_provided, xstrdup(name));
# # - + -
+ ]
615 : 10 : return (EPKG_OK);
616 : : }
617 : :
618 : : static int
619 : 439 : pkgdb_load_shlib_provided(sqlite3 *sqlite, struct pkg *pkg)
620 : : {
621 : 439 : const char sql[] = ""
622 : : "SELECT name"
623 : : " FROM pkg_shlibs_provided, shlibs AS s"
624 : : " WHERE package_id = ?1"
625 : : " AND shlib_id = s.id"
626 : : " ORDER by name DESC";
627 : :
628 [ + - ]: 439 : assert(pkg != NULL);
629 : :
630 : 439 : return (load_val(sqlite, pkg, sql, PKG_LOAD_SHLIBS_PROVIDED,
631 : : addshlib_provided_raw, PKG_SHLIBS_PROVIDED));
632 : : }
633 : :
634 : : static int
635 : 561 : pkgdb_load_annotations(sqlite3 *sqlite, struct pkg *pkg)
636 : : {
637 : 561 : const char sql[] = ""
638 : : "SELECT k.annotation AS tag, v.annotation AS value"
639 : : " FROM pkg_annotation p"
640 : : " JOIN annotation k ON (p.tag_id = k.annotation_id)"
641 : : " JOIN annotation v ON (p.value_id = v.annotation_id)"
642 : : " WHERE p.package_id = ?1"
643 : : " ORDER BY tag, value";
644 : :
645 : 561 : return (load_tag_val(sqlite, pkg, sql, PKG_LOAD_ANNOTATIONS,
646 : : pkg_addannotation, PKG_ATTR_ANNOTATIONS));
647 : : }
648 : :
649 : : static int
650 : 77 : pkgdb_load_lua_scripts(sqlite3 *sqlite, struct pkg *pkg)
651 : : {
652 : 77 : sqlite3_stmt *stmt = NULL;
653 : : int ret;
654 : 77 : const char sql[] = ""
655 : : "SELECT lua_script, type"
656 : : " FROM lua_script"
657 : : " JOIN pkg_lua_script USING(lua_script_id)"
658 : : " WHERE package_id = ?1";
659 : :
660 [ + - ]: 77 : assert(pkg != NULL);
661 [ + - ]: 77 : assert(pkg->type == PKG_INSTALLED);
662 : :
663 [ - + ]: 77 : if (pkg->flags & PKG_LOAD_LUA_SCRIPTS)
664 : 0 : return (EPKG_OK);
665 : :
666 [ - + ]: 77 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
667 : 0 : ERROR_SQLITE(sqlite, sql);
668 : 0 : return (EPKG_FATAL);
669 : : }
670 : :
671 : 77 : sqlite3_bind_int64(stmt, 1, pkg->id);
672 : :
673 : 77 : pkgdb_debug(4, stmt);
674 : :
675 [ + + ]: 80 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
676 : 6 : pkg_add_lua_script(pkg, sqlite3_column_text(stmt, 0),
677 : 3 : sqlite3_column_int64(stmt, 1));
678 : : }
679 : :
680 [ - + ]: 77 : if (ret != SQLITE_DONE) {
681 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
682 : 0 : sqlite3_finalize(stmt);
683 : 0 : return (EPKG_FATAL);
684 : : }
685 : 77 : sqlite3_finalize(stmt);
686 : :
687 : 77 : pkg->flags |= PKG_LOAD_LUA_SCRIPTS;
688 : 77 : return (EPKG_OK);
689 : 77 : }
690 : :
691 : : static int
692 : 77 : pkgdb_load_scripts(sqlite3 *sqlite, struct pkg *pkg)
693 : : {
694 : 77 : sqlite3_stmt *stmt = NULL;
695 : : int ret;
696 : 77 : const char sql[] = ""
697 : : "SELECT script, type"
698 : : " FROM pkg_script"
699 : : " JOIN script USING(script_id)"
700 : : " WHERE package_id = ?1";
701 : :
702 [ + - ]: 77 : assert(pkg != NULL);
703 [ + - ]: 77 : assert(pkg->type == PKG_INSTALLED);
704 : :
705 [ - + ]: 77 : if (pkg->flags & PKG_LOAD_SCRIPTS)
706 : 0 : return (EPKG_OK);
707 : :
708 [ - + ]: 77 : if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
709 : 0 : ERROR_SQLITE(sqlite, sql);
710 : 0 : return (EPKG_FATAL);
711 : : }
712 : :
713 : 77 : sqlite3_bind_int64(stmt, 1, pkg->id);
714 : 77 : pkgdb_debug(4, stmt);
715 : :
716 [ + + ]: 80 : while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
717 : 6 : pkg_addscript(pkg, sqlite3_column_text(stmt, 0),
718 : 3 : sqlite3_column_int64(stmt, 1));
719 : : }
720 : :
721 [ - + ]: 77 : if (ret != SQLITE_DONE) {
722 : 0 : ERROR_STMT_SQLITE(sqlite, stmt);
723 : 0 : sqlite3_finalize(stmt);
724 : 0 : return (EPKG_FATAL);
725 : : }
726 : 77 : sqlite3_finalize(stmt);
727 : :
728 : 77 : pkg->flags |= PKG_LOAD_SCRIPTS;
729 : 77 : return (EPKG_OK);
730 : 77 : }
731 : :
732 : :
733 : : static int
734 : 495 : pkgdb_load_options(sqlite3 *sqlite, struct pkg *pkg)
735 : : {
736 : : unsigned int i;
737 : :
738 : : struct optionsql {
739 : : const char *sql;
740 : : int (*pkg_addtagval)(struct pkg *pkg,
741 : : const char *tag,
742 : : const char *val);
743 : 495 : } optionsql[] = {
744 : : {
745 : : "SELECT option, value"
746 : : " FROM option"
747 : : " JOIN pkg_option USING(option_id)"
748 : : " WHERE package_id = ?1"
749 : : " ORDER BY option",
750 : : pkg_addoption,
751 : : },
752 : : {
753 : : "SELECT option, default_value"
754 : : " FROM option"
755 : : " JOIN pkg_option_default USING(option_id)"
756 : : " WHERE package_id = ?1"
757 : : " ORDER BY option",
758 : : pkg_addoption_default,
759 : : },
760 : : {
761 : : "SELECT option, description"
762 : : " FROM option"
763 : : " JOIN pkg_option_desc USING(option_id)"
764 : : " JOIN option_desc USING(option_desc_id)"
765 : : " WHERE package_id = ?1"
766 : : " ORDER BY option",
767 : : pkg_addoption_description,
768 : : }
769 : : };
770 : : const char *opt_sql;
771 : : int (*pkg_addtagval)(struct pkg *pkg,
772 : : const char *tag,
773 : : const char *val);
774 : : int ret;
775 : :
776 [ + - ]: 495 : assert(pkg != NULL);
777 : :
778 [ - + ]: 495 : if (pkg->flags & PKG_LOAD_OPTIONS)
779 : 0 : return (EPKG_OK);
780 : :
781 : :
782 [ + + ]: 1980 : for (i = 0; i < NELEM(optionsql); i++) {
783 : 1485 : opt_sql = optionsql[i].sql;
784 : 1485 : pkg_addtagval = optionsql[i].pkg_addtagval;
785 : :
786 : 1485 : dbg(4, "adding option");
787 : 2970 : ret = load_tag_val(sqlite, pkg, opt_sql, PKG_LOAD_OPTIONS,
788 : 1485 : pkg_addtagval, PKG_OPTIONS);
789 [ - + ]: 1485 : if (ret != EPKG_OK)
790 : 0 : break;
791 : 1485 : }
792 : 495 : return (ret);
793 : 495 : }
794 : :
795 : : static int
796 : 441 : pkgdb_load_conflicts(sqlite3 *sqlite, struct pkg *pkg)
797 : : {
798 : 441 : const char sql[] = ""
799 : : "SELECT packages.name"
800 : : " FROM pkg_conflicts"
801 : : " LEFT JOIN packages ON"
802 : : " (packages.id = pkg_conflicts.conflict_id)"
803 : : " WHERE package_id = ?1";
804 : :
805 [ + - ]: 441 : assert(pkg != NULL);
806 : :
807 : 441 : return (load_val(sqlite, pkg, sql, PKG_LOAD_CONFLICTS,
808 : : pkg_addconflict, PKG_ATTR_CONFLICTS));
809 : : }
810 : :
811 : : static int
812 : 439 : pkgdb_load_provides(sqlite3 *sqlite, struct pkg *pkg)
813 : : {
814 : 439 : const char sql[] = ""
815 : : "SELECT provide"
816 : : " FROM pkg_provides, provides AS s"
817 : : " WHERE package_id = ?1"
818 : : " AND provide_id = s.id"
819 : : " ORDER by provide DESC";
820 : :
821 [ + - ]: 439 : assert(pkg != NULL);
822 : :
823 : 439 : return (load_val(sqlite, pkg, sql, PKG_LOAD_PROVIDES,
824 : : pkg_addprovide, PKG_ATTR_PROVIDES));
825 : : }
826 : :
827 : : static int
828 : 448 : pkgdb_load_requires(sqlite3 *sqlite, struct pkg *pkg)
829 : : {
830 : 448 : const char sql[] = ""
831 : : "SELECT require"
832 : : " FROM pkg_requires, requires AS s"
833 : : " WHERE package_id = ?1"
834 : : " AND require_id = s.id"
835 : : " ORDER by require DESC";
836 : :
837 [ + - ]: 448 : assert(pkg != NULL);
838 : :
839 : 448 : return (load_val(sqlite, pkg, sql, PKG_LOAD_REQUIRES,
840 : : pkg_addrequire, PKG_REQUIRES));
841 : : }
842 : :
843 : : static void
844 : 1005 : populate_pkg(sqlite3_stmt *stmt, struct pkg *pkg) {
845 : 1005 : int icol = 0;
846 : : const char *colname, *msg;
847 : : char legacyarch[BUFSIZ];
848 : :
849 [ + - ]: 1005 : assert(stmt != NULL);
850 : :
851 [ + + ]: 19480 : for (icol = 0; icol < sqlite3_column_count(stmt); icol++) {
852 : 18475 : colname = sqlite3_column_name(stmt, icol);
853 : : struct column_mapping *column;
854 [ - - - + : 18475 : switch (sqlite3_column_type(stmt, icol)) {
+ + ]
855 : : case SQLITE_TEXT:
856 : 12590 : column = bsearch(colname, columns,
857 : : NELEM(columns) - 1,
858 : : sizeof(columns[0]),
859 : : compare_column_func);
860 [ + - ]: 12590 : if (column == NULL) {
861 : 0 : pkg_emit_error("unknown column %s", colname);
862 : 0 : continue;
863 : : }
864 : :
865 [ + + + + : 12590 : switch (column->type) {
+ + + + +
+ + + + +
+ - + -
- ]
866 : : case PKG_ATTR_ABI:
867 : 1005 : free(pkg->abi);
868 : 1005 : pkg->abi = xstrdup(sqlite3_column_text(stmt, icol));
869 : 1005 : break;
870 : : case PKG_ATTR_CKSUM:
871 : 561 : free(pkg->sum);
872 : 561 : pkg->sum = xstrdup(sqlite3_column_text(stmt, icol));
873 : 561 : break;
874 : : case PKG_ATTR_COMMENT:
875 : 1005 : free(pkg->comment);
876 : 1005 : pkg->comment = xstrdup(sqlite3_column_text(stmt, icol));
877 : 1005 : break;
878 : : case PKG_ATTR_REPONAME:
879 : 561 : free(pkg->reponame);
880 : 561 : pkg->reponame = xstrdup(sqlite3_column_text(stmt, icol));
881 : 561 : break;
882 : : case PKG_ATTR_DESC:
883 : 1005 : free(pkg->desc);
884 : 1005 : pkg->desc = xstrdup(sqlite3_column_text(stmt, icol));
885 : 1005 : break;
886 : : case PKG_ATTR_MAINTAINER:
887 : 1005 : free(pkg->maintainer);
888 : 1005 : pkg->maintainer = xstrdup(sqlite3_column_text(stmt, icol));
889 : 1005 : break;
890 : : case PKG_ATTR_DIGEST:
891 : 842 : free(pkg->digest);
892 : 842 : pkg->digest = xstrdup(sqlite3_column_text(stmt, icol));
893 : 842 : break;
894 : : case PKG_ATTR_MESSAGE:
895 : 15 : msg = sqlite3_column_text(stmt, icol);
896 [ - + ]: 15 : if (msg) {
897 : : /* A stupid logic to detect legacy pkg message */
898 [ + - ]: 15 : if (msg[0] == '[') {
899 : 15 : pkg_message_from_str(pkg, msg, 0);
900 : 15 : }
901 : : else {
902 : : struct pkg_message *message;
903 : 0 : message = xcalloc(1, sizeof(*message));
904 : 0 : message->str = xstrdup(msg);
905 [ # # # # : 0 : tll_push_back(pkg->message, message);
# # # # #
# ]
906 : : }
907 : 15 : }
908 : 15 : break;
909 : : case PKG_ATTR_NAME:
910 : 1005 : free(pkg->name);
911 : 1005 : pkg->name = xstrdup(sqlite3_column_text(stmt, icol));
912 : 1005 : break;
913 : : case PKG_ATTR_OLD_VERSION:
914 : 0 : free(pkg->old_version);
915 : 0 : pkg->old_version = xstrdup(sqlite3_column_text(stmt, icol));
916 : 0 : break;
917 : : case PKG_ATTR_ORIGIN:
918 : 1005 : free(pkg->origin);
919 : 1005 : pkg->origin = xstrdup(sqlite3_column_text(stmt, icol));
920 : 1005 : break;
921 : : case PKG_ATTR_PREFIX:
922 : 1005 : free(pkg->prefix);
923 : 1005 : pkg->prefix = xstrdup(sqlite3_column_text(stmt, icol));
924 : 1005 : break;
925 : : case PKG_ATTR_REPOPATH:
926 : 561 : free(pkg->repopath);
927 : 561 : pkg->repopath = xstrdup(sqlite3_column_text(stmt, icol));
928 : 561 : break;
929 : : case PKG_ATTR_REPOURL:
930 : 14 : free(pkg->repourl);
931 : 14 : pkg->repourl = xstrdup(sqlite3_column_text(stmt, icol));
932 : 14 : break;
933 : : case PKG_ATTR_UNIQUEID:
934 : 991 : free(pkg->uid);
935 : 991 : pkg->uid = xstrdup(sqlite3_column_text(stmt, icol));
936 : 991 : break;
937 : : case PKG_ATTR_VERSION:
938 : 1005 : free(pkg->version);
939 : 1005 : pkg->version = xstrdup(sqlite3_column_text(stmt, icol));
940 : 1005 : break;
941 : : case PKG_ATTR_WWW:
942 : 1005 : free(pkg->www);
943 : 1005 : pkg->www = xstrdup(sqlite3_column_text(stmt, icol));
944 : 1005 : break;
945 : : case PKG_ATTR_DEP_FORMULA:
946 : 0 : free(pkg->dep_formula);
947 : 0 : pkg->dep_formula = xstrdup(sqlite3_column_text(stmt, icol));
948 : 0 : break;
949 : : default:
950 : 0 : pkg_emit_error("Unexpected text value for %s", colname);
951 : 0 : break;
952 : : }
953 : 12590 : break;
954 : : case SQLITE_INTEGER:
955 : 5316 : column = bsearch(colname, columns,
956 : : NELEM(columns) - 1,
957 : : sizeof(columns[0]),
958 : : compare_column_func);
959 [ + - ]: 5316 : if (column == NULL) {
960 : 0 : pkg_emit_error("Unknown column %s", colname);
961 : 0 : continue;
962 : : }
963 : :
964 [ + - + + : 5316 : switch (column->type) {
+ + - + +
+ ]
965 : : case PKG_ATTR_AUTOMATIC:
966 : 435 : pkg->automatic = (bool)sqlite3_column_int64(stmt, icol);
967 : 435 : break;
968 : : case PKG_ATTR_LOCKED:
969 : 435 : pkg->locked = (bool)sqlite3_column_int64(stmt, icol);
970 : 435 : break;
971 : : case PKG_ATTR_FLATSIZE:
972 : 1005 : pkg->flatsize = sqlite3_column_int64(stmt, icol);
973 : 1005 : break;
974 : : case PKG_ATTR_ROWID:
975 : 1005 : pkg->id = sqlite3_column_int64(stmt, icol);
976 : 1005 : break;
977 : : case PKG_ATTR_LICENSE_LOGIC:
978 : 996 : pkg->licenselogic = (lic_t)sqlite3_column_int64(stmt, icol);
979 : 996 : break;
980 : : case PKG_ATTR_OLD_FLATSIZE:
981 : 0 : pkg->old_flatsize = sqlite3_column_int64(stmt, icol);
982 : 0 : break;
983 : : case PKG_ATTR_PKGSIZE:
984 : 561 : pkg->pkgsize = sqlite3_column_int64(stmt, icol);
985 : 561 : break;
986 : : case PKG_ATTR_VITAL:
987 : 435 : pkg->vital = (bool)sqlite3_column_int64(stmt, icol);
988 : 435 : break;
989 : : case PKG_ATTR_TIME:
990 : 444 : pkg->timestamp = sqlite3_column_int64(stmt, icol);
991 : 444 : break;
992 : : default:
993 : 0 : pkg_emit_error("Unexpected integer value for %s", colname);
994 : 0 : break;
995 : : }
996 : 5316 : break;
997 : : case SQLITE_BLOB:
998 : : case SQLITE_FLOAT:
999 : 0 : pkg_emit_error("wrong type for column: %s",
1000 : 0 : colname);
1001 : : /* just ignore currently */
1002 : 0 : break;
1003 : : case SQLITE_NULL:
1004 : 569 : break;
1005 : : }
1006 : 18475 : }
1007 : :
1008 : 1005 : pkg_arch_to_legacy(pkg->abi, legacyarch, BUFSIZ);
1009 : 1005 : pkg->altabi = xstrdup(legacyarch);
1010 : 1005 : }
1011 : :
1012 : : static struct load_on_flag {
1013 : : int flag;
1014 : : int (*load)(sqlite3 *sqlite, struct pkg *p);
1015 : : } load_on_flag[] = {
1016 : : { PKG_LOAD_DEPS, pkgdb_load_deps },
1017 : : { PKG_LOAD_RDEPS, pkgdb_load_rdeps },
1018 : : { PKG_LOAD_FILES, pkgdb_load_files },
1019 : : { PKG_LOAD_DIRS, pkgdb_load_dirs },
1020 : : { PKG_LOAD_SCRIPTS, pkgdb_load_scripts },
1021 : : { PKG_LOAD_OPTIONS, pkgdb_load_options },
1022 : : { PKG_LOAD_CATEGORIES, pkgdb_load_category },
1023 : : { PKG_LOAD_LICENSES, pkgdb_load_license },
1024 : : { PKG_LOAD_USERS, pkgdb_load_user },
1025 : : { PKG_LOAD_GROUPS, pkgdb_load_group },
1026 : : { PKG_LOAD_SHLIBS_REQUIRED, pkgdb_load_shlib_required },
1027 : : { PKG_LOAD_SHLIBS_PROVIDED, pkgdb_load_shlib_provided },
1028 : : { PKG_LOAD_ANNOTATIONS, pkgdb_load_annotations },
1029 : : { PKG_LOAD_CONFLICTS, pkgdb_load_conflicts },
1030 : : { PKG_LOAD_PROVIDES, pkgdb_load_provides },
1031 : : { PKG_LOAD_REQUIRES, pkgdb_load_requires },
1032 : : { PKG_LOAD_LUA_SCRIPTS, pkgdb_load_lua_scripts },
1033 : : { -1, NULL }
1034 : : };
1035 : :
1036 : : static void
1037 : 25 : pkgdb_sqlite_it_reset(struct pkgdb_sqlite_it *it)
1038 : : {
1039 [ + - ]: 25 : if (it == NULL)
1040 : 0 : return;
1041 : :
1042 : 25 : it->finished = 0;
1043 : 25 : sqlite3_reset(it->stmt);
1044 : 25 : }
1045 : :
1046 : : static void
1047 : 1714 : pkgdb_sqlite_it_free(struct pkgdb_sqlite_it *it)
1048 : : {
1049 [ + - ]: 1714 : if (it == NULL)
1050 : 0 : return;
1051 : :
1052 : 1714 : sqlite3_finalize(it->stmt);
1053 : 1714 : }
1054 : :
1055 : : static int
1056 : 2394 : pkgdb_sqlite_it_next(struct pkgdb_sqlite_it *it,
1057 : : struct pkg **pkg_p, unsigned flags)
1058 : : {
1059 : : struct pkg *pkg;
1060 : : int i;
1061 : : int ret;
1062 : :
1063 [ + - ]: 2394 : assert(it != NULL);
1064 : :
1065 : : /*
1066 : : * XXX:
1067 : : * Currently, we have a lot of issues related to pkg digests.
1068 : : * So we want to ensure that we always have a valid package digest
1069 : : * even if we work with pkg 1.2 repo. Therefore, we explicitly check
1070 : : * manifest digests and set it to NULL if it is invalid.
1071 : : *
1072 : : */
1073 : :
1074 [ - + # # ]: 2394 : if (it->finished && (it->flags & PKGDB_IT_FLAG_ONCE))
1075 : 0 : return (EPKG_END);
1076 : :
1077 [ - + + ]: 2394 : switch (sqlite3_step(it->stmt)) {
1078 : : case SQLITE_ROW:
1079 : 1005 : pkg_free(*pkg_p);
1080 : 1005 : ret = pkg_new(pkg_p, it->pkg_type);
1081 [ - + ]: 1005 : if (ret != EPKG_OK)
1082 : 0 : return (ret);
1083 : 1005 : pkg = *pkg_p;
1084 : :
1085 : 1005 : populate_pkg(it->stmt, pkg);
1086 : :
1087 [ + + + - ]: 1005 : if (pkg->digest != NULL && !pkg_checksum_is_valid(pkg->digest, strlen(pkg->digest))) {
1088 : 0 : free(pkg->digest);
1089 : 0 : pkg->digest = NULL;
1090 : 0 : }
1091 : :
1092 [ + + ]: 18090 : for (i = 0; load_on_flag[i].load != NULL; i++) {
1093 [ + + ]: 17085 : if (flags & load_on_flag[i].flag) {
1094 [ - + ]: 3867 : if (it->sqlite != NULL) {
1095 : 3867 : ret = load_on_flag[i].load(it->sqlite, pkg);
1096 [ - + ]: 3867 : if (ret != EPKG_OK)
1097 : 0 : return (ret);
1098 : 3867 : }
1099 : : else {
1100 : 0 : pkg_emit_error("invalid iterator passed to pkgdb_it_next");
1101 : 0 : return (EPKG_FATAL);
1102 : : }
1103 : 3867 : }
1104 : 17085 : }
1105 : :
1106 : 1005 : return (EPKG_OK);
1107 : : case SQLITE_DONE:
1108 : 1389 : it->finished ++;
1109 [ - + ]: 1389 : if (it->flags & PKGDB_IT_FLAG_CYCLED) {
1110 : 0 : sqlite3_reset(it->stmt);
1111 : 0 : return (EPKG_OK);
1112 : : }
1113 : : else {
1114 [ + - ]: 1389 : if (it->flags & PKGDB_IT_FLAG_AUTO)
1115 : 0 : pkgdb_sqlite_it_free(it);
1116 : 1389 : return (EPKG_END);
1117 : : }
1118 : : break;
1119 : : default:
1120 : 0 : ERROR_SQLITE(it->sqlite, "iterator");
1121 : 0 : return (EPKG_FATAL);
1122 : : }
1123 : 2394 : }
1124 : :
1125 : : int
1126 : 3167 : pkgdb_it_next(struct pkgdb_it *it, struct pkg **pkg_p, unsigned flags)
1127 : : {
1128 : : struct pkg_repo_it *rit;
1129 : 3167 : int ret = EPKG_END;
1130 : :
1131 [ + - ]: 3167 : assert(it != NULL);
1132 : :
1133 [ + + - + ]: 3167 : if (it->local != NULL && !it->local->finished) {
1134 : 2394 : int r = pkgdb_sqlite_it_next(it->local, pkg_p, flags);
1135 [ + + ]: 2394 : if ( r != EPKG_END)
1136 : 1005 : return (r);
1137 : 1389 : }
1138 : :
1139 [ + + ]: 2162 : if (tll_length(it->remote) != 0) {
1140 [ + + ]: 768 : if (it->opq_it == NULL)
1141 : 316 : it->opq_it = it->remote.head;
1142 : 768 : __typeof__(*(it->remote).head) *lit = it->opq_it;
1143 : 768 : rit = lit->item;
1144 : 768 : ret = rit->ops->next(rit, pkg_p, flags);
1145 [ + + ]: 768 : if (ret != EPKG_OK) {
1146 [ + + ]: 372 : if (it->opq_it == it->remote.tail)
1147 : 316 : return (EPKG_END);
1148 : 56 : it->opq_it = lit->next;
1149 : 56 : return (pkgdb_it_next(it, pkg_p, flags));
1150 : : }
1151 : :
1152 [ - + ]: 396 : if (*pkg_p != NULL)
1153 : 396 : (*pkg_p)->repo = rit->repo;
1154 : :
1155 : 396 : return (EPKG_OK);
1156 : : }
1157 : :
1158 : 1394 : return ret;
1159 : 3167 : }
1160 : :
1161 : : // TODO: Why doesn't this function handle remote?
1162 : : int
1163 : 25 : pkgdb_it_count(struct pkgdb_it *it)
1164 : : {
1165 : : int i;
1166 : : int ret;
1167 : : struct pkgdb_sqlite_it *sit;
1168 : :
1169 [ + - ]: 25 : assert(it != NULL);
1170 : :
1171 : 25 : i = 0;
1172 : 25 : sit = it->local;
1173 : :
1174 [ + - ]: 25 : if (sit == NULL)
1175 : 0 : return (0);
1176 : :
1177 [ + - ]: 52 : while ((ret = sqlite3_step(sit->stmt))) {
1178 [ + - + ]: 52 : switch (ret) {
1179 : : case SQLITE_ROW:
1180 : 27 : ++i;
1181 : 27 : break;
1182 : : case SQLITE_DONE:
1183 : 25 : goto done;
1184 : : default:
1185 : 0 : ERROR_SQLITE(sit->sqlite, "iterator");
1186 : 0 : return (-1);
1187 : : }
1188 : : }
1189 : :
1190 : : done:
1191 : 25 : pkgdb_it_reset(it);
1192 : 25 : return (i);
1193 : 25 : }
1194 : :
1195 : : void
1196 : 25 : pkgdb_it_reset(struct pkgdb_it *it)
1197 : : {
1198 [ + - ]: 25 : assert(it != NULL);
1199 : :
1200 [ - + ]: 25 : if (it->local != NULL) {
1201 : 25 : pkgdb_sqlite_it_reset(it->local);
1202 : 25 : }
1203 [ - + - + : 25 : tll_foreach(it->remote, cur) {
# # ]
1204 : 0 : cur->item->ops->reset(cur->item);
1205 : 0 : }
1206 : 25 : }
1207 : :
1208 : : void
1209 : 2035 : pkgdb_it_free(struct pkgdb_it *it)
1210 : : {
1211 [ + - ]: 2035 : if (it == NULL)
1212 : 0 : return;
1213 : :
1214 [ + + ]: 2035 : if (it->local != NULL) {
1215 : 1714 : pkgdb_sqlite_it_free(it->local);
1216 : 1714 : free(it->local);
1217 : 1714 : }
1218 [ + + + + : 2407 : tll_free_and_free(it->remote, remote_free);
+ + ]
1219 : :
1220 : 2035 : free(it);
1221 : 2035 : }
1222 : :
1223 : : struct pkgdb_it *
1224 : 1714 : pkgdb_it_new_sqlite(struct pkgdb *db, sqlite3_stmt *s, int type, short flags)
1225 : : {
1226 : : struct pkgdb_it *it;
1227 : :
1228 [ + - ]: 1714 : assert(db != NULL && s != NULL);
1229 [ + - ]: 1714 : assert(!(flags & (PKGDB_IT_FLAG_CYCLED & PKGDB_IT_FLAG_ONCE)));
1230 [ + - ]: 1714 : assert(!(flags & (PKGDB_IT_FLAG_AUTO & (PKGDB_IT_FLAG_CYCLED | PKGDB_IT_FLAG_ONCE))));
1231 : :
1232 : 1714 : it = xcalloc(1, sizeof(struct pkgdb_it));
1233 : :
1234 : 1714 : it->db = db;
1235 : 1714 : it->local = xmalloc(sizeof(struct pkgdb_sqlite_it));
1236 : 1714 : it->local->sqlite = db->sqlite;
1237 : 1714 : it->local->stmt = s;
1238 : 1714 : it->local->pkg_type = type;
1239 : :
1240 : 1714 : it->local->flags = flags;
1241 : 1714 : it->local->finished = 0;
1242 : 1714 : it->opq_it = it->remote.head;
1243 : :
1244 : 1714 : return (it);
1245 : : }
1246 : :
1247 : : struct pkgdb_it *
1248 : 321 : pkgdb_it_new_repo(struct pkgdb *db)
1249 : : {
1250 : : struct pkgdb_it *it;
1251 : :
1252 : 321 : it = xcalloc(1, sizeof(struct pkgdb_it));
1253 : :
1254 : 321 : it->db = db;
1255 : :
1256 : 321 : return (it);
1257 : : }
1258 : :
1259 : : void
1260 : 372 : pkgdb_it_repo_attach(struct pkgdb_it *it, struct pkg_repo_it *rit)
1261 : : {
1262 [ + + + + : 372 : tll_push_front(it->remote, rit);
+ - - + +
+ ]
1263 : 372 : }
1264 : :
1265 : : int
1266 : 298 : pkgdb_ensure_loaded_sqlite(sqlite3 *sqlite, struct pkg *pkg, unsigned flags)
1267 : : {
1268 : : int i, ret;
1269 : :
1270 [ + + ]: 5364 : for (i = 0; load_on_flag[i].load != NULL; i++) {
1271 [ + + ]: 5066 : if (~pkg->flags & flags & load_on_flag[i].flag) {
1272 : 358 : ret = load_on_flag[i].load(sqlite, pkg);
1273 [ + - ]: 358 : if (ret != EPKG_OK)
1274 : 0 : return (ret);
1275 : 358 : pkg->flags |= load_on_flag[i].flag;
1276 : 358 : }
1277 : 5066 : }
1278 : :
1279 : 298 : return (EPKG_OK);
1280 : 298 : }
1281 : :
1282 : : int
1283 : 926 : pkgdb_ensure_loaded(struct pkgdb *db, struct pkg *pkg, unsigned flags)
1284 : : {
1285 [ + + ]: 926 : if (pkg->type == PKG_INSTALLED)
1286 : 298 : return (pkgdb_ensure_loaded_sqlite(db->sqlite, pkg, flags));
1287 : :
1288 [ + + + + : 666 : tll_foreach(db->repos, cur) {
+ - ]
1289 [ + + ]: 542 : if (cur->item == pkg->repo) {
1290 [ + - ]: 504 : if (cur->item->ops->ensure_loaded) {
1291 : 1008 : return (cur->item->ops->ensure_loaded(cur->item,
1292 : 504 : pkg, flags));
1293 : : }
1294 : 0 : }
1295 : 38 : }
1296 : :
1297 : 124 : return (EPKG_FATAL);
1298 : 926 : }
|