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