diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c index 908a5ea5..b9b62998 100644 --- a/bin/xbps-bin/install.c +++ b/bin/xbps-bin/install.c @@ -322,7 +322,7 @@ xbps_install_new_pkg(const char *pkg) return 0; } if ((rv = xbps_repository_install_pkg(pkgpatt)) != 0) { - if (rv == EAGAIN) { + if (rv == ENOENT) { fprintf(stderr, "xbps-bin: unable to locate '%s' in " "repository pool.\n", pkg); rv = -1; diff --git a/lib/repository_findpkg.c b/lib/repository_findpkg.c index 0534ffc0..1029ff58 100644 --- a/lib/repository_findpkg.c +++ b/lib/repository_findpkg.c @@ -66,19 +66,139 @@ set_pkg_state(prop_dictionary_t pkgd, const char *pkgname) * Overwrite package state in dictionary if it was unpacked * previously. */ - rv = xbps_get_pkg_state_installed(pkgname, &state); - if (rv == 0) { + if ((rv = xbps_get_pkg_state_installed(pkgname, &state)) == 0) { if (state == XBPS_PKG_STATE_INSTALLED) return 0; - if ((rv = xbps_set_pkg_state_dictionary(pkgd, state)) != 0) return rv; - } else if (rv == ENOENT) + } + /* pkg not installed, don't error out */ + if (rv == ENOENT) rv = 0; return rv; } +static int +repository_find_pkg(const char *pattern, const char *reason) +{ + prop_dictionary_t pkg_repod = NULL, origin_pkgrd = NULL; + prop_dictionary_t transd; + prop_array_t mdeps, unsorted; + const char *pkgname; + int rv = 0; + bool success, install, bypattern, bestpkg; + + assert(pattern != NULL); + assert(reason != NULL); + success = install = bypattern = bestpkg = false; + + if (strcmp(reason, "install") == 0) { + /* install */ + install = true; + bypattern = true; + bestpkg = false; + } else { + /* update */ + pkg_repod = xbps_find_pkg_dict_installed(pattern, false); + if (pkg_repod == NULL) { + rv = ENODEV; + goto out; + } + prop_object_release(pkg_repod); + pkg_repod = NULL; + bestpkg = true; + } + + /* + * Find out if the pkg has been found in repository pool. + */ + pkg_repod = xbps_repository_pool_find_pkg(pattern, + bypattern, bestpkg); + if (pkg_repod == NULL) { + /* not found */ + rv = errno; + errno = 0; + goto out; + } + /* + * Prepare transaction dictionary and missing deps array. + */ + if ((transd = xbps_transaction_dictionary_get()) == NULL) { + rv = EINVAL; + goto out; + } + if ((mdeps = xbps_transaction_missingdeps_get()) == NULL) { + rv = EINVAL; + goto out; + } + + origin_pkgrd = prop_dictionary_copy(pkg_repod); + prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); + /* + * Check that this pkg hasn't been added previously into + * the transaction. + */ + if (install) { + success = xbps_find_pkg_in_dict_by_pattern(transd, + "unsorted_pkgs", pattern); + } else { + success = xbps_find_pkg_in_dict_by_name(transd, + "unsorted_pkgs", pattern); + } + if (success) { + xbps_dbg_printf("package '%s' already queued in transaction\n", + pattern); + goto out; + } + /* + * Prepare required package dependencies and add them into the + * "unsorted" array in transaction dictionary. + */ + rv = xbps_repository_find_pkg_deps(transd, mdeps, origin_pkgrd); + if (rv != 0) + goto out; + + /* + * Set package state to the correct one. + */ + if ((rv = set_pkg_state(origin_pkgrd, pkgname)) != 0) + goto out; + + /* + * Set trans-action obj in pkg dictionary to "install" or "update". + */ + if (!prop_dictionary_set_cstring_nocopy(origin_pkgrd, + "trans-action", reason)) { + rv = EINVAL; + goto out; + } + /* + * Add required package dictionary into the unsorted array. + */ + unsorted = prop_dictionary_get(transd, "unsorted_deps"); + if (unsorted == NULL) { + rv = EINVAL; + goto out; + } + /* + * Add the pkg dictionary from repository's index dictionary into + * the "unsorted" array in transaction dictionary. + */ + if (!prop_array_add(unsorted, origin_pkgrd)) { + rv = errno; + goto out; + } + +out: + if (pkg_repod) + prop_object_release(pkg_repod); + if (origin_pkgrd) + prop_object_release(origin_pkgrd); + + return rv; +} + int xbps_repository_update_allpkgs(void) { @@ -99,9 +219,9 @@ xbps_repository_update_allpkgs(void) iter = xbps_get_array_iter_from_dict(dict, "packages"); if (iter == NULL) { rv = errno; - goto out; + xbps_regpkgdb_dictionary_release(); + return rv; } - /* * Find out if there is a newer version for all currently * installed packages. @@ -109,206 +229,39 @@ xbps_repository_update_allpkgs(void) while ((obj = prop_object_iterator_next(iter)) != NULL) { prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); if ((rv = xbps_repository_update_pkg(pkgname)) != 0) { - if (rv == ENOENT || rv == EEXIST) + if (rv == ENOENT || rv == EEXIST) { + /* + * missing pkg or installed version is + * greater than or equal than pkg + * in repositories. + */ + rv = 0; continue; + } xbps_dbg_printf("[update-all] '%s' returned: %s\n", pkgname, strerror(rv)); - goto out; + break; } newpkg_found = true; } prop_object_iterator_release(iter); - - if (newpkg_found) - rv = 0; - else - rv = ENXIO; - -out: xbps_regpkgdb_dictionary_release(); + if (!newpkg_found) + rv = ENXIO; + return rv; } int xbps_repository_update_pkg(const char *pkgname) { - prop_array_t unsorted, mdeps; - prop_dictionary_t transd, pkg_repod; - int rv = 0; - - assert(pkgname != NULL); - /* - * Check if package is not installed. - */ - pkg_repod = xbps_find_pkg_dict_installed(pkgname, false); - if (pkg_repod == NULL) { - rv = ENODEV; - goto out; - } - prop_object_release(pkg_repod); - - /* - * Find out if a new package version exists in repositories. - */ - pkg_repod = xbps_repository_pool_find_pkg(pkgname, false, true); - xbps_dbg_printf("xbps_repository_pool_find_pkg returned %s for %s\n", - strerror(errno), pkgname); - if (pkg_repod == NULL) { - rv = errno; - errno = 0; - goto out; - } - if ((transd = xbps_transaction_dictionary_get()) == NULL) { - rv = EINVAL; - goto out; - } - if ((mdeps = xbps_transaction_missingdeps_get()) == NULL) { - rv = EINVAL; - goto out; - } - /* - * Construct the dependency chain for this package. - */ - rv = xbps_repository_find_pkg_deps(transd, mdeps, pkg_repod); - if (rv != 0) - goto out; - - /* - * Add required package dictionary into the packages - * dictionary. - */ - unsorted = prop_dictionary_get(transd, "unsorted_deps"); - if (unsorted == NULL) { - rv = errno; - goto out; - } - - /* - * Always set "not-installed" package state. Will be overwritten - * to its correct state later. - */ - if ((rv = set_pkg_state(pkg_repod, pkgname)) != 0) - goto out; - - /* - * Set trans-action obj in pkg dictionary to "update". - */ - if (!prop_dictionary_set_cstring_nocopy(pkg_repod, - "trans-action", "update")) { - rv = errno; - goto out; - } - - /* - * Added package dictionary from repository into the "unsorted" - * array in the transaction dictionary. - */ - if (!prop_array_add(unsorted, pkg_repod)) { - rv = errno; - goto out; - } - -out: - if (pkg_repod) - prop_object_release(pkg_repod); - - return rv; + return repository_find_pkg(pkgname, "update"); } int -xbps_repository_install_pkg(const char *pkg) +xbps_repository_install_pkg(const char *pkgpattern) { - prop_dictionary_t pkg_repod = NULL, origin_pkgrd = NULL; - prop_dictionary_t transd; - prop_array_t mdeps, unsorted; - const char *pkgname; - int rv = 0; - - assert(pkg != NULL); - - /* - * Get the package dictionary from current repository. - * If it's not there, pass to the next repository. - */ - pkg_repod = xbps_repository_pool_find_pkg(pkg, true, false); - if (pkg_repod == NULL) { - /* - * Package couldn't be found in repository pool... EAGAIN. - */ - rv = EAGAIN; - goto out; - } - /* - * Prepare transaction dictionary and missing deps array. - */ - if ((transd = xbps_transaction_dictionary_get()) == NULL) { - rv = EINVAL; - goto out; - } - if ((mdeps = xbps_transaction_missingdeps_get()) == NULL) { - rv = EINVAL; - goto out; - } - - origin_pkgrd = prop_dictionary_copy(pkg_repod); - prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); - /* - * Check that this pkg hasn't been added previously into - * the transaction. - */ - if (xbps_find_pkg_in_dict_by_pattern(transd, "unsorted_pkgs", pkg)) { - xbps_dbg_printf("package '%s' already queued in transaction\n", - pkg); - goto out; - } - /* - * Prepare required package dependencies and add them into the - * "unsorted" array in transaction dictionary. - */ - if ((rv = xbps_repository_find_pkg_deps(transd, mdeps, - origin_pkgrd)) != 0) - goto out; - - if ((rv = set_pkg_state(origin_pkgrd, pkgname)) != 0) - goto out; - - /* - * Set trans-action obj in pkg dictionary to "install". - */ - if (!prop_dictionary_set_cstring_nocopy(origin_pkgrd, - "trans-action", "install")) { - rv = EINVAL; - goto out; - } - - /* - * Add required package dictionary into the unsorted array and - * set package state as not yet installed. - */ - unsorted = prop_dictionary_get(transd, "unsorted_deps"); - if (unsorted == NULL) { - rv = EINVAL; - goto out; - } - /* - * Add the pkg dictionary from repository's index dictionary into - * the "unsorted" array in transaction dictionary. - */ - if (!prop_array_add(unsorted, origin_pkgrd)) { - rv = errno; - goto out; - } - -out: - if (pkg_repod) - prop_object_release(pkg_repod); - if (origin_pkgrd) - prop_object_release(origin_pkgrd); - - xbps_dbg_printf("%s: returned %s for '%s'\n\n", - __func__, strerror(rv), pkg); - - return rv; + return repository_find_pkg(pkgpattern, "install"); }