diff --git a/include/xbps_api.h b/include/xbps_api.h index 53b747f0..f58d7a22 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -56,7 +56,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.3" -#define XBPS_API_VERSION "20111222-1" +#define XBPS_API_VERSION "20111223" #define XBPS_VERSION "0.12" /** @@ -772,7 +772,7 @@ int xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict, /** * Executes a function callback per a package dictionary registered - * in "regpkgdb" plist. + * in "regpkgdb" plist (downwards). * * @param[in] fn Function callback to run for any pkg dictionary. * @param[in] arg Argument to be passed to the function callback. @@ -783,6 +783,20 @@ int xbps_callback_array_iter_reverse_in_dict(prop_dictionary_t dict, int xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *), void *arg); +/** + * Executes a function callback per a package dictionary registered + * in "regpkgdb" plist, in reverse order (upwards). + * + * @param[in] fn Function callback to run for any pkg dictionary. + * @param[in] arg Argument to be passed to the function callback. + * + * @return 0 on success (all objects were processed), otherwise an + * errno value. + */ +int xbps_regpkgdb_foreach_reverse_pkg_cb( + int (*fn)(prop_object_t, void *, bool *), + void *arg); + /** * Finds the proplib's dictionary associated with a package, by looking * it via its name in a proplib dictionary. diff --git a/lib/package_configure.c b/lib/package_configure.c index 3f004689..ebafc0a0 100644 --- a/lib/package_configure.c +++ b/lib/package_configure.c @@ -46,35 +46,24 @@ * member, the package (or packages) will be reconfigured even if its * state is XBPS_PKG_STATE_INSTALLED. */ +static int +configure_pkgs_cb(prop_object_t obj, void *arg, bool *done) +{ + const char *pkgname, *version; + + (void)arg; + (void)done; + + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "version", &version); + + return xbps_configure_pkg(pkgname, version, true, false); +} + int xbps_configure_packages(void) { - struct xbps_handle *xhp; - prop_object_t obj; - prop_object_iterator_t iter; - const char *pkgname, *version; - int rv = 0; - - xhp = xbps_handle_get(); - if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0) { - xbps_dbg_printf("%s: couldn't initialize " - "regpkgdb: %s\n", strerror(rv)); - return rv; - } - iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); - if (iter == NULL) - return errno; - - while ((obj = prop_object_iterator_next(iter)) != NULL) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(obj, "version", &version); - rv = xbps_configure_pkg(pkgname, version, true, false); - if (rv != 0) - break; - } - prop_object_iterator_release(iter); - - return rv; + return xbps_regpkgdb_foreach_pkg_cb(configure_pkgs_cb, NULL); } int diff --git a/lib/package_orphans.c b/lib/package_orphans.c index 0095fa55..0f31a055 100644 --- a/lib/package_orphans.c +++ b/lib/package_orphans.c @@ -165,12 +165,10 @@ find_orphan_pkg(prop_object_t obj, void *arg, bool *loop_done) prop_array_t xbps_find_pkg_orphans(prop_array_t orphans_user) { - struct xbps_handle *xhp; prop_array_t array = NULL; struct orphan_data od; int rv = 0; - xhp = xbps_handle_get(); /* * Prepare an array with all packages previously found. */ @@ -182,13 +180,7 @@ xbps_find_pkg_orphans(prop_array_t orphans_user) * in which packages were installed. */ od.orphans_user = orphans_user; - if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0) { - xbps_dbg_printf("%s: couldn't initialize " - "regpkgdb: %s\n", strerror(rv)); - return NULL; - } - rv = xbps_callback_array_iter_reverse_in_dict(xhp->regpkgdb_dictionary, - "packages", find_orphan_pkg, &od); + rv = xbps_regpkgdb_foreach_reverse_pkg_cb(find_orphan_pkg, &od); if (rv != 0) { errno = rv; prop_object_release(od.array); diff --git a/lib/package_purge.c b/lib/package_purge.c index ef96ac1f..78d447d6 100644 --- a/lib/package_purge.c +++ b/lib/package_purge.c @@ -98,32 +98,21 @@ remove_pkg_metadata(const char *pkgname, return rv; } +static int +purge_pkgs_cb(prop_object_t obj, void *arg, bool *done) +{ + const char *pkgname; + + (void)arg; + (void)done; + + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + return xbps_purge_pkg(pkgname, true); +} int xbps_purge_packages(void) { - struct xbps_handle *xhp; - prop_object_t obj; - prop_object_iterator_t iter; - const char *pkgname; - int rv = 0; - - xhp = xbps_handle_get(); - if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0) { - xbps_dbg_printf("%s: couldn't initialize " - "regpkgdb: %s\n", strerror(rv)); - return rv; - } - iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); - if (iter == NULL) - return errno; - - while ((obj = prop_object_iterator_next(iter)) != NULL) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - if ((rv = xbps_purge_pkg(pkgname, true)) != 0) - break; - } - prop_object_iterator_release(iter); - return rv; + return xbps_regpkgdb_foreach_pkg_cb(purge_pkgs_cb, NULL); } int diff --git a/lib/regpkgdb_dictionary.c b/lib/regpkgdb_dictionary.c index f4f1dc94..a1b46ed4 100644 --- a/lib/regpkgdb_dictionary.c +++ b/lib/regpkgdb_dictionary.c @@ -98,14 +98,15 @@ xbps_regpkgdb_dictionary_release(struct xbps_handle *xhp) xbps_dbg_printf("[regpkgdb] released ok.\n"); } -int -xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *), - void *arg) +static int +foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *), + void *arg, + bool reverse) { prop_array_t array; prop_object_t obj; struct xbps_handle *xhp = xbps_handle_get(); - size_t i; + size_t i, cnt; int rv; bool done = false; @@ -117,11 +118,35 @@ xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *), if (prop_object_type(array) != PROP_TYPE_ARRAY) return EINVAL; - for (i = 0; i < prop_array_count(array); i++) { - obj = prop_array_get(array, i); - rv = (*fn)(obj, arg, &done); - if (rv != 0 || done) - break; + cnt = prop_array_count(array); + if (reverse) { + while (cnt--) { + obj = prop_array_get(array, cnt); + rv = (*fn)(obj, arg, &done); + if (rv != 0 || done) + break; + } + } else { + for (i = 0; i < cnt; i++) { + obj = prop_array_get(array, i); + rv = (*fn)(obj, arg, &done); + if (rv != 0 || done) + break; + } } return rv; } + +int +xbps_regpkgdb_foreach_reverse_pkg_cb(int (*fn)(prop_object_t, void *, bool *), + void *arg) +{ + return foreach_pkg_cb(fn, arg, true); +} + +int +xbps_regpkgdb_foreach_pkg_cb(int (*fn)(prop_object_t, void *, bool *), + void *arg) +{ + return foreach_pkg_cb(fn, arg, false); +} diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 4cc6e2a9..dbc6804e 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -177,50 +177,37 @@ out: return rv; } +static int +update_pkgs_cb(prop_object_t obj, void *arg, bool *done) +{ + const char *pkgname; + bool *newpkg_found = arg; + int rv = 0; + + (void)done; + + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + rv = xbps_transaction_update_pkg(pkgname); + if (rv == 0) + *newpkg_found = true; + else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) { + /* + * missing pkg or installed version is greater than or + * equal than pkg in repositories. + */ + rv = 0; + } + + return rv; +} + int xbps_transaction_update_packages(void) { - struct xbps_handle *xhp; - prop_object_t obj; - prop_object_iterator_t iter; - const char *pkgname; - int rv = 0; bool newpkg_found = false; + int rv; - xhp = xbps_handle_get(); - if ((rv = xbps_regpkgdb_dictionary_init(xhp)) != 0) { - xbps_dbg_printf("%s: couldn't initialize " - "regpkgdb: %s\n", strerror(rv)); - return rv; - } - iter = xbps_array_iter_from_dict(xhp->regpkgdb_dictionary, "packages"); - if (iter == NULL) - return ENOENT; - /* - * Find out if there is a newer version for all currently - * installed packages. - */ - while ((obj = prop_object_iterator_next(iter)) != NULL) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - if ((rv = xbps_transaction_update_pkg(pkgname)) != 0) { - if (rv == ENOENT || rv == EEXIST || rv == ENODEV) { - /* - * 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)); - break; - } - newpkg_found = true; - } - prop_object_iterator_release(iter); - + rv = xbps_regpkgdb_foreach_pkg_cb(update_pkgs_cb, &newpkg_found); if (!newpkg_found) rv = EEXIST;