xbps-bin: implemented (WIP) "autoupdate" target.
Some parts in the library related to findings pkgs in repositories has been improved vastly by caching the dictionary once. Duplicated code has been added in xbps-bin/install.c, but will be fixed soon. --HG-- extra : convert_revision : 2924012a8589a2a6ecaa3863b5091049006c0ef3
This commit is contained in:
parent
951a775432
commit
9f108b4cd2
9 changed files with 506 additions and 225 deletions
|
@ -29,5 +29,6 @@
|
||||||
void xbps_install_pkg(const char *, bool, bool);
|
void xbps_install_pkg(const char *, bool, bool);
|
||||||
void xbps_autoremove_pkgs(void);
|
void xbps_autoremove_pkgs(void);
|
||||||
void xbps_remove_pkg(const char *, bool);
|
void xbps_remove_pkg(const char *, bool);
|
||||||
|
void xbps_autoupdate_pkgs(bool);
|
||||||
|
|
||||||
#endif /* !_XBPS_BIN_DEFS_H_ */
|
#endif /* !_XBPS_BIN_DEFS_H_ */
|
||||||
|
|
|
@ -65,73 +65,48 @@ show_missing_dep_cb(prop_object_t obj, void *arg, bool *loop_done)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
xbps_install_pkg(const char *pkg, bool force, bool update)
|
check_pkg_hashes(prop_dictionary_t props, prop_object_iterator_t iter)
|
||||||
|
{
|
||||||
|
prop_object_t obj;
|
||||||
|
const char *repoloc, *filename;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
printf("Checking binary package file(s) integrity...\n");
|
||||||
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj, "filename", &filename);
|
||||||
|
rv = xbps_check_pkg_file_hash(obj, repoloc);
|
||||||
|
if (rv != 0 && rv != ERANGE) {
|
||||||
|
printf("error: checking hash for %s (%s)\n",
|
||||||
|
filename, strerror(rv));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (rv != 0 && rv == ERANGE) {
|
||||||
|
printf("Hash doesn't match for %s!\n", filename);
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop_object_iterator_reset(iter);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_transaction_sizes(prop_dictionary_t props, prop_object_iterator_t iter,
|
||||||
|
const char *descr)
|
||||||
{
|
{
|
||||||
prop_dictionary_t props, instpkg;
|
|
||||||
prop_array_t array;
|
|
||||||
prop_object_t obj;
|
prop_object_t obj;
|
||||||
prop_object_iterator_t iter;
|
|
||||||
uint64_t tsize = 0, dlsize = 0, instsize = 0;
|
uint64_t tsize = 0, dlsize = 0, instsize = 0;
|
||||||
size_t cols = 0;
|
size_t cols = 0;
|
||||||
const char *repoloc, *filename, *instver, *origin;
|
|
||||||
const char *pkgname, *version;
|
const char *pkgname, *version;
|
||||||
char size[64];
|
char size[64];
|
||||||
int rv = 0;
|
bool first = false;
|
||||||
bool pkg_is_dep, doup = false, first = false;
|
|
||||||
|
|
||||||
assert(props != NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find and sort all required package dictionaries.
|
|
||||||
*/
|
|
||||||
printf("Finding/sorting required binary packages...\n");
|
|
||||||
|
|
||||||
rv = xbps_prepare_pkg(pkg);
|
|
||||||
if (rv != 0 && rv == EAGAIN) {
|
|
||||||
printf("Unable to locate %s in repository pool.\n", pkg);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else if (rv != 0 && rv != ENOENT) {
|
|
||||||
printf("Unexpected error: %s\n", strerror(rv));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
props = xbps_get_pkg_props(pkg);
|
|
||||||
if (props == NULL) {
|
|
||||||
printf("error: unexistent props dictionary!\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bail out if there are unresolved deps.
|
|
||||||
*/
|
|
||||||
array = prop_dictionary_get(props, "missing_deps");
|
|
||||||
if (prop_array_count(array) > 0) {
|
|
||||||
show_missing_deps(props, pkg);
|
|
||||||
prop_object_release(props);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
prop_dictionary_get_cstring_nocopy(props, "origin", &origin);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over the list of packages that are going to be
|
* Iterate over the list of packages that are going to be
|
||||||
* installed and check the file hash.
|
* installed and check the file hash.
|
||||||
*/
|
*/
|
||||||
array = prop_dictionary_get(props, "packages");
|
|
||||||
if (array == NULL || prop_array_count(array) == 0) {
|
|
||||||
printf("error: empty packages array!\n");
|
|
||||||
prop_object_release(props);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
iter = prop_array_iterator(array);
|
|
||||||
if (iter == NULL) {
|
|
||||||
printf("error: allocating array mem! (%s)\n", strerror(errno));
|
|
||||||
prop_object_release(props);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
prop_dictionary_get_uint64(obj, "filename-size", &tsize);
|
prop_dictionary_get_uint64(obj, "filename-size", &tsize);
|
||||||
dlsize += tsize;
|
dlsize += tsize;
|
||||||
|
@ -145,7 +120,7 @@ xbps_install_pkg(const char *pkg, bool force, bool update)
|
||||||
/*
|
/*
|
||||||
* Show the list of packages that will be installed.
|
* Show the list of packages that will be installed.
|
||||||
*/
|
*/
|
||||||
printf("\nThe following new packages will be installed:\n\n");
|
printf("\nThe following new packages will be %s:\n\n", descr);
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
||||||
|
@ -182,7 +157,71 @@ xbps_install_pkg(const char *pkg, bool force, bool update)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf("Total installed size: %s\n\n", size);
|
printf("Total installed size: %s\n\n", size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xbps_install_pkg(const char *pkg, bool force, bool update)
|
||||||
|
{
|
||||||
|
prop_dictionary_t props, instpkg;
|
||||||
|
prop_array_t array;
|
||||||
|
prop_object_t obj;
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
const char *instver, *origin, *pkgname, *version;
|
||||||
|
int rv = 0;
|
||||||
|
bool pkg_is_dep, doup = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and sort all required package dictionaries.
|
||||||
|
*/
|
||||||
|
printf("Finding/sorting required binary packages...\n");
|
||||||
|
|
||||||
|
rv = xbps_prepare_pkg(pkg);
|
||||||
|
if (rv != 0 && rv == EAGAIN) {
|
||||||
|
printf("Unable to locate %s in repository pool.\n", pkg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (rv != 0 && rv != ENOENT) {
|
||||||
|
printf("Unexpected error: %s\n", strerror(rv));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
props = xbps_get_pkg_props();
|
||||||
|
if (props == NULL) {
|
||||||
|
printf("error: unexistent props dictionary!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bail out if there are unresolved deps.
|
||||||
|
*/
|
||||||
|
array = prop_dictionary_get(props, "missing_deps");
|
||||||
|
if (prop_array_count(array) > 0) {
|
||||||
|
show_missing_deps(props, pkg);
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_dictionary_get_cstring_nocopy(props, "origin", &origin);
|
||||||
|
|
||||||
|
array = prop_dictionary_get(props, "packages");
|
||||||
|
if (array == NULL || prop_array_count(array) == 0) {
|
||||||
|
printf("error: empty packages array!\n");
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
iter = prop_array_iterator(array);
|
||||||
|
if (iter == NULL) {
|
||||||
|
printf("error: allocating array mem! (%s)\n", strerror(errno));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Show download/installed size for the transaction.
|
||||||
|
*/
|
||||||
|
show_transaction_sizes(props, iter, "installed");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ask interactively (if -f not set).
|
||||||
|
*/
|
||||||
if (force == false) {
|
if (force == false) {
|
||||||
if (xbps_noyes("Do you want to continue?") == false) {
|
if (xbps_noyes("Do you want to continue?") == false) {
|
||||||
printf("Aborting!\n");
|
printf("Aborting!\n");
|
||||||
|
@ -191,24 +230,10 @@ xbps_install_pkg(const char *pkg, bool force, bool update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Checking binary package file(s) integrity...\n");
|
/*
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
* Check the SHA256 hash for all required packages.
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
|
*/
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "filename", &filename);
|
check_pkg_hashes(props, iter);
|
||||||
rv = xbps_check_pkg_file_hash(obj, repoloc);
|
|
||||||
if (rv != 0 && rv != ERANGE) {
|
|
||||||
printf("error: checking hash for %s (%s)\n",
|
|
||||||
filename, strerror(rv));
|
|
||||||
prop_object_release(props);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else if (rv != 0 && rv == ERANGE) {
|
|
||||||
printf("Hash doesn't match for %s!\n", filename);
|
|
||||||
prop_object_release(props);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prop_object_iterator_reset(iter);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Install all packages, the list is already sorted.
|
* Install all packages, the list is already sorted.
|
||||||
|
@ -276,3 +301,144 @@ xbps_install_pkg(const char *pkg, bool force, bool update)
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xbps_autoupdate_pkgs(bool force)
|
||||||
|
{
|
||||||
|
prop_dictionary_t dict, props, instpkg;
|
||||||
|
prop_array_t array;
|
||||||
|
prop_object_t obj;
|
||||||
|
prop_object_iterator_t iter;
|
||||||
|
const char *pkgname, *version, *instver;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
dict = xbps_get_regpkgdb_dict();
|
||||||
|
if (dict == NULL) {
|
||||||
|
printf("No packages currently installed (%s).\n",
|
||||||
|
strerror(errno));
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = xbps_get_array_iter_from_dict(dict, "packages");
|
||||||
|
if (iter == NULL) {
|
||||||
|
xbps_release_regpkgdb_dict();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xbps_prepare_repolist_data() != 0) {
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
xbps_release_regpkgdb_dict();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
||||||
|
rv = xbps_find_new_pkg(pkgname, obj);
|
||||||
|
if (rv != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
xbps_release_regpkgdb_dict();
|
||||||
|
|
||||||
|
/* Sort the list of packages */
|
||||||
|
props = xbps_get_pkg_props();
|
||||||
|
if (props == NULL) {
|
||||||
|
if (errno == 0) {
|
||||||
|
printf("All packages are up-to-date.\n");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
printf("Error while checking for new pkgs: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if ((rv = xbps_sort_pkg_deps(props)) != 0) {
|
||||||
|
printf("Error while sorting packages: %s\n",
|
||||||
|
strerror(rv));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
/* Update all packages now */
|
||||||
|
array = prop_dictionary_get(props, "packages");
|
||||||
|
if (array == NULL || prop_array_count(array) == 0) {
|
||||||
|
printf("error: empty packages array!\n");
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
iter = prop_array_iterator(array);
|
||||||
|
if (iter == NULL) {
|
||||||
|
printf("error: allocating array mem! (%s)\n", strerror(errno));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show download/installed size for the transaction.
|
||||||
|
*/
|
||||||
|
show_transaction_sizes(props, iter, "upgraded");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ask interactively (if -f not set).
|
||||||
|
*/
|
||||||
|
if (force == false) {
|
||||||
|
if (xbps_noyes("Do you want to continue?") == false) {
|
||||||
|
printf("Aborting!\n");
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the SHA256 hash for all required packages.
|
||||||
|
*/
|
||||||
|
check_pkg_hashes(props, iter);
|
||||||
|
|
||||||
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
||||||
|
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update a package, firstly removing current package.
|
||||||
|
*/
|
||||||
|
instpkg = xbps_find_pkg_installed_from_plist(pkgname);
|
||||||
|
if (instpkg == NULL) {
|
||||||
|
printf("error: unable to find %s installed "
|
||||||
|
"dict!\n", pkgname);
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_dictionary_get_cstring_nocopy(instpkg,
|
||||||
|
"version", &instver);
|
||||||
|
printf("Updating package %s-%s to %s...\n", pkgname,
|
||||||
|
instver, version);
|
||||||
|
prop_object_release(instpkg);
|
||||||
|
rv = xbps_remove_binary_pkg(pkgname, true);
|
||||||
|
if (rv != 0) {
|
||||||
|
printf("error: removing %s-%s (%s)\n",
|
||||||
|
pkgname, instver, strerror(rv));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unpack binary package.
|
||||||
|
*/
|
||||||
|
if ((rv = xbps_unpack_binary_pkg(obj)) != 0) {
|
||||||
|
printf("error: unpacking %s-%s (%s)\n", pkgname,
|
||||||
|
version, strerror(rv));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Register binary package.
|
||||||
|
*/
|
||||||
|
if ((rv = xbps_register_pkg(obj, true, false)) != 0) {
|
||||||
|
printf("error: registering %s-%s! (%s)\n",
|
||||||
|
pkgname, version, strerror(rv));
|
||||||
|
prop_object_release(props);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
xbps_release_repolist_data();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
|
@ -45,7 +45,8 @@ usage(void)
|
||||||
{
|
{
|
||||||
printf("Usage: xbps-bin [options] [target] [arguments]\n\n"
|
printf("Usage: xbps-bin [options] [target] [arguments]\n\n"
|
||||||
" Available targets:\n"
|
" Available targets:\n"
|
||||||
" autoremove, files, install, list, remove, show, update\n"
|
" autoremove, autoupdate, files, install, list, remove\n"
|
||||||
|
" show, update\n"
|
||||||
" Targets with arguments:\n"
|
" Targets with arguments:\n"
|
||||||
" files\t<pkgname>\n"
|
" files\t<pkgname>\n"
|
||||||
" install\t<pkgname>\n"
|
" install\t<pkgname>\n"
|
||||||
|
@ -63,6 +64,7 @@ usage(void)
|
||||||
"\n"
|
"\n"
|
||||||
" Examples:\n"
|
" Examples:\n"
|
||||||
" $ xbps-bin autoremove\n"
|
" $ xbps-bin autoremove\n"
|
||||||
|
" $ xbps-bin autoupdate\n"
|
||||||
" $ xbps-bin -C files klibc\n"
|
" $ xbps-bin -C files klibc\n"
|
||||||
" $ xbps-bin install klibc\n"
|
" $ xbps-bin install klibc\n"
|
||||||
" $ xbps-bin -r /path/to/root install klibc\n"
|
" $ xbps-bin -r /path/to/root install klibc\n"
|
||||||
|
@ -204,6 +206,15 @@ main(int argc, char **argv)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strcasecmp(argv[0], "autoupdate") == 0) {
|
||||||
|
/*
|
||||||
|
* To update all packages currently installed.
|
||||||
|
*/
|
||||||
|
if (argc != 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
xbps_autoupdate_pkgs(force);
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "autoremove") == 0) {
|
} else if (strcasecmp(argv[0], "autoremove") == 0) {
|
||||||
/*
|
/*
|
||||||
* Removes orphan pkgs. These packages were installed
|
* Removes orphan pkgs. These packages were installed
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -86,8 +87,17 @@ int xbps_humanize_number(char *, size_t, int64_t, const char *,
|
||||||
int, int);
|
int, int);
|
||||||
|
|
||||||
/* From lib/findpkg.c */
|
/* From lib/findpkg.c */
|
||||||
|
struct repository_data {
|
||||||
|
SIMPLEQ_ENTRY(repository_data) chain;
|
||||||
|
prop_dictionary_t rd_repod;
|
||||||
|
};
|
||||||
|
SIMPLEQ_HEAD(, repository_data) repodata_queue;
|
||||||
|
|
||||||
int xbps_prepare_pkg(const char *);
|
int xbps_prepare_pkg(const char *);
|
||||||
prop_dictionary_t xbps_get_pkg_props(const char *);
|
int xbps_find_new_pkg(const char *, prop_dictionary_t);
|
||||||
|
int xbps_prepare_repolist_data(void);
|
||||||
|
void xbps_release_repolist_data(void);
|
||||||
|
prop_dictionary_t xbps_get_pkg_props(void);
|
||||||
|
|
||||||
/* From lib/register.c */
|
/* From lib/register.c */
|
||||||
int xbps_register_pkg(prop_dictionary_t, bool, bool);
|
int xbps_register_pkg(prop_dictionary_t, bool, bool);
|
||||||
|
@ -100,8 +110,7 @@ int xbps_requiredby_pkg_remove(const char *);
|
||||||
int xbps_unpack_binary_pkg(prop_dictionary_t);
|
int xbps_unpack_binary_pkg(prop_dictionary_t);
|
||||||
|
|
||||||
/* From lib/depends.c */
|
/* From lib/depends.c */
|
||||||
int xbps_find_deps_in_pkg(prop_dictionary_t, prop_dictionary_t,
|
int xbps_find_deps_in_pkg(prop_dictionary_t, prop_dictionary_t);
|
||||||
prop_object_iterator_t);
|
|
||||||
|
|
||||||
/* From lib/plist.c */
|
/* From lib/plist.c */
|
||||||
bool xbps_add_obj_to_dict(prop_dictionary_t, prop_object_t,
|
bool xbps_add_obj_to_dict(prop_dictionary_t, prop_object_t,
|
||||||
|
@ -121,6 +130,8 @@ prop_dictionary_t xbps_find_pkg_from_plist(const char *, const char *);
|
||||||
prop_dictionary_t xbps_find_pkg_installed_from_plist(const char *);
|
prop_dictionary_t xbps_find_pkg_installed_from_plist(const char *);
|
||||||
bool xbps_find_string_in_array(prop_array_t, const char *);
|
bool xbps_find_string_in_array(prop_array_t, const char *);
|
||||||
|
|
||||||
|
prop_dictionary_t xbps_get_regpkgdb_dict(void);
|
||||||
|
void xbps_release_regpkgdb_dict(void);
|
||||||
prop_object_iterator_t xbps_get_array_iter_from_dict(prop_dictionary_t,
|
prop_object_iterator_t xbps_get_array_iter_from_dict(prop_dictionary_t,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,7 @@ store_dependency(prop_dictionary_t master, prop_dictionary_t origind,
|
||||||
{
|
{
|
||||||
prop_dictionary_t dict;
|
prop_dictionary_t dict;
|
||||||
prop_array_t array;
|
prop_array_t array;
|
||||||
size_t dirdepscnt = 0, indirdepscnt = 0;
|
const char *reqbyname, *repoloc;
|
||||||
const char *reqbyname, *repoloc, *originpkg;
|
|
||||||
bool indirectdep = false;
|
|
||||||
|
|
||||||
assert(origind != NULL);
|
assert(origind != NULL);
|
||||||
assert(depd != NULL);
|
assert(depd != NULL);
|
||||||
|
@ -59,25 +57,6 @@ store_dependency(prop_dictionary_t master, prop_dictionary_t origind,
|
||||||
prop_dictionary_get_cstring_nocopy(origind, "pkgname", &reqbyname);
|
prop_dictionary_get_cstring_nocopy(origind, "pkgname", &reqbyname);
|
||||||
prop_dictionary_get_cstring_nocopy(repod, "location-local", &repoloc);
|
prop_dictionary_get_cstring_nocopy(repod, "location-local", &repoloc);
|
||||||
|
|
||||||
/*
|
|
||||||
* Required dependency is not installed. Check if it's
|
|
||||||
* already registered in the chain, and update some objects
|
|
||||||
* or add the object into array otherwise.
|
|
||||||
*/
|
|
||||||
prop_dictionary_get_cstring_nocopy(master, "origin", &originpkg);
|
|
||||||
if (strcmp(originpkg, reqbyname)) {
|
|
||||||
indirectdep = true;
|
|
||||||
prop_dictionary_get_uint32(master, "indirectdeps_count",
|
|
||||||
&indirdepscnt);
|
|
||||||
prop_dictionary_set_uint32(master, "indirectdeps_count",
|
|
||||||
++indirdepscnt);
|
|
||||||
} else {
|
|
||||||
prop_dictionary_get_uint32(master, "directdeps_count",
|
|
||||||
&dirdepscnt);
|
|
||||||
prop_dictionary_set_uint32(master, "directdeps_count",
|
|
||||||
++dirdepscnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
dict = prop_dictionary_copy(depd);
|
dict = prop_dictionary_copy(depd);
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -91,7 +70,6 @@ store_dependency(prop_dictionary_t master, prop_dictionary_t origind,
|
||||||
* Add required objects into package dep's dictionary.
|
* Add required objects into package dep's dictionary.
|
||||||
*/
|
*/
|
||||||
prop_dictionary_set_cstring(dict, "repository", repoloc);
|
prop_dictionary_set_cstring(dict, "repository", repoloc);
|
||||||
prop_dictionary_set_bool(dict, "indirect_dep", indirectdep);
|
|
||||||
/*
|
/*
|
||||||
* Remove some unneeded objects.
|
* Remove some unneeded objects.
|
||||||
*/
|
*/
|
||||||
|
@ -144,16 +122,12 @@ add_missing_reqdep(prop_dictionary_t master, const char *pkgname,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg,
|
xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg)
|
||||||
prop_object_iterator_t iter)
|
|
||||||
{
|
{
|
||||||
prop_array_t pkg_rdeps, missing_rdeps;
|
prop_array_t pkg_rdeps, missing_rdeps;
|
||||||
prop_dictionary_t repod;
|
struct repository_data *rdata;
|
||||||
prop_object_t obj;
|
|
||||||
char *plist;
|
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
assert(pkg_props != NULL);
|
|
||||||
assert(pkg != NULL);
|
assert(pkg != NULL);
|
||||||
assert(iter != NULL);
|
assert(iter != NULL);
|
||||||
|
|
||||||
|
@ -165,35 +139,20 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg,
|
||||||
* Iterate over the repository pool and find out if we have
|
* Iterate over the repository pool and find out if we have
|
||||||
* all available binary packages.
|
* all available binary packages.
|
||||||
*/
|
*/
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||||
plist =
|
|
||||||
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
|
||||||
if (plist == NULL)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
repod = prop_dictionary_internalize_from_file(plist);
|
|
||||||
if (repod == NULL) {
|
|
||||||
free(plist);
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
free(plist);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This will find direct and indirect deps,
|
* This will find direct and indirect deps,
|
||||||
* if any of them is not there it will be added
|
* if any of them is not there it will be added
|
||||||
* into the missing_deps array.
|
* into the missing_deps array.
|
||||||
*/
|
*/
|
||||||
rv = find_repo_deps(master, repod, pkg, pkg_rdeps);
|
rv = find_repo_deps(master, rdata->rd_repod, pkg, pkg_rdeps);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
if (rv == ENOENT) {
|
if (rv == ENOENT) {
|
||||||
rv = 0;
|
rv = 0;
|
||||||
prop_object_release(repod);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
prop_object_release(repod);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prop_object_release(repod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
missing_rdeps = prop_dictionary_get(master, "missing_deps");
|
missing_rdeps = prop_dictionary_get(master, "missing_deps");
|
||||||
|
@ -204,27 +163,10 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg,
|
||||||
* If there are missing deps, iterate one more time
|
* If there are missing deps, iterate one more time
|
||||||
* just in case that indirect deps weren't found.
|
* just in case that indirect deps weren't found.
|
||||||
*/
|
*/
|
||||||
prop_object_iterator_reset(iter);
|
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
rv = find_repo_missing_deps(master, rdata->rd_repod, pkg);
|
||||||
plist =
|
if (rv != 0 && rv != ENOENT)
|
||||||
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
|
||||||
if (plist == NULL)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
repod = prop_dictionary_internalize_from_file(plist);
|
|
||||||
if (repod == NULL) {
|
|
||||||
free(plist);
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
free(plist);
|
|
||||||
|
|
||||||
rv = find_repo_missing_deps(master, repod, pkg);
|
|
||||||
if (rv != 0 && rv != ENOENT) {
|
|
||||||
prop_object_release(repod);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
|
|
||||||
prop_object_release(repod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
246
lib/findpkg.c
246
lib/findpkg.c
|
@ -34,18 +34,20 @@
|
||||||
|
|
||||||
#include <xbps_api.h>
|
#include <xbps_api.h>
|
||||||
|
|
||||||
static int create_pkg_props_dictionary(const char *);
|
|
||||||
|
|
||||||
static prop_dictionary_t pkg_props;
|
static prop_dictionary_t pkg_props;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
create_pkg_props_dictionary(const char *pkgname)
|
create_pkg_props_dictionary(void)
|
||||||
{
|
{
|
||||||
prop_array_t unsorted, missing;
|
prop_array_t unsorted, missing;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
static bool pkg_props_avail;
|
||||||
|
|
||||||
assert(pkgname != NULL);
|
assert(pkgname != NULL);
|
||||||
|
|
||||||
|
if (pkg_props_avail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pkg_props = prop_dictionary_create();
|
pkg_props = prop_dictionary_create();
|
||||||
if (pkg_props == NULL)
|
if (pkg_props == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -71,7 +73,7 @@ create_pkg_props_dictionary(const char *pkgname)
|
||||||
goto fail3;
|
goto fail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_set_cstring_nocopy(pkg_props, "origin", pkgname);
|
pkg_props_avail = true;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
@ -86,32 +88,37 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_get_pkg_props(const char *pkgname)
|
xbps_get_pkg_props(void)
|
||||||
{
|
{
|
||||||
prop_string_t origin;
|
|
||||||
|
|
||||||
if (pkg_props == NULL || prop_dictionary_count(pkg_props) == 0)
|
if (pkg_props == NULL || prop_dictionary_count(pkg_props) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
origin = prop_dictionary_get(pkg_props, "origin");
|
|
||||||
if (!prop_string_equals_cstring(origin, pkgname))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return prop_dictionary_copy(pkg_props);
|
return prop_dictionary_copy(pkg_props);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xbps_prepare_pkg(const char *pkgname)
|
xbps_prepare_repolist_data(void)
|
||||||
{
|
{
|
||||||
prop_dictionary_t repod = NULL, repolistd, pkgrd = NULL;
|
prop_dictionary_t dict = NULL;
|
||||||
prop_array_t array, pkgs_array;
|
prop_array_t array;
|
||||||
prop_object_t obj;
|
prop_object_t obj;
|
||||||
prop_object_iterator_t repolist_iter;
|
prop_object_iterator_t iter;
|
||||||
const char *repoloc, *rootdir;
|
struct repository_data *rdata;
|
||||||
|
const char *rootdir;
|
||||||
char *plist;
|
char *plist;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
static bool repodata_init;
|
||||||
|
|
||||||
assert(pkgname != NULL);
|
if (repodata_init == false) {
|
||||||
|
SIMPLEQ_INIT(&repodata_queue);
|
||||||
|
repodata_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdata = malloc(sizeof(struct repository_data));
|
||||||
|
if (rdata == NULL) {
|
||||||
|
rv = errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rootdir = xbps_get_rootdir();
|
rootdir = xbps_get_rootdir();
|
||||||
if (rootdir == NULL)
|
if (rootdir == NULL)
|
||||||
|
@ -119,79 +126,201 @@ xbps_prepare_pkg(const char *pkgname)
|
||||||
|
|
||||||
plist = xbps_xasprintf("%s/%s/%s", rootdir,
|
plist = xbps_xasprintf("%s/%s/%s", rootdir,
|
||||||
XBPS_META_PATH, XBPS_REPOLIST);
|
XBPS_META_PATH, XBPS_REPOLIST);
|
||||||
if (plist == NULL)
|
if (plist == NULL) {
|
||||||
return EINVAL;
|
rv = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
repolistd = prop_dictionary_internalize_from_file(plist);
|
dict = prop_dictionary_internalize_from_file(plist);
|
||||||
if (repolistd == NULL) {
|
if (dict == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return EINVAL;
|
rv = errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
free(plist);
|
free(plist);
|
||||||
|
|
||||||
array = prop_dictionary_get(repolistd, "repository-list");
|
array = prop_dictionary_get(dict, "repository-list");
|
||||||
if (array == NULL) {
|
if (array == NULL) {
|
||||||
prop_object_release(repolistd);
|
rv = EINVAL;
|
||||||
return EINVAL;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
repolist_iter = prop_array_iterator(array);
|
iter = prop_array_iterator(array);
|
||||||
if (repolist_iter == NULL) {
|
if (iter == NULL) {
|
||||||
prop_object_release(repolistd);
|
rv = ENOMEM;
|
||||||
return ENOMEM;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(repolist_iter)) != NULL) {
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
/*
|
/*
|
||||||
* Iterate over the repository pool and find out if we have
|
* Iterate over the repository pool and add the dictionary
|
||||||
* the binary package.
|
* for current repository into the queue.
|
||||||
*/
|
*/
|
||||||
plist =
|
plist =
|
||||||
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
||||||
if (plist == NULL)
|
if (plist == NULL) {
|
||||||
return EINVAL;
|
rv = EINVAL;
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
repod = prop_dictionary_internalize_from_file(plist);
|
rdata->rd_repod = prop_dictionary_internalize_from_file(plist);
|
||||||
if (repod == NULL) {
|
if (rdata->rd_repod == NULL) {
|
||||||
free(plist);
|
free(plist);
|
||||||
return errno;
|
rv = errno;
|
||||||
|
goto out2;
|
||||||
}
|
}
|
||||||
free(plist);
|
free(plist);
|
||||||
|
SIMPLEQ_INSERT_TAIL(&repodata_queue, rdata, chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
out2:
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
|
out:
|
||||||
|
prop_object_release(dict);
|
||||||
|
if (rv != 0)
|
||||||
|
xbps_release_repolist_data();
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xbps_release_repolist_data(void)
|
||||||
|
{
|
||||||
|
struct repository_data *rdata;
|
||||||
|
|
||||||
|
while ((rdata = SIMPLEQ_FIRST(&repodata_queue)) != NULL) {
|
||||||
|
SIMPLEQ_REMOVE(&repodata_queue, rdata, repository_data, chain);
|
||||||
|
prop_object_release(rdata->rd_repod);
|
||||||
|
free(rdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
|
||||||
|
{
|
||||||
|
prop_dictionary_t pkgrd = NULL;
|
||||||
|
prop_array_t unsorted;
|
||||||
|
struct repository_data *rdata;
|
||||||
|
const char *repoloc, *repover, *instver;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
assert(pkgname != NULL);
|
||||||
|
assert(instpkg != NULL);
|
||||||
|
|
||||||
|
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||||
/*
|
/*
|
||||||
* Get the package dictionary from current repository.
|
* Get the package dictionary from current repository.
|
||||||
* If it's not there, pass to the next repository.
|
* If it's not there, pass to the next repository.
|
||||||
*/
|
*/
|
||||||
pkgrd = xbps_find_pkg_in_dict(repod, "packages", pkgname);
|
pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||||
if (pkgrd == NULL) {
|
"packages", pkgname);
|
||||||
prop_object_release(repod);
|
if (pkgrd != NULL) {
|
||||||
continue;
|
/*
|
||||||
}
|
* Check if installed version is >= than the
|
||||||
break;
|
* one available in current repository.
|
||||||
}
|
*/
|
||||||
prop_object_iterator_reset(repolist_iter);
|
prop_dictionary_get_cstring_nocopy(instpkg,
|
||||||
|
"version", &instver);
|
||||||
|
prop_dictionary_get_cstring_nocopy(pkgrd,
|
||||||
|
"version", &repover);
|
||||||
|
if (xbps_cmpver_versions(instver, repover) >= 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (pkgrd == NULL) {
|
break;
|
||||||
rv = EAGAIN;
|
}
|
||||||
goto out2;
|
|
||||||
}
|
}
|
||||||
|
if (pkgrd == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create master pkg dictionary.
|
* Create master pkg dictionary.
|
||||||
*/
|
*/
|
||||||
if ((rv = create_pkg_props_dictionary(pkgname)) != 0)
|
if ((rv = create_pkg_props_dictionary()) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set repository in pkg dictionary.
|
* Set repository in pkg dictionary.
|
||||||
*/
|
*/
|
||||||
if (!prop_dictionary_get_cstring_nocopy(repod,
|
if (!prop_dictionary_get_cstring_nocopy(rdata->rd_repod,
|
||||||
"location-local", &repoloc)) {
|
"location-local", &repoloc)) {
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
prop_dictionary_set_cstring(pkgrd, "repository", repoloc);
|
prop_dictionary_set_cstring(pkgrd, "repository", repoloc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Construct the dependency chain for this package.
|
||||||
|
*/
|
||||||
|
if ((rv = xbps_find_deps_in_pkg(pkg_props, pkgrd)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add required package dictionary into the packages
|
||||||
|
* dictionary.
|
||||||
|
*/
|
||||||
|
unsorted = prop_dictionary_get(pkg_props, "unsorted_deps");
|
||||||
|
if (unsorted == NULL) {
|
||||||
|
rv = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prop_array_add(unsorted, pkgrd))
|
||||||
|
rv = errno;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (rv != 0)
|
||||||
|
xbps_release_repolist_data();
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xbps_prepare_pkg(const char *pkgname)
|
||||||
|
{
|
||||||
|
prop_dictionary_t pkgrd = NULL;
|
||||||
|
prop_array_t pkgs_array;
|
||||||
|
struct repository_data *rdata;
|
||||||
|
const char *repoloc;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
assert(pkgname != NULL);
|
||||||
|
|
||||||
|
if ((rv = xbps_prepare_repolist_data()) != 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||||
|
/*
|
||||||
|
* Get the package dictionary from current repository.
|
||||||
|
* If it's not there, pass to the next repository.
|
||||||
|
*/
|
||||||
|
pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||||
|
"packages", pkgname);
|
||||||
|
if (pkgrd != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pkgrd == NULL) {
|
||||||
|
rv = EAGAIN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create master pkg dictionary.
|
||||||
|
*/
|
||||||
|
if ((rv = create_pkg_props_dictionary()) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set repository in pkg dictionary.
|
||||||
|
*/
|
||||||
|
if (!prop_dictionary_get_cstring_nocopy(rdata->rd_repod,
|
||||||
|
"location-local", &repoloc)) {
|
||||||
|
rv = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
prop_dictionary_set_cstring(pkgrd, "repository", repoloc);
|
||||||
|
prop_dictionary_set_cstring(pkgrd, "origin", pkgname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if this package needs dependencies.
|
* Check if this package needs dependencies.
|
||||||
*/
|
*/
|
||||||
|
@ -199,8 +328,7 @@ xbps_prepare_pkg(const char *pkgname)
|
||||||
/*
|
/*
|
||||||
* Construct the dependency chain for this package.
|
* Construct the dependency chain for this package.
|
||||||
*/
|
*/
|
||||||
if ((rv = xbps_find_deps_in_pkg(pkg_props, pkgrd,
|
if ((rv = xbps_find_deps_in_pkg(pkg_props, pkgrd)) != 0)
|
||||||
repolist_iter)) != 0)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,7 +346,8 @@ xbps_prepare_pkg(const char *pkgname)
|
||||||
rv = errno;
|
rv = errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!prop_dictionary_set(pkg_props, "packages", pkgs_array)) {
|
if (!prop_dictionary_set(pkg_props, "packages",
|
||||||
|
pkgs_array)) {
|
||||||
rv = errno;
|
rv = errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -235,18 +364,11 @@ xbps_prepare_pkg(const char *pkgname)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prop_array_add(pkgs_array, pkgrd)) {
|
if (!prop_array_add(pkgs_array, pkgrd))
|
||||||
rv = errno;
|
rv = errno;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
prop_dictionary_remove(pkg_props, "unsorted_deps");
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
prop_object_release(repod);
|
xbps_release_repolist_data();
|
||||||
out2:
|
|
||||||
prop_object_iterator_release(repolist_iter);
|
|
||||||
prop_object_release(repolistd);
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
47
lib/plist.c
47
lib/plist.c
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include <xbps_api.h>
|
#include <xbps_api.h>
|
||||||
|
|
||||||
|
static prop_dictionary_t regpkgdb_dict;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
|
xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
|
||||||
const char *key)
|
const char *key)
|
||||||
|
@ -160,18 +162,14 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
|
||||||
prop_dictionary_t
|
prop_dictionary_t
|
||||||
xbps_find_pkg_installed_from_plist(const char *pkgname)
|
xbps_find_pkg_installed_from_plist(const char *pkgname)
|
||||||
{
|
{
|
||||||
prop_dictionary_t pkgd;
|
prop_dictionary_t instd, pkgd;
|
||||||
const char *rootdir;
|
|
||||||
char *plist;
|
|
||||||
|
|
||||||
rootdir = xbps_get_rootdir();
|
instd = xbps_get_regpkgdb_dict();
|
||||||
plist = xbps_xasprintf("%s/%s/%s", rootdir,
|
if (instd == NULL)
|
||||||
XBPS_META_PATH, XBPS_REGPKGDB);
|
|
||||||
if (plist == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pkgd = xbps_find_pkg_from_plist(plist, pkgname);
|
pkgd = xbps_find_pkg_in_dict(instd, "packages", pkgname);
|
||||||
free(plist);
|
xbps_release_regpkgdb_dict();
|
||||||
|
|
||||||
return pkgd;
|
return pkgd;
|
||||||
}
|
}
|
||||||
|
@ -202,6 +200,37 @@ xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop_dictionary_t
|
||||||
|
xbps_get_regpkgdb_dict(void)
|
||||||
|
{
|
||||||
|
const char *rootdir;
|
||||||
|
char *plist;
|
||||||
|
|
||||||
|
if (regpkgdb_dict == NULL) {
|
||||||
|
rootdir = xbps_get_rootdir();
|
||||||
|
plist = xbps_xasprintf("%s/%s/%s", rootdir,
|
||||||
|
XBPS_META_PATH, XBPS_REGPKGDB);
|
||||||
|
if (plist == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
regpkgdb_dict = prop_dictionary_internalize_from_file(plist);
|
||||||
|
if (regpkgdb_dict == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop_dictionary_copy(regpkgdb_dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xbps_release_regpkgdb_dict(void)
|
||||||
|
{
|
||||||
|
if (regpkgdb_dict == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prop_object_release(regpkgdb_dict);
|
||||||
|
regpkgdb_dict = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_find_string_in_array(prop_array_t array, const char *val)
|
xbps_find_string_in_array(prop_array_t array, const char *val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ xbps_sort_pkg_deps(prop_dictionary_t chaindeps)
|
||||||
prop_object_t obj, obj2;
|
prop_object_t obj, obj2;
|
||||||
prop_object_iterator_t iter, iter2;
|
prop_object_iterator_t iter, iter2;
|
||||||
struct sorted_dependency *sdep;
|
struct sorted_dependency *sdep;
|
||||||
size_t indirdepscnt = 0, dirdepscnt = 0, rundepscnt = 0, cnt = 0;
|
size_t ndeps = 0, rundepscnt = 0, cnt = 0;
|
||||||
const char *pkgname;
|
const char *pkgname;
|
||||||
char *curpkgnamedep;
|
char *curpkgnamedep;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
@ -84,10 +84,7 @@ xbps_sort_pkg_deps(prop_dictionary_t chaindeps)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_dictionary_get_uint32(chaindeps, "indirectdeps_count",
|
ndeps = prop_array_count(unsorted);
|
||||||
&indirdepscnt);
|
|
||||||
prop_dictionary_get_uint32(chaindeps, "directdeps_count",
|
|
||||||
&dirdepscnt);
|
|
||||||
unsorted = prop_dictionary_get(chaindeps, "unsorted_deps");
|
unsorted = prop_dictionary_get(chaindeps, "unsorted_deps");
|
||||||
|
|
||||||
iter = prop_array_iterator(unsorted);
|
iter = prop_array_iterator(unsorted);
|
||||||
|
@ -159,7 +156,7 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate until all deps are processed. */
|
/* Iterate until all deps are processed. */
|
||||||
if (cnt < dirdepscnt + indirdepscnt) {
|
if (cnt < ndeps) {
|
||||||
prop_object_iterator_reset(iter);
|
prop_object_iterator_reset(iter);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
@ -179,14 +176,16 @@ again:
|
||||||
* Sanity check that the array contains the same number of
|
* Sanity check that the array contains the same number of
|
||||||
* objects than the total number of required dependencies.
|
* objects than the total number of required dependencies.
|
||||||
*/
|
*/
|
||||||
cnt = dirdepscnt + indirdepscnt;
|
if (ndeps != prop_array_count(sorted)) {
|
||||||
if (cnt != prop_array_count(sorted)) {
|
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prop_dictionary_set(chaindeps, "packages", sorted))
|
if (!prop_dictionary_set(chaindeps, "packages", sorted))
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
|
|
||||||
|
prop_dictionary_remove(chaindeps, "unsorted_deps");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/*
|
/*
|
||||||
* Release resources used by temporary sorting.
|
* Release resources used by temporary sorting.
|
||||||
|
|
|
@ -125,7 +125,7 @@ xbps_check_is_installed_pkg(const char *pkg)
|
||||||
dict = xbps_find_pkg_installed_from_plist(pkgname);
|
dict = xbps_find_pkg_installed_from_plist(pkgname);
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
free(pkgname);
|
free(pkgname);
|
||||||
return -1; /* not installed */
|
return -2; /* not installed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get version from installed package */
|
/* Get version from installed package */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue