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