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)); }
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)); }
int pkg_delete2(struct pkg *pkg, struct pkgdb *db, int force, int upgrade) { struct pkg_dep *rdep = NULL; int ret; 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_loadrdeps(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadfiles(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loaddirs(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadscripts(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadmtree(db, pkg)) != EPKG_OK) return (ret); if (!upgrade) pkg_emit_deinstall_begin(pkg); else pkg_emit_upgrade_begin(pkg); /* If there are dependencies */ if (pkg_rdeps(pkg, &rdep) == EPKG_OK) { pkg_emit_required(pkg, force); if (!force) return (EPKG_REQUIRED); } if (upgrade) { if (( ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_UPGRADE)) != EPKG_OK ) return (ret); } else { if ((ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_DEINSTALL)) != EPKG_OK) return (ret); } if ((ret = pkg_delete_files(pkg, force)) != EPKG_OK) return (ret); if (!upgrade) if ((ret = pkg_script_run(pkg, PKG_SCRIPT_POST_DEINSTALL)) != EPKG_OK) return (ret); if ((ret = pkg_delete_dirs(db, pkg, force)) != EPKG_OK) return (ret); if (!upgrade) pkg_emit_deinstall_finished(pkg); return (pkgdb_unregister_pkg(db, pkg_get(pkg, PKG_ORIGIN))); }
int pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_key *keys) { const char *arch; const char *origin; const char *name; struct archive *a; struct archive_entry *ae; struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct pkg *pkg_inst = NULL; bool extract = true; bool handle_rc = false; bool disable_mtree; char dpath[MAXPATHLEN]; const char *basedir; const char *ext; char *mtree; char *prefix; int retcode = EPKG_OK; int ret; assert(path != NULL); /* * Open the package archive file, read all the meta files and set the * current archive_entry to the first non-meta file. * If there is no non-meta files, EPKG_END is returned. */ ret = pkg_open2(&pkg, &a, &ae, path, keys, 0); if (ret == EPKG_END) extract = false; else if (ret != EPKG_OK) { retcode = ret; goto cleanup; } if ((flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_begin(pkg); if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } if (flags & PKG_ADD_AUTOMATIC) pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true); /* * Check the architecture */ pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin, PKG_NAME, &name); if (!is_valid_abi(arch, true)) { if ((flags & PKG_ADD_FORCE) == 0) { retcode = EPKG_FATAL; goto cleanup; } } /* * Check if the package is already installed */ ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC); if (ret == EPKG_OK) { if ((flags & PKG_FLAG_FORCE) == 0) { pkg_emit_already_installed(pkg_inst); retcode = EPKG_INSTALLED; pkg_free(pkg_inst); pkg_inst = NULL; goto cleanup; } else { pkg_emit_notice("package %s is already installed, forced install", name); pkg_free(pkg_inst); pkg_inst = NULL; } } else if (ret != EPKG_END) { retcode = ret; goto cleanup; } /* * 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 * somesuch, there's no valid directory to search. */ if (pkg_type(pkg) == PKG_FILE) { basedir = dirname(path); if ((ext = strrchr(path, '.')) == NULL) { pkg_emit_error("%s has no extension", path); retcode = EPKG_FATAL; goto cleanup; } } else { basedir = NULL; ext = NULL; } while (pkg_deps(pkg, &dep) == EPKG_OK) { if (pkg_is_installed(db, pkg_dep_origin(dep)) == EPKG_OK) continue; if (basedir != NULL) { const char *dep_name = pkg_dep_name(dep); const char *dep_ver = pkg_dep_version(dep); snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir, dep_name, dep_ver, ext); if ((flags & PKG_ADD_UPGRADE) == 0 && access(dpath, F_OK) == 0) { ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys); if (ret != EPKG_OK) { retcode = EPKG_FATAL; goto cleanup; } } else { pkg_emit_error("Missing dependency matching '%s'", pkg_dep_get(dep, PKG_DEP_ORIGIN)); retcode = EPKG_FATAL; goto cleanup; } } else { retcode = EPKG_FATAL; pkg_emit_missing_dep(pkg, dep); goto cleanup; } } /* register the package before installing it in case there are * problems that could be caught here. */ retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_UPGRADE, flags & PKG_FLAG_FORCE); if (retcode != EPKG_OK) goto cleanup; /* MTREE replicates much of the standard functionality * inplicit in the way pkg works. It has to remain available * in the ports for compatibility with the old pkg_tools, but * ultimately, MTREE should be made redundant. Use this for * experimantal purposes and to develop MTREE-free versions of * packages. */ pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree); if (!disable_mtree) { pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree); if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK) goto cleanup_reg; } /* * Execute pre-install scripts */ if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0) pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL); /* add the user and group if necessary */ /* pkg_add_user_group(pkg); */ /* * Extract the files on disk. */ if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) { /* If the add failed, clean up (silently) */ pkg_delete_files(pkg, 2); pkg_delete_dirs(db, pkg, 1); goto cleanup_reg; } /* * Execute post install scripts */ if ((flags & PKG_ADD_NOSCRIPT) == 0) { if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS) pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE); else pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL); } /* * start the different related services if the users do want that * and that the service is running */ pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc); if (handle_rc) pkg_start_stop_rc_scripts(pkg, PKG_RC_START); cleanup_reg: if ((flags & PKG_ADD_UPGRADE) == 0) pkgdb_register_finale(db, retcode); if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_finished(pkg); cleanup: if (a != NULL) { archive_read_close(a); archive_read_free(a); } pkg_free(pkg); if (pkg_inst != NULL) pkg_free(pkg_inst); return (retcode); }
int pkg_add(struct pkgdb *db, const char *path, unsigned flags) { const char *arch; const char *myarch; const char *origin; struct archive *a; struct archive_entry *ae; struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct pkg *pkg_inst = NULL; bool extract = true; bool handle_rc = false; char dpath[MAXPATHLEN + 1]; const char *basedir; const char *ext; char *mtree; char *prefix; int retcode = EPKG_OK; int ret; assert(path != NULL); /* * Open the package archive file, read all the meta files and set the * current archive_entry to the first non-meta file. * If there is no non-meta files, EPKG_END is returned. */ ret = pkg_open2(&pkg, &a, &ae, path); if (ret == EPKG_END) extract = false; else if (ret != EPKG_OK) { retcode = ret; goto cleanup; } if ((flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_begin(pkg); if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } if (flags & PKG_ADD_AUTOMATIC) pkg_set(pkg, PKG_AUTOMATIC, true); /* * Check the architecture */ pkg_config_string(PKG_CONFIG_ABI, &myarch); pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin); if (fnmatch(myarch, arch, FNM_CASEFOLD) == FNM_NOMATCH && strncmp(arch, myarch, strlen(myarch)) != 0) { pkg_emit_error("wrong architecture: %s instead of %s", arch, myarch); if ((flags & PKG_ADD_FORCE) == 0) { retcode = EPKG_FATAL; goto cleanup; } } /* * Check if the package is already installed */ ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC); if (ret == EPKG_OK) { pkg_emit_already_installed(pkg_inst); retcode = EPKG_INSTALLED; goto cleanup; } else if (ret != EPKG_END) { retcode = ret; goto cleanup; } /* * Check for dependencies */ basedir = dirname(path); if ((ext = strrchr(path, '.')) == NULL) { pkg_emit_error("%s has no extension", path); retcode = EPKG_FATAL; goto cleanup; } while (pkg_deps(pkg, &dep) == EPKG_OK) { if (pkg_is_installed(db, pkg_dep_origin(dep)) != EPKG_OK) { const char *dep_name = pkg_dep_name(dep); const char *dep_ver = pkg_dep_version(dep); snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir, dep_name, dep_ver, ext); if ((flags & PKG_ADD_UPGRADE) == 0 && access(dpath, F_OK) == 0) { ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC); if (ret != EPKG_OK) { retcode = EPKG_FATAL; goto cleanup; } } else { retcode = EPKG_FATAL; pkg_emit_missing_dep(pkg, dep); goto cleanup; } } } /* register the package before installing it in case there are * problems that could be caught here. */ if ((flags & PKG_ADD_UPGRADE) == 0) retcode = pkgdb_register_pkg(db, pkg, 0); else retcode = pkgdb_register_pkg(db, pkg, 1); if (retcode != EPKG_OK) goto cleanup; pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree); if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK) goto cleanup_reg; /* * Execute pre-install scripts */ if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0) pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL); /* add the user and group if necessary */ /* pkg_add_user_group(pkg); */ /* * Extract the files on disk. */ if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) { /* If the add failed, clean up */ pkg_delete_files(pkg, 1); pkg_delete_dirs(db, pkg, 1); goto cleanup_reg; } /* * Execute post install scripts */ if ((flags & PKG_ADD_NOSCRIPT) == 0) { if (flags & PKG_ADD_USE_UPGRADE_SCRIPTS) pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE); else pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL); } /* * start the different related services if the users do want that * and that the service is running */ pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc); if (handle_rc) pkg_start_stop_rc_scripts(pkg, PKG_RC_START); cleanup_reg: if ((flags & PKG_ADD_UPGRADE) == 0) pkgdb_register_finale(db, retcode); if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_finished(pkg); cleanup: if (a != NULL) archive_read_free(a); pkg_free(pkg); pkg_free(pkg_inst); return (retcode); }