/** * 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); }
int pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags) { struct pkg_dep *rdep = NULL; int ret; bool handle_rc = false; const char *origin; assert(pkg != NULL); assert(db != NULL); /* * Do not trust the existing entries as it may have changed if we * delete packages in batch. */ pkg_list_free(pkg, PKG_RDEPS); /* * Ensure that we have all the informations we need */ if ((ret = pkgdb_load_rdeps(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_load_files(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_load_dirs(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_load_scripts(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_load_mtree(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_load_annotations(db, pkg)) != EPKG_OK) return (ret); if ((flags & PKG_DELETE_UPGRADE) == 0) pkg_emit_deinstall_begin(pkg); /* If the package is locked */ if (pkg_is_locked(pkg)) { pkg_emit_locked(pkg); return (EPKG_LOCKED); } /* If there are dependencies */ if ((flags & (PKG_DELETE_UPGRADE|PKG_DELETE_CONFLICT)) == 0) { if (pkg_rdeps(pkg, &rdep) == EPKG_OK) { pkg_emit_required(pkg, flags & PKG_DELETE_FORCE); if ((flags & PKG_DELETE_FORCE) == 0) return (EPKG_REQUIRED); } } /* * stop the different related services if the users do want that * and that the service is running */ handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS")); if (handle_rc) pkg_start_stop_rc_scripts(pkg, PKG_RC_STOP); if ((flags & PKG_DELETE_NOSCRIPT) == 0) { if (flags & PKG_DELETE_UPGRADE) { ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_UPGRADE); if (ret != EPKG_OK) return (ret); } else { ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (ret != EPKG_OK) return (ret); } } if ((ret = pkg_delete_files(pkg, flags & PKG_DELETE_FORCE ? 1 : 0)) != EPKG_OK) return (ret); if ((flags & (PKG_DELETE_NOSCRIPT | PKG_DELETE_UPGRADE)) == 0) { ret = pkg_script_run(pkg, PKG_SCRIPT_POST_DEINSTALL); if (ret != EPKG_OK) return (ret); } ret = pkg_delete_dirs(db, pkg, flags & PKG_DELETE_FORCE); if (ret != EPKG_OK) return (ret); if ((flags & PKG_DELETE_UPGRADE) == 0) pkg_emit_deinstall_finished(pkg); pkg_get(pkg, PKG_ORIGIN, &origin); return (pkgdb_unregister_pkg(db, origin)); }
static int pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg, const char *path, int flags, struct pkg_manifest_key *keys, const char *location) { const char *arch; int ret, retcode; struct pkg_dep *dep = NULL; char bd[MAXPATHLEN], *basedir; char dpath[MAXPATHLEN], *ppath; const char *ext; struct pkg *pkg_inst = NULL; arch = pkg->abi != NULL ? pkg->abi : pkg->arch; if (!is_valid_abi(arch, true)) { if ((flags & PKG_ADD_FORCE) == 0) { return (EPKG_FATAL); } } /* XX check */ ret = pkg_try_installed(db, pkg->origin, &pkg_inst, PKG_LOAD_BASIC); if (ret == EPKG_OK) { if ((flags & PKG_ADD_FORCE) == 0) { pkg_emit_already_installed(pkg_inst); pkg_free(pkg_inst); pkg_inst = NULL; return (EPKG_INSTALLED); } else if (pkg_inst->locked) { pkg_emit_locked(pkg_inst); pkg_free(pkg_inst); pkg_inst = NULL; return (EPKG_LOCKED); } else { pkg_emit_notice("package %s is already installed, forced install", pkg->name); pkg_free(pkg_inst); pkg_inst = NULL; } } else if (ret != EPKG_END) { return (ret); } /* * Check for dependencies by searching the same directory as * the package archive we're reading. Of course, if we're * reading from a file descriptor or a unix domain socket or * whatever, there's no valid directory to search. */ strlcpy(bd, path, sizeof(bd)); if (strncmp(path, "-", 2) != 0) { basedir = dirname(bd); if ((ext = strrchr(path, '.')) == NULL) { pkg_emit_error("%s has no extension", path); return (EPKG_FATAL); } } else { ext = NULL; basedir = NULL; } retcode = EPKG_FATAL; pkg_emit_add_deps_begin(pkg); while (pkg_deps(pkg, &dep) == EPKG_OK) { if (pkg_is_installed(db, dep->name) == EPKG_OK) continue; if (basedir == NULL) { pkg_emit_missing_dep(pkg, dep); if ((flags & PKG_ADD_FORCE_MISSING) == 0) goto cleanup; continue; } if (dep->version != NULL && dep->version[0] != '\0') { snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir, dep->name, dep->version, ext); if ((flags & PKG_ADD_UPGRADE) == 0 && access(dpath, F_OK) == 0) { ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys, location); if (ret != EPKG_OK) goto cleanup; } else { pkg_emit_missing_dep(pkg, dep); if ((flags & PKG_ADD_FORCE_MISSING) == 0) goto cleanup; } } else { snprintf(dpath, sizeof(dpath), "%s/%s-*%s", basedir, dep->name, ext); ppath = pkg_globmatch(dpath, dep->name); if (ppath == NULL) { pkg_emit_missing_dep(pkg, dep); if ((flags & PKG_ADD_FORCE_MISSING) == 0) goto cleanup; continue; } if ((flags & PKG_ADD_UPGRADE) == 0 && access(ppath, F_OK) == 0) { ret = pkg_add(db, ppath, PKG_ADD_AUTOMATIC, keys, location); free(ppath); if (ret != EPKG_OK) goto cleanup; } else { free(ppath); pkg_emit_missing_dep(pkg, dep); if ((flags & PKG_ADD_FORCE_MISSING) == 0) goto cleanup; continue; } } } retcode = EPKG_OK; cleanup: pkg_emit_add_deps_finished(pkg); return (retcode); }
int pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags) { int ret; bool handle_rc = false; int64_t id; const unsigned load_flags = PKG_LOAD_RDEPS|PKG_LOAD_FILES|PKG_LOAD_DIRS| PKG_LOAD_SCRIPTS|PKG_LOAD_MTREE|PKG_LOAD_ANNOTATIONS; assert(pkg != NULL); assert(db != NULL); if (pkgdb_ensure_loaded(db, pkg, load_flags) != EPKG_OK) return (EPKG_FATAL); if ((flags & PKG_DELETE_UPGRADE) == 0) pkg_emit_deinstall_begin(pkg); /* If the package is locked */ if (pkg_is_locked(pkg)) { pkg_emit_locked(pkg); return (EPKG_LOCKED); } /* * stop the different related services if the users do want that * and that the service is running */ handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS")); if (handle_rc) pkg_start_stop_rc_scripts(pkg, PKG_RC_STOP); if ((flags & PKG_DELETE_NOSCRIPT) == 0) { if (flags & PKG_DELETE_UPGRADE) { ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_UPGRADE); if (ret != EPKG_OK) return (ret); } else { ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (ret != EPKG_OK) return (ret); } } if ((ret = pkg_delete_files(pkg, flags & PKG_DELETE_FORCE ? 1 : 0)) != EPKG_OK) return (ret); if ((flags & (PKG_DELETE_NOSCRIPT | PKG_DELETE_UPGRADE)) == 0) { ret = pkg_script_run(pkg, PKG_SCRIPT_POST_DEINSTALL); if (ret != EPKG_OK) return (ret); } ret = pkg_delete_dirs(db, pkg); if (ret != EPKG_OK) return (ret); if ((flags & PKG_DELETE_UPGRADE) == 0) pkg_emit_deinstall_finished(pkg); pkg_get(pkg, PKG_ROWID, &id); return (pkgdb_unregister_pkg(db, id)); }