static int pkg_repo_binary_add_from_manifest(char *buf, const char *origin, const char *digest, long offset, sqlite3 *sqlite, struct pkg_manifest_key **keys, struct pkg **p, bool is_legacy, struct pkg_repo *repo) { int rc = EPKG_OK; struct pkg *pkg; const char *local_origin, *pkg_arch; if (*p == NULL) { rc = pkg_new(p, PKG_REMOTE); if (rc != EPKG_OK) return (EPKG_FATAL); } else { pkg_reset(*p, PKG_REMOTE); } pkg = *p; pkg_manifest_keys_new(keys); rc = pkg_parse_manifest(pkg, buf, offset, *keys); if (rc != EPKG_OK) { goto cleanup; } rc = pkg_is_valid(pkg); if (rc != EPKG_OK) { goto cleanup; } /* Ensure that we have a proper origin and arch*/ pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch); if (local_origin == NULL || strcmp(local_origin, origin) != 0) { pkg_emit_error("manifest contains origin %s while we wanted to add origin %s", local_origin ? local_origin : "NULL", origin); rc = EPKG_FATAL; goto cleanup; } if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) { rc = EPKG_FATAL; pkg_emit_error("repository %s contains packages with wrong ABI: %s", repo->name, pkg_arch); goto cleanup; } pkg_set(pkg, PKG_REPONAME, repo->name); if (is_legacy) { pkg_set(pkg, PKG_OLD_DIGEST, digest); pkg_checksum_calculate(pkg, NULL); } else { pkg_set(pkg, PKG_DIGEST, digest); } rc = pkg_repo_binary_add_pkg(pkg, NULL, sqlite, true); cleanup: return (rc); }
static int pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe, struct pkgdb_it *it, const char *name, bool is_shlib, struct pkg *parent) { struct pkg_job_universe_item *unit; struct pkg_job_provide *pr, *prhead; struct pkg *npkg, *rpkg; int rc; unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS| PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES| PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED| PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS; rpkg = NULL; HASH_FIND_STR(universe->provides, name, prhead); while (pkgdb_it_next(it, &rpkg, flags) == EPKG_OK) { /* Check for local packages */ HASH_FIND_STR(universe->items, rpkg->uid, unit); if (unit != NULL) { /* Remote provide is newer, so we can add it */ if (pkg_jobs_universe_process_item(universe, rpkg, &unit) != EPKG_OK) { continue; } rpkg = NULL; } else { /* Maybe local package has just been not added */ npkg = pkg_jobs_universe_get_local(universe, rpkg->uid, 0); if (npkg != NULL) { if (pkg_jobs_universe_process_item(universe, npkg, &unit) != EPKG_OK) { return (EPKG_FATAL); } if (pkg_jobs_universe_process_item(universe, rpkg, &unit) != EPKG_OK) { continue; } if (unit != NULL) rpkg = NULL; } } /* Skip seen packages */ if (unit == NULL) { if (rpkg->digest == NULL) { pkg_debug(3, "no digest found for package %s", rpkg->uid); if (pkg_checksum_calculate(rpkg, universe->j->db) != EPKG_OK) { return (EPKG_FATAL); } } rc = pkg_jobs_universe_process_item(universe, rpkg, &unit); if (rc != EPKG_OK) { return (rc); } /* Reset package to avoid freeing */ rpkg = NULL; } pr = calloc (1, sizeof (*pr)); if (pr == NULL) { pkg_emit_errno("pkg_jobs_add_universe", "calloc: " "struct pkg_job_provide"); return (EPKG_FATAL); } pr->un = unit; pr->provide = name; pr->is_shlib = is_shlib; if (prhead == NULL) { DL_APPEND(prhead, pr); HASH_ADD_KEYPTR(hh, universe->provides, pr->provide, strlen(pr->provide), prhead); pkg_debug (4, "universe: add new provide %s-%s(%s) for require %s", pr->un->pkg->name, pr->un->pkg->version, pr->un->pkg->type == PKG_INSTALLED ? "l" : "r", pr->provide); } else { DL_APPEND(prhead, pr); pkg_debug (4, "universe: append provide %s-%s(%s) for require %s", pr->un->pkg->name, pr->un->pkg->version, pr->un->pkg->type == PKG_INSTALLED ? "l" : "r", pr->provide); } } return (EPKG_OK); }
/** * Check whether a package is in the universe already or add it * @return item or NULL */ int pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg, bool force, struct pkg_job_universe_item **found) { struct pkg_job_universe_item *item, *seen, *tmp = NULL; pkg_validate(pkg, universe->j->db); if (pkg->digest == NULL) { pkg_debug(3, "no digest found for package %s (%s-%s)", pkg->uid, pkg->name, pkg->version); if (pkg_checksum_calculate(pkg, universe->j->db) != EPKG_OK) { *found = NULL; return (EPKG_FATAL); } } kh_find(pkg_jobs_seen, universe->seen, pkg->digest, seen); if (seen) { bool same_package = false; DL_FOREACH(seen, tmp) { if (tmp->pkg == pkg || (tmp->pkg->type == pkg->type && strcmp(tmp->pkg->digest, pkg->digest) == 0)) { if (tmp->pkg->reponame != NULL) { if (strcmp(tmp->pkg->reponame, pkg->reponame) == 0) { same_package = true; break; } } else { same_package = true; break; } } } if (same_package) { if (found != NULL) { *found = seen; } return (EPKG_END); } } if (pkg_is_locked(pkg)) { pkg_emit_locked(pkg); return (EPKG_LOCKED); } pkg_debug(2, "universe: add new %s pkg: %s, (%s-%s:%s)", (pkg->type == PKG_INSTALLED ? "local" : "remote"), pkg->uid, pkg->name, pkg->version, pkg->digest); item = calloc(1, sizeof (struct pkg_job_universe_item)); if (item == NULL) { pkg_emit_errno("pkg_jobs_pkg_insert_universe", "calloc: struct pkg_job_universe_item"); return (EPKG_FATAL); } item->pkg = pkg; HASH_FIND_STR(universe->items, pkg->uid, tmp); if (tmp == NULL) HASH_ADD_KEYPTR(hh, universe->items, pkg->uid, strlen(pkg->uid), item); DL_APPEND(tmp, item); if (seen == NULL) kh_safe_add(pkg_jobs_seen, universe->seen, item, item->pkg->digest); universe->nitems++; if (found != NULL) *found = item; return (EPKG_OK); }