Major changes in libxbps to implement caching in some cases.
libxbps: - Moved repolist code to lib/repository_pool.c. - Renamed xbps_{prepare,release}_repolist_data() to xbps_repository_pool_{init,release} respectively. - Moved regpkgdb dict code to lib/regpkgs_dictionary.c. - Renamed xbps_{prepare,release}_regpkgdb_dict() to xbps_regpkgs_dictionary_{init,release} respectively. - Use a global reference count for repository_pool and regpkgs_dictionary, this gives a substantial performance gain while looking for dependencies in repository pool, among other things. - Make xbps_find_pkg_* functions return errno and use it to detect for spurious errors in code using them. - Add code to detect when a dependency is already unpacked. xbps-bin: - Do not set pkg state to unpacked in the transaction, it's set already while a package is unpacked. - While installing or updating packages, it now knows when a dependency is already unpacked and shows it as "unconfigured". Bump XBPS_RELVER to 20091126. --HG-- extra : convert_revision : xtraeme%40gmail.com-20091126022250-uu8x0fa86l4scb5x
This commit is contained in:
parent
fa7e3a3a7e
commit
87a216fd11
@ -50,29 +50,33 @@ xbps_check_pkg_integrity_all(void)
|
||||
{
|
||||
prop_dictionary_t d;
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
prop_object_iterator_t iter = NULL;
|
||||
const char *pkgname, *version;
|
||||
int rv = 0;
|
||||
size_t npkgs = 0, nbrokenpkgs = 0;
|
||||
|
||||
d = xbps_prepare_regpkgdb_dict();
|
||||
d = xbps_regpkgs_dictionary_init();
|
||||
if (d == NULL)
|
||||
return ENODEV;
|
||||
|
||||
iter = xbps_get_array_iter_from_dict(d, "packages");
|
||||
if (iter == NULL)
|
||||
return ENOENT;
|
||||
if (iter == NULL) {
|
||||
rv = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgname", &pkgname)) {
|
||||
prop_object_iterator_release(iter);
|
||||
return errno;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"version", &version)) {
|
||||
prop_object_iterator_release(iter);
|
||||
return errno;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
printf("Checking %s-%s ...\n", pkgname, version);
|
||||
if ((rv = xbps_check_pkg_integrity(pkgname)) != 0)
|
||||
@ -80,11 +84,15 @@ xbps_check_pkg_integrity_all(void)
|
||||
npkgs++;
|
||||
printf("\033[1A\033[K");
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
|
||||
printf("%zu package%s processed: %zu broken.\n", npkgs,
|
||||
npkgs == 1 ? "" : "s", nbrokenpkgs);
|
||||
|
||||
out:
|
||||
if (iter)
|
||||
prop_object_iterator_release(iter);
|
||||
|
||||
xbps_regpkgs_dictionary_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -312,7 +320,6 @@ out1:
|
||||
prop_object_release(propsd);
|
||||
out:
|
||||
prop_object_release(pkgd);
|
||||
xbps_release_regpkgdb_dict();
|
||||
|
||||
if (broken)
|
||||
rv = EINVAL;
|
||||
|
@ -246,7 +246,9 @@ show_transaction_sizes(prop_object_iterator_t iter)
|
||||
uint64_t tsize = 0, dlsize = 0, instsize = 0;
|
||||
const char *tract;
|
||||
char size[64];
|
||||
bool trans_inst = false, trans_up = false;
|
||||
bool trans_inst, trans_up, trans_conf;
|
||||
|
||||
trans_inst = trans_up = trans_conf = false;
|
||||
|
||||
/*
|
||||
* Iterate over the list of packages that are going to be
|
||||
@ -275,6 +277,8 @@ show_transaction_sizes(prop_object_iterator_t iter)
|
||||
trans_inst = true;
|
||||
else if (strcmp(tract, "update") == 0)
|
||||
trans_up = true;
|
||||
else if (strcmp(tract, "configure") == 0)
|
||||
trans_conf = true;
|
||||
}
|
||||
prop_object_iterator_reset(iter);
|
||||
|
||||
@ -291,6 +295,11 @@ show_transaction_sizes(prop_object_iterator_t iter)
|
||||
show_package_list(iter, "update");
|
||||
printf("\n\n");
|
||||
}
|
||||
if (trans_conf) {
|
||||
printf("The following packages will be configured:\n\n");
|
||||
show_package_list(iter, "configure");
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Show total download/installed size for all required packages.
|
||||
@ -386,7 +395,7 @@ xbps_exec_transaction(const char *pkgname, bool force, bool update)
|
||||
"repository pool.\n", pkgname);
|
||||
return rv;
|
||||
} else if (rv != 0 && rv != ENOENT) {
|
||||
printf("Unexpected error: %s", strerror(rv));
|
||||
printf("Unexpected error: %s", strerror(errno));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@ -410,13 +419,6 @@ xbps_exec_transaction(const char *pkgname, bool force, bool update)
|
||||
show_missing_deps(trans->dict, pkgname);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if (!prop_dictionary_get_cstring_nocopy(trans->dict,
|
||||
"origin", &trans->originpkgname)) {
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
/*
|
||||
* Sort the package transaction dictionary.
|
||||
@ -426,8 +428,13 @@ xbps_exec_transaction(const char *pkgname, bool force, bool update)
|
||||
strerror(rv));
|
||||
goto out2;
|
||||
}
|
||||
} else {
|
||||
if (!prop_dictionary_get_cstring_nocopy(trans->dict,
|
||||
"origin", &trans->originpkgname)) {
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* It's time to run the transaction!
|
||||
*/
|
||||
@ -654,13 +661,6 @@ exec_transaction(struct transaction *trans)
|
||||
return rv;
|
||||
}
|
||||
autoinst = false;
|
||||
/*
|
||||
* Set package state to unpacked in the transaction
|
||||
* dictionary.
|
||||
*/
|
||||
if ((rv = xbps_set_pkg_state_dictionary(obj,
|
||||
XBPS_PKG_STATE_UNPACKED)) != 0)
|
||||
return rv;
|
||||
}
|
||||
prop_object_iterator_reset(trans->iter);
|
||||
/*
|
||||
|
@ -157,7 +157,7 @@ main(int argc, char **argv)
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGQUIT, &sa, NULL);
|
||||
|
||||
if ((dict = xbps_prepare_regpkgdb_dict()) == NULL) {
|
||||
if ((dict = xbps_regpkgs_dictionary_init()) == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
rv = errno;
|
||||
printf("Couldn't initialized regpkgdb dict: %s\n",
|
||||
@ -319,8 +319,6 @@ out:
|
||||
static void
|
||||
cleanup(int signum)
|
||||
{
|
||||
xbps_release_repolist_data();
|
||||
xbps_release_regpkgdb_dict();
|
||||
|
||||
xbps_regpkgs_dictionary_release();
|
||||
exit(signum);
|
||||
}
|
||||
|
@ -69,8 +69,6 @@ xbps_show_pkg_deps(const char *pkgname)
|
||||
prop_object_release(propsd);
|
||||
prop_object_release(pkgd);
|
||||
|
||||
xbps_release_regpkgdb_dict();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -89,7 +87,6 @@ xbps_show_pkg_reverse_deps(const char *pkgname)
|
||||
rv = xbps_callback_array_iter_in_dict(pkgd, "requiredby",
|
||||
list_strings_sep_in_array, NULL);
|
||||
prop_object_release(pkgd);
|
||||
xbps_release_regpkgdb_dict();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -129,7 +129,13 @@ xbps_repo_addpkg_index(prop_dictionary_t idxdict, const char *filedir,
|
||||
* pass to the next one.
|
||||
*/
|
||||
curpkgd = xbps_find_pkg_in_dict(idxdict, "packages", pkgname);
|
||||
if (curpkgd) {
|
||||
if (curpkgd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
prop_object_release(newpkgd);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
} else if (curpkgd) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(curpkgd,
|
||||
"version", ®ver)) {
|
||||
prop_object_release(newpkgd);
|
||||
|
@ -96,7 +96,7 @@ main(int argc, char **argv)
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
if ((rv = xbps_prepare_repolist_data()) != 0) {
|
||||
if ((rv = xbps_repository_pool_init()) != 0) {
|
||||
if (rv != ENOENT) {
|
||||
printf("E: cannot get repository list pool! %s\n",
|
||||
strerror(rv));
|
||||
@ -202,6 +202,6 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
out:
|
||||
xbps_release_repolist_data();
|
||||
xbps_repository_pool_release();
|
||||
exit(rv ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -207,7 +207,10 @@ show_pkg_info_from_repolist(const char *pkgname)
|
||||
repo_pkgd = xbps_find_pkg_in_dict(rd->rd_repod,
|
||||
"packages", pkgname);
|
||||
if (repo_pkgd == NULL) {
|
||||
errno = ENOENT;
|
||||
if (errno && errno != ENOENT) {
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
url = xbps_get_path_from_pkg_dict_repo(repo_pkgd, rd->rd_uri);
|
||||
@ -243,7 +246,10 @@ show_pkg_deps_from_repolist(const char *pkgname)
|
||||
SIMPLEQ_FOREACH(rd, &repodata_queue, chain) {
|
||||
pkgd = xbps_find_pkg_in_dict(rd->rd_repod, "packages", pkgname);
|
||||
if (pkgd == NULL) {
|
||||
errno = ENOENT;
|
||||
if (errno != ENOENT) {
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
|
@ -113,7 +113,7 @@ show_pkg_info(prop_dictionary_t dict)
|
||||
|
||||
obj = prop_dictionary_get(dict, "short_desc");
|
||||
if (obj && prop_object_type(obj) == PROP_TYPE_STRING)
|
||||
printf("Description: %s\n", prop_string_cstring_nocopy(obj));
|
||||
printf("Description: %s", prop_string_cstring_nocopy(obj));
|
||||
|
||||
obj = prop_dictionary_get(dict, "long_desc");
|
||||
if (obj && prop_object_type(obj) == PROP_TYPE_STRING)
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <archive_entry.h>
|
||||
|
||||
/* Current release version */
|
||||
#define XBPS_RELVER "20091125"
|
||||
#define XBPS_RELVER "20091126"
|
||||
|
||||
/* Default root PATH for xbps to store metadata info. */
|
||||
#define XBPS_META_PATH "/var/db/xbps"
|
||||
@ -111,18 +111,9 @@ int SYMEXPORT xbps_humanize_number(char *, size_t, int64_t, const char *,
|
||||
int, int);
|
||||
|
||||
/* From lib/findpkg.c */
|
||||
struct repository_data {
|
||||
SIMPLEQ_ENTRY(repository_data) chain;
|
||||
prop_dictionary_t rd_repod;
|
||||
char *rd_uri;
|
||||
};
|
||||
SYMEXPORT SIMPLEQ_HEAD(, repository_data) repodata_queue;
|
||||
|
||||
int SYMEXPORT xbps_prepare_pkg(const char *);
|
||||
int SYMEXPORT xbps_find_new_pkg(const char *, prop_dictionary_t);
|
||||
int SYMEXPORT xbps_find_new_packages(void);
|
||||
int SYMEXPORT xbps_prepare_repolist_data(void);
|
||||
void SYMEXPORT xbps_release_repolist_data(void);
|
||||
prop_dictionary_t SYMEXPORT xbps_get_pkg_props(void);
|
||||
|
||||
/* From lib/depends.c */
|
||||
@ -156,8 +147,6 @@ prop_dictionary_t SYMEXPORT
|
||||
xbps_find_pkg_installed_from_plist(const char *);
|
||||
bool SYMEXPORT xbps_find_string_in_array(prop_array_t, const char *);
|
||||
|
||||
prop_dictionary_t SYMEXPORT xbps_prepare_regpkgdb_dict(void);
|
||||
void SYMEXPORT xbps_release_regpkgdb_dict(void);
|
||||
prop_object_iterator_t SYMEXPORT
|
||||
xbps_get_array_iter_from_dict(prop_dictionary_t, const char *);
|
||||
|
||||
@ -177,6 +166,10 @@ int SYMEXPORT xbps_purge_all_pkgs(void);
|
||||
int SYMEXPORT xbps_register_pkg(prop_dictionary_t, bool);
|
||||
int SYMEXPORT xbps_unregister_pkg(const char *);
|
||||
|
||||
/* From lib/regpkgs_dictionary.c */
|
||||
prop_dictionary_t SYMEXPORT xbps_regpkgs_dictionary_init(void);
|
||||
void SYMEXPORT xbps_regpkgs_dictionary_release(void);
|
||||
|
||||
/* From lib/remove.c */
|
||||
int SYMEXPORT xbps_remove_pkg(const char *, const char *, bool);
|
||||
|
||||
@ -192,6 +185,17 @@ prop_dictionary_t SYMEXPORT
|
||||
prop_dictionary_t SYMEXPORT
|
||||
xbps_get_pkg_plist_dict_from_url(const char *, const char *);
|
||||
|
||||
/* From lib/repository_pool.c */
|
||||
struct repository_data {
|
||||
SIMPLEQ_ENTRY(repository_data) chain;
|
||||
prop_dictionary_t rd_repod;
|
||||
char *rd_uri;
|
||||
};
|
||||
SYMEXPORT SIMPLEQ_HEAD(, repository_data) repodata_queue;
|
||||
|
||||
int SYMEXPORT xbps_repository_pool_init(void);
|
||||
void SYMEXPORT xbps_repository_pool_release(void);
|
||||
|
||||
/* From lib/requiredby.c */
|
||||
int SYMEXPORT xbps_requiredby_pkg_add(prop_array_t, prop_dictionary_t);
|
||||
int SYMEXPORT xbps_requiredby_pkg_remove(const char *);
|
||||
|
@ -18,7 +18,7 @@ OBJS += configure.o cmpver.o depends.o download.o fexec.o findpkg.o
|
||||
OBJS += humanize_number.o orphans.o plist.o purge.o register.o remove.o
|
||||
OBJS += repository.o requiredby.o sha256.o sortdeps.o state.o
|
||||
OBJS += sync_remote_pkgidx.o unpack.o util.o pkgmatch.o
|
||||
OBJS += repository_plist.o
|
||||
OBJS += regpkgs_dictionary.o repository_plist.o repository_pool.o
|
||||
|
||||
.PHONY: all
|
||||
all: libfetch libxbps.so libxbps.a
|
||||
|
@ -43,13 +43,14 @@ xbps_configure_all_pkgs(void)
|
||||
int rv = 0;
|
||||
pkg_state_t state = 0;
|
||||
|
||||
d = xbps_prepare_regpkgdb_dict();
|
||||
if (d == NULL)
|
||||
return ENODEV;
|
||||
if ((d = xbps_regpkgs_dictionary_init()) == NULL)
|
||||
return errno;
|
||||
|
||||
iter = xbps_get_array_iter_from_dict(d, "packages");
|
||||
if (iter == NULL)
|
||||
return ENOENT;
|
||||
if (iter == NULL) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
@ -70,6 +71,8 @@ xbps_configure_all_pkgs(void)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
out:
|
||||
xbps_regpkgs_dictionary_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -108,7 +111,7 @@ xbps_configure_pkg(const char *pkgname, const char *version, bool check_state)
|
||||
|
||||
pkgd = xbps_find_pkg_installed_from_plist(pkgname);
|
||||
if (pkgd == NULL)
|
||||
return ENOENT;
|
||||
return errno;
|
||||
|
||||
if (!prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"version", &lver)) {
|
||||
@ -131,8 +134,10 @@ xbps_configure_pkg(const char *pkgname, const char *version, bool check_state)
|
||||
if (strcmp(rootdir, "") == 0)
|
||||
rootdir = "/";
|
||||
|
||||
if (chdir(rootdir) == -1)
|
||||
if (chdir(rootdir) == -1) {
|
||||
free(buf);
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (access(buf, X_OK) == 0) {
|
||||
if ((rv = xbps_file_chdir_exec(rootdir, buf, "post",
|
||||
|
@ -89,12 +89,6 @@ store_dependency(prop_dictionary_t master, prop_dictionary_t depd,
|
||||
prop_object_release(dict);
|
||||
return errno;
|
||||
}
|
||||
/*
|
||||
* Remove some unneeded objects.
|
||||
*/
|
||||
prop_dictionary_remove(dict, "conf_files");
|
||||
prop_dictionary_remove(dict, "maintainer");
|
||||
prop_dictionary_remove(dict, "long_desc");
|
||||
|
||||
/*
|
||||
* Add the dictionary into the array.
|
||||
@ -112,12 +106,16 @@ add_missing_reqdep(prop_dictionary_t master, const char *pkgname,
|
||||
const char *version)
|
||||
{
|
||||
prop_array_t missing_rdeps;
|
||||
prop_dictionary_t mdepd;
|
||||
prop_dictionary_t mdepd, tmpd;
|
||||
|
||||
assert(array != NULL);
|
||||
assert(reqdep != NULL);
|
||||
|
||||
if (xbps_find_pkg_in_dict(master, "missing_deps", pkgname))
|
||||
tmpd = xbps_find_pkg_in_dict(master, "missing_deps", pkgname);
|
||||
if (tmpd == NULL) {
|
||||
if (errno && errno != ENOENT)
|
||||
return errno;
|
||||
} else if (tmpd)
|
||||
return EEXIST;
|
||||
|
||||
mdepd = prop_dictionary_create();
|
||||
@ -159,6 +157,9 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg)
|
||||
if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
|
||||
return errno;
|
||||
|
||||
if ((rv = xbps_repository_pool_init()) != 0)
|
||||
return rv;
|
||||
|
||||
DPRINTF(("Checking rundeps for %s.\n", pkgname));
|
||||
/*
|
||||
* Iterate over the repository pool and find out if we have
|
||||
@ -173,8 +174,8 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg)
|
||||
if ((rv = find_repo_deps(master, rdata->rd_repod,
|
||||
rdata->rd_uri, pkg_rdeps)) != 0) {
|
||||
DPRINTF(("Error '%s' while checking rundeps!\n",
|
||||
strerror(rv)));
|
||||
return rv;
|
||||
strerror(errno)));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +184,7 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg)
|
||||
*/
|
||||
missing_rdeps = prop_dictionary_get(master, "missing_deps");
|
||||
if (prop_array_count(missing_rdeps) == 0)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Iterate one more time, but this time with missing deps
|
||||
@ -194,10 +195,12 @@ xbps_find_deps_in_pkg(prop_dictionary_t master, prop_dictionary_t pkg)
|
||||
if ((rv = find_repo_deps(master, rdata->rd_repod,
|
||||
rdata->rd_uri, missing_rdeps)) != 0) {
|
||||
DPRINTF(("Error '%s' while checking for"
|
||||
"missing rundeps!\n", strerror(rv)));
|
||||
return rv;
|
||||
"missing rundeps!\n", strerror(errno)));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
xbps_repository_pool_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -210,6 +213,7 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
|
||||
prop_array_t curpkg_rdeps;
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
pkg_state_t state = 0;
|
||||
const char *reqpkg, *reqvers, *pkg_queued;
|
||||
char *pkgname;
|
||||
int rv = 0;
|
||||
@ -260,7 +264,13 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
|
||||
* dependency pattern is matched.
|
||||
*/
|
||||
curpkgd = xbps_find_pkg_in_dict(master, "unsorted_deps", pkgname);
|
||||
if (curpkgd) {
|
||||
if (curpkgd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
free(pkgname);
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
} else if (curpkgd) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(curpkgd,
|
||||
"pkgver", &pkg_queued)) {
|
||||
DPRINTF(("pkgver failed %s\n", reqpkg));
|
||||
@ -283,6 +293,12 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
|
||||
*/
|
||||
curpkgd = xbps_find_pkg_in_dict(repo, "packages", pkgname);
|
||||
if (curpkgd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
free(pkgname);
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = add_missing_reqdep(master, pkgname, reqvers);
|
||||
if (rv != 0 && rv != EEXIST) {
|
||||
DPRINTF(("add missing reqdep failed %s\n",
|
||||
@ -305,16 +321,32 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
|
||||
/*
|
||||
* If package is installed but version doesn't satisfy
|
||||
* the dependency mark it as an update, otherwise as
|
||||
* an install.
|
||||
* an install. Packages that were unpacked previously
|
||||
* will be marked as pending to be configured.
|
||||
*/
|
||||
tmpd = xbps_find_pkg_installed_from_plist(pkgname);
|
||||
if (tmpd != NULL) {
|
||||
prop_dictionary_set_cstring_nocopy(curpkgd,
|
||||
"trans-action", "update");
|
||||
prop_object_release(tmpd);
|
||||
} else {
|
||||
if (tmpd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
free(pkgname);
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
prop_dictionary_set_cstring_nocopy(curpkgd,
|
||||
"trans-action", "install");
|
||||
} else if (tmpd) {
|
||||
rv = xbps_get_pkg_state_installed(pkgname, &state);
|
||||
if (rv != 0) {
|
||||
prop_object_release(tmpd);
|
||||
break;
|
||||
}
|
||||
if (state == XBPS_PKG_STATE_INSTALLED)
|
||||
prop_dictionary_set_cstring_nocopy(curpkgd,
|
||||
"trans-action", "update");
|
||||
else
|
||||
prop_dictionary_set_cstring_nocopy(curpkgd,
|
||||
"trans-action", "configure");
|
||||
|
||||
prop_object_release(tmpd);
|
||||
}
|
||||
/*
|
||||
* Package is on repo, add it into the dictionary.
|
||||
@ -357,7 +389,7 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
|
||||
if ((rv = find_repo_deps(master, repo, repoloc,
|
||||
curpkg_rdeps)) != 0) {
|
||||
DPRINTF(("Error checking %s rundeps %s\n",
|
||||
reqpkg, strerror(rv)));
|
||||
reqpkg, strerror(errno)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
185
lib/findpkg.c
185
lib/findpkg.c
@ -93,111 +93,6 @@ xbps_get_pkg_props(void)
|
||||
return pkg_props;
|
||||
}
|
||||
|
||||
int SYMEXPORT
|
||||
xbps_prepare_repolist_data(void)
|
||||
{
|
||||
prop_dictionary_t dict = NULL;
|
||||
prop_array_t array;
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
struct repository_data *rdata;
|
||||
char *plist;
|
||||
int rv = 0;
|
||||
static bool repodata_initialized;
|
||||
|
||||
if (repodata_initialized)
|
||||
return 0;
|
||||
|
||||
SIMPLEQ_INIT(&repodata_queue);
|
||||
|
||||
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
|
||||
XBPS_META_PATH, XBPS_REPOLIST);
|
||||
if (plist == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
free(plist);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
free(plist);
|
||||
|
||||
array = prop_dictionary_get(dict, "repository-list");
|
||||
if (array == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
iter = prop_array_iterator(array);
|
||||
if (iter == NULL) {
|
||||
rv = ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
/*
|
||||
* Iterate over the repository pool and add the dictionary
|
||||
* for current repository into the queue.
|
||||
*/
|
||||
plist =
|
||||
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
||||
if (plist == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
rdata = malloc(sizeof(struct repository_data));
|
||||
if (rdata == NULL) {
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
rdata->rd_uri = prop_string_cstring(obj);
|
||||
if (rdata->rd_uri == NULL) {
|
||||
free(plist);
|
||||
rv = EINVAL;
|
||||
goto out2;
|
||||
}
|
||||
rdata->rd_repod = prop_dictionary_internalize_from_file(plist);
|
||||
if (rdata->rd_repod == NULL) {
|
||||
free(plist);
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
free(plist);
|
||||
SIMPLEQ_INSERT_TAIL(&repodata_queue, rdata, chain);
|
||||
}
|
||||
|
||||
repodata_initialized = true;
|
||||
|
||||
out2:
|
||||
prop_object_iterator_release(iter);
|
||||
out1:
|
||||
prop_object_release(dict);
|
||||
out:
|
||||
if (rv != 0)
|
||||
xbps_release_repolist_data();
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
void SYMEXPORT
|
||||
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->rd_uri);
|
||||
free(rdata);
|
||||
}
|
||||
}
|
||||
|
||||
int SYMEXPORT
|
||||
xbps_find_new_packages(void)
|
||||
{
|
||||
@ -211,19 +106,21 @@ xbps_find_new_packages(void)
|
||||
/*
|
||||
* Prepare dictionary with all registered packages.
|
||||
*/
|
||||
dict = xbps_prepare_regpkgdb_dict();
|
||||
dict = xbps_regpkgs_dictionary_init();
|
||||
if (dict == NULL)
|
||||
return ENOENT;
|
||||
|
||||
/*
|
||||
* Prepare dictionary with all registered repositories.
|
||||
* Prepare simpleq with all registered repositories.
|
||||
*/
|
||||
if ((rv = xbps_prepare_repolist_data()) != 0)
|
||||
return rv;
|
||||
if ((rv = xbps_repository_pool_init()) != 0)
|
||||
goto out;
|
||||
|
||||
iter = xbps_get_array_iter_from_dict(dict, "packages");
|
||||
if (iter == NULL)
|
||||
return EINVAL;
|
||||
if (iter == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out if there is a newer version for all currently
|
||||
@ -250,6 +147,9 @@ xbps_find_new_packages(void)
|
||||
|
||||
if (rv != ENOENT && !newpkg_found)
|
||||
rv = ENOPKG;
|
||||
out:
|
||||
xbps_repository_pool_release();
|
||||
xbps_regpkgs_dictionary_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -268,9 +168,9 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
|
||||
assert(instpkg != NULL);
|
||||
|
||||
/*
|
||||
* Prepare dictionary with all registered repositories.
|
||||
* Prepare repository pool queue.
|
||||
*/
|
||||
if ((rv = xbps_prepare_repolist_data()) != 0)
|
||||
if ((rv = xbps_repository_pool_init()) != 0)
|
||||
return rv;
|
||||
|
||||
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||
@ -280,7 +180,14 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
|
||||
*/
|
||||
pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||
"packages", pkgname);
|
||||
if (pkgrd != NULL) {
|
||||
if (pkgrd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
DPRINTF(("Package %s not found in repo %s.\n",
|
||||
pkgname, rdata->rd_uri));
|
||||
} else if (pkgrd != NULL) {
|
||||
/*
|
||||
* Check if version in repository is greater than
|
||||
* the version currently installed.
|
||||
@ -305,14 +212,16 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
|
||||
pkgname, repover, rdata->rd_uri));
|
||||
continue;
|
||||
}
|
||||
DPRINTF(("Package %s not found in repo %s.\n",
|
||||
pkgname, rdata->rd_uri));
|
||||
}
|
||||
if (!newpkg_found)
|
||||
return EEXIST;
|
||||
if (!newpkg_found) {
|
||||
rv = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pkgrd == NULL)
|
||||
return ENOENT;
|
||||
if (pkgrd == NULL) {
|
||||
rv = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Create master pkg dictionary.
|
||||
*/
|
||||
@ -360,8 +269,7 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
|
||||
rv = errno;
|
||||
|
||||
out:
|
||||
if (rv != 0)
|
||||
xbps_release_repolist_data();
|
||||
xbps_repository_pool_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -375,7 +283,6 @@ set_pkg_state(prop_dictionary_t pkgd, const char *pkgname)
|
||||
rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_NOT_INSTALLED);
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
|
||||
/*
|
||||
* Overwrite package state in dictionary if it was unpacked
|
||||
* previously.
|
||||
@ -393,14 +300,14 @@ set_pkg_state(prop_dictionary_t pkgd, const char *pkgname)
|
||||
int SYMEXPORT
|
||||
xbps_prepare_pkg(const char *pkgname)
|
||||
{
|
||||
prop_dictionary_t pkgrd = NULL;
|
||||
prop_dictionary_t origin_pkgrd = NULL, pkgrd = NULL;
|
||||
prop_array_t pkgs_array;
|
||||
struct repository_data *rdata;
|
||||
int rv = 0;
|
||||
|
||||
assert(pkgname != NULL);
|
||||
|
||||
if ((rv = xbps_prepare_repolist_data()) != 0)
|
||||
if ((rv = xbps_repository_pool_init()) != 0)
|
||||
return rv;
|
||||
|
||||
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||
@ -410,7 +317,12 @@ xbps_prepare_pkg(const char *pkgname)
|
||||
*/
|
||||
pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||
"packages", pkgname);
|
||||
if (pkgrd != NULL)
|
||||
if (pkgrd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
} else if (pkgrd != NULL)
|
||||
break;
|
||||
}
|
||||
if (pkgrd == NULL) {
|
||||
@ -431,11 +343,12 @@ xbps_prepare_pkg(const char *pkgname)
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
origin_pkgrd = prop_dictionary_copy(pkgrd);
|
||||
|
||||
if (!prop_dictionary_set_cstring(pkg_props, "origin", pkgname)) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this package needs dependencies.
|
||||
*/
|
||||
@ -445,7 +358,6 @@ xbps_prepare_pkg(const char *pkgname)
|
||||
*/
|
||||
if ((rv = xbps_find_deps_in_pkg(pkg_props, pkgrd)) != 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Sort the dependency chain for this package.
|
||||
*/
|
||||
@ -478,25 +390,22 @@ xbps_prepare_pkg(const char *pkgname)
|
||||
rv = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always set "not-installed" package state. Will be overwritten
|
||||
* to its correct state later.
|
||||
*/
|
||||
if ((rv = set_pkg_state(pkgrd, pkgname)) != 0)
|
||||
if ((rv = set_pkg_state(origin_pkgrd, pkgname)) != 0)
|
||||
goto out;
|
||||
|
||||
if (!prop_dictionary_set_cstring_nocopy(pkgrd,
|
||||
if (!prop_dictionary_set_cstring_nocopy(origin_pkgrd,
|
||||
"trans-action", "install")) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!prop_array_add(pkgs_array, pkgrd))
|
||||
if (!prop_array_add(pkgs_array, origin_pkgrd))
|
||||
rv = errno;
|
||||
|
||||
out:
|
||||
xbps_release_repolist_data();
|
||||
if (origin_pkgrd)
|
||||
prop_object_release(origin_pkgrd);
|
||||
|
||||
xbps_repository_pool_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ cleanup(void)
|
||||
prop_object_release(orphan->dict);
|
||||
free(orphan);
|
||||
}
|
||||
xbps_regpkgs_dictionary_release();
|
||||
}
|
||||
|
||||
prop_array_t SYMEXPORT
|
||||
@ -135,7 +136,7 @@ xbps_find_orphan_packages(void)
|
||||
struct orphan_pkg *orphan;
|
||||
int rv = 0;
|
||||
|
||||
if ((dict = xbps_prepare_regpkgdb_dict()) == NULL)
|
||||
if ((dict = xbps_regpkgs_dictionary_init()) == NULL)
|
||||
return NULL;
|
||||
/*
|
||||
* Find out all orphans by looking at the
|
||||
@ -166,6 +167,7 @@ xbps_find_orphan_packages(void)
|
||||
prop_object_release(orphan->dict);
|
||||
free(orphan);
|
||||
}
|
||||
xbps_regpkgs_dictionary_release();
|
||||
|
||||
return array;
|
||||
}
|
||||
|
67
lib/plist.c
67
lib/plist.c
@ -31,9 +31,6 @@
|
||||
|
||||
#include <xbps_api.h>
|
||||
|
||||
static prop_dictionary_t regpkgdb_dict;
|
||||
static bool regpkgdb_initialized;
|
||||
|
||||
bool SYMEXPORT
|
||||
xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
|
||||
const char *key)
|
||||
@ -134,15 +131,12 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
|
||||
assert(pkgname != NULL);
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
errno = ENOENT;
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = xbps_find_pkg_in_dict(dict, "packages", pkgname);
|
||||
if (obj == NULL) {
|
||||
prop_object_release(dict);
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -158,24 +152,27 @@ xbps_find_pkg_installed_from_plist(const char *pkgname)
|
||||
prop_dictionary_t d, pkgd;
|
||||
pkg_state_t state = 0;
|
||||
|
||||
d = xbps_prepare_regpkgdb_dict();
|
||||
if (d == NULL)
|
||||
if ((d = xbps_regpkgs_dictionary_init()) == NULL)
|
||||
return NULL;
|
||||
|
||||
pkgd = xbps_find_pkg_in_dict(d, "packages", pkgname);
|
||||
if (pkgd == NULL)
|
||||
return NULL;
|
||||
goto fail;
|
||||
|
||||
if (xbps_get_pkg_state_installed(pkgname, &state) != 0)
|
||||
return NULL;
|
||||
if (xbps_get_pkg_state_dictionary(pkgd, &state) != 0)
|
||||
goto fail;
|
||||
|
||||
switch (state) {
|
||||
case XBPS_PKG_STATE_INSTALLED:
|
||||
case XBPS_PKG_STATE_UNPACKED:
|
||||
xbps_regpkgs_dictionary_release();
|
||||
return prop_dictionary_copy(pkgd);
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
fail:
|
||||
xbps_regpkgs_dictionary_release();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop_dictionary_t SYMEXPORT
|
||||
@ -183,7 +180,7 @@ xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
|
||||
const char *pkgname)
|
||||
{
|
||||
prop_object_iterator_t iter;
|
||||
prop_object_t obj;
|
||||
prop_object_t obj = NULL;
|
||||
const char *dpkgn;
|
||||
|
||||
assert(dict != NULL);
|
||||
@ -196,52 +193,18 @@ xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter))) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgname", &dpkgn)) {
|
||||
obj = NULL;
|
||||
"pkgname", &dpkgn))
|
||||
break;
|
||||
}
|
||||
if (strcmp(dpkgn, pkgname) == 0)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
if (obj == NULL)
|
||||
errno = ENOENT;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
prop_dictionary_t SYMEXPORT
|
||||
xbps_prepare_regpkgdb_dict(void)
|
||||
{
|
||||
char *plist;
|
||||
|
||||
if (regpkgdb_initialized == false) {
|
||||
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
|
||||
XBPS_META_PATH, XBPS_REGPKGDB);
|
||||
if (plist == NULL)
|
||||
return NULL;
|
||||
|
||||
regpkgdb_dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (regpkgdb_dict == NULL) {
|
||||
free(plist);
|
||||
return NULL;
|
||||
}
|
||||
free(plist);
|
||||
regpkgdb_initialized = true;
|
||||
}
|
||||
|
||||
return regpkgdb_dict;
|
||||
}
|
||||
|
||||
void SYMEXPORT
|
||||
xbps_release_regpkgdb_dict(void)
|
||||
{
|
||||
if (regpkgdb_initialized == false)
|
||||
return;
|
||||
|
||||
prop_object_release(regpkgdb_dict);
|
||||
regpkgdb_dict = NULL;
|
||||
regpkgdb_initialized = false;
|
||||
}
|
||||
|
||||
bool SYMEXPORT
|
||||
xbps_find_string_in_array(prop_array_t array, const char *val)
|
||||
{
|
||||
@ -296,7 +259,7 @@ xbps_remove_string_from_array(prop_array_t array, const char *str)
|
||||
|
||||
iter = prop_array_iterator(array);
|
||||
if (iter == NULL)
|
||||
return ENOMEM;
|
||||
return errno;
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if (prop_object_type(obj) != PROP_TYPE_STRING)
|
||||
|
13
lib/purge.c
13
lib/purge.c
@ -44,13 +44,14 @@ xbps_purge_all_pkgs(void)
|
||||
int rv = 0;
|
||||
pkg_state_t state = 0;
|
||||
|
||||
d = xbps_prepare_regpkgdb_dict();
|
||||
if (d == NULL)
|
||||
return ENODEV;
|
||||
if ((d = xbps_regpkgs_dictionary_init()) == NULL)
|
||||
return errno;
|
||||
|
||||
iter = xbps_get_array_iter_from_dict(d, "packages");
|
||||
if (iter == NULL)
|
||||
return ENOENT;
|
||||
if (iter == NULL) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
@ -66,6 +67,8 @@ xbps_purge_all_pkgs(void)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
out:
|
||||
xbps_regpkgs_dictionary_release();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -61,11 +61,10 @@ xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict != NULL) {
|
||||
if ((dict = prop_dictionary_internalize_from_file(plist)) != NULL) {
|
||||
pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname);
|
||||
if (pkgd == NULL) {
|
||||
rv = ENOENT;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
if (!prop_dictionary_set_cstring_nocopy(pkgd,
|
||||
|
73
lib/regpkgs_dictionary.c
Normal file
73
lib/regpkgs_dictionary.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2009 Juan Romero Pardines.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <xbps_api.h>
|
||||
|
||||
static prop_dictionary_t regpkgs_dict;
|
||||
static size_t regpkgs_refcount;
|
||||
static bool regpkgs_initialized;
|
||||
|
||||
prop_dictionary_t SYMEXPORT
|
||||
xbps_regpkgs_dictionary_init(void)
|
||||
{
|
||||
char *plist;
|
||||
|
||||
if (regpkgs_initialized == false) {
|
||||
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
|
||||
XBPS_META_PATH, XBPS_REGPKGDB);
|
||||
if (plist == NULL)
|
||||
return NULL;
|
||||
|
||||
regpkgs_dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (regpkgs_dict == NULL) {
|
||||
free(plist);
|
||||
return NULL;
|
||||
}
|
||||
free(plist);
|
||||
regpkgs_initialized = true;
|
||||
DPRINTF(("%s: initialized ok.\n", __func__));
|
||||
}
|
||||
regpkgs_refcount++;
|
||||
|
||||
return regpkgs_dict;
|
||||
}
|
||||
|
||||
void SYMEXPORT
|
||||
xbps_regpkgs_dictionary_release(void)
|
||||
{
|
||||
if (--regpkgs_refcount > 0)
|
||||
return;
|
||||
|
||||
prop_object_release(regpkgs_dict);
|
||||
regpkgs_dict = NULL;
|
||||
regpkgs_initialized = false;
|
||||
DPRINTF(("%s: released ok.\n", __func__));
|
||||
}
|
@ -200,7 +200,7 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
|
||||
char *url = NULL;
|
||||
int rv = 0;
|
||||
|
||||
if ((rv = xbps_prepare_repolist_data()) != 0) {
|
||||
if ((rv = xbps_repository_pool_init()) != 0) {
|
||||
errno = rv;
|
||||
return NULL;
|
||||
}
|
||||
@ -215,9 +215,13 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
|
||||
* libfetch!
|
||||
*/
|
||||
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
|
||||
if ((pkgd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||
"packages", pkgname)) == NULL)
|
||||
pkgd = xbps_find_pkg_in_dict(rdata->rd_repod,
|
||||
"packages", pkgname);
|
||||
if (pkgd == NULL) {
|
||||
if (errno != ENOENT)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
url = xbps_get_path_from_pkg_dict_repo(pkgd, rdata->rd_uri);
|
||||
if (url == NULL)
|
||||
break;
|
||||
@ -229,7 +233,7 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
|
||||
free(url);
|
||||
}
|
||||
|
||||
xbps_release_repolist_data();
|
||||
xbps_repository_pool_release();
|
||||
if (plistd == NULL)
|
||||
errno = ENOENT;
|
||||
|
||||
|
148
lib/repository_pool.c
Normal file
148
lib/repository_pool.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Juan Romero Pardines.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <xbps_api.h>
|
||||
|
||||
static size_t repolist_refcnt;
|
||||
static bool repolist_initialized;
|
||||
|
||||
int SYMEXPORT
|
||||
xbps_repository_pool_init(void)
|
||||
{
|
||||
prop_dictionary_t dict = NULL;
|
||||
prop_array_t array;
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
struct repository_data *rdata;
|
||||
char *plist;
|
||||
int rv = 0;
|
||||
|
||||
if (repolist_initialized) {
|
||||
repolist_refcnt++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SIMPLEQ_INIT(&repodata_queue);
|
||||
|
||||
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
|
||||
XBPS_META_PATH, XBPS_REPOLIST);
|
||||
if (plist == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
free(plist);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
free(plist);
|
||||
|
||||
array = prop_dictionary_get(dict, "repository-list");
|
||||
if (array == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
iter = prop_array_iterator(array);
|
||||
if (iter == NULL) {
|
||||
rv = ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
/*
|
||||
* Iterate over the repository pool and add the dictionary
|
||||
* for current repository into the queue.
|
||||
*/
|
||||
plist =
|
||||
xbps_get_pkg_index_plist(prop_string_cstring_nocopy(obj));
|
||||
if (plist == NULL) {
|
||||
rv = EINVAL;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
rdata = malloc(sizeof(struct repository_data));
|
||||
if (rdata == NULL) {
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
rdata->rd_uri = prop_string_cstring(obj);
|
||||
if (rdata->rd_uri == NULL) {
|
||||
free(plist);
|
||||
rv = EINVAL;
|
||||
goto out2;
|
||||
}
|
||||
rdata->rd_repod = prop_dictionary_internalize_from_file(plist);
|
||||
if (rdata->rd_repod == NULL) {
|
||||
free(plist);
|
||||
rv = errno;
|
||||
goto out2;
|
||||
}
|
||||
free(plist);
|
||||
SIMPLEQ_INSERT_TAIL(&repodata_queue, rdata, chain);
|
||||
}
|
||||
|
||||
repolist_initialized = true;
|
||||
repolist_refcnt = 1;
|
||||
DPRINTF(("%s: initialized ok.\n", __func__));
|
||||
out2:
|
||||
prop_object_iterator_release(iter);
|
||||
out1:
|
||||
prop_object_release(dict);
|
||||
out:
|
||||
if (rv != 0)
|
||||
xbps_repository_pool_release();
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
void SYMEXPORT
|
||||
xbps_repository_pool_release(void)
|
||||
{
|
||||
struct repository_data *rdata;
|
||||
|
||||
if (--repolist_refcnt > 0)
|
||||
return;
|
||||
|
||||
while ((rdata = SIMPLEQ_FIRST(&repodata_queue)) != NULL) {
|
||||
SIMPLEQ_REMOVE(&repodata_queue, rdata, repository_data, chain);
|
||||
prop_object_release(rdata->rd_repod);
|
||||
free(rdata->rd_uri);
|
||||
free(rdata);
|
||||
}
|
||||
repolist_refcnt = 0;
|
||||
repolist_initialized = false;
|
||||
DPRINTF(("%s: released ok.\n", __func__));
|
||||
}
|
@ -133,8 +133,7 @@ xbps_requiredby_pkg_remove(const char *pkgname)
|
||||
if (plist == NULL)
|
||||
return EINVAL;
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
|
||||
free(plist);
|
||||
return errno;
|
||||
}
|
||||
|
70
lib/state.c
70
lib/state.c
@ -34,7 +34,7 @@
|
||||
static int
|
||||
set_new_state(prop_dictionary_t dict, pkg_state_t state)
|
||||
{
|
||||
const char *state_str;
|
||||
const char *pkgname, *state_str;
|
||||
|
||||
assert(dict != NULL);
|
||||
|
||||
@ -61,6 +61,11 @@ set_new_state(prop_dictionary_t dict, pkg_state_t state)
|
||||
if (!prop_dictionary_set_cstring_nocopy(dict, "state", state_str))
|
||||
return -1;
|
||||
|
||||
if (prop_dictionary_get_cstring_nocopy(dict, "pkgname", &pkgname)) {
|
||||
DPRINTF(("%s: changed pkg state to '%s'.\n",
|
||||
pkgname, state_str));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -94,33 +99,17 @@ get_state(prop_dictionary_t dict)
|
||||
int SYMEXPORT
|
||||
xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state)
|
||||
{
|
||||
prop_dictionary_t dict, pkgd;
|
||||
char *plist;
|
||||
prop_dictionary_t pkgd;
|
||||
|
||||
assert(pkgname != NULL);
|
||||
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
|
||||
XBPS_META_PATH, XBPS_REGPKGDB);
|
||||
if (plist == NULL)
|
||||
|
||||
pkgd = xbps_find_pkg_installed_from_plist(pkgname);
|
||||
if (pkgd == NULL)
|
||||
return errno;
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
free(plist);
|
||||
return errno;
|
||||
}
|
||||
free(plist);
|
||||
|
||||
pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname);
|
||||
if (pkgd == NULL) {
|
||||
prop_object_release(dict);
|
||||
return ENOENT;
|
||||
}
|
||||
*state = get_state(pkgd);
|
||||
if (*state == 0) {
|
||||
prop_object_release(dict);
|
||||
if (*state == 0)
|
||||
return EINVAL;
|
||||
}
|
||||
prop_object_release(dict);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -147,7 +136,7 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
|
||||
int SYMEXPORT
|
||||
xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
||||
{
|
||||
prop_dictionary_t dict, pkgd;
|
||||
prop_dictionary_t dict = NULL, pkgd;
|
||||
prop_array_t array;
|
||||
char *plist;
|
||||
int rv = 0;
|
||||
@ -158,16 +147,15 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
||||
if (plist == NULL)
|
||||
return EINVAL;
|
||||
|
||||
dict = prop_dictionary_internalize_from_file(plist);
|
||||
if (dict == NULL) {
|
||||
if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
|
||||
dict = prop_dictionary_create();
|
||||
if (dict == NULL) {
|
||||
free(plist);
|
||||
return ENOMEM;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
array = prop_array_create();
|
||||
if (array == NULL) {
|
||||
rv = ENOMEM;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
pkgd = prop_dictionary_create();
|
||||
@ -179,27 +167,34 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
||||
if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgname",
|
||||
pkgname)) {
|
||||
prop_object_release(array);
|
||||
prop_object_release(pkgd);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
if ((rv = set_new_state(pkgd, state)) != 0) {
|
||||
prop_object_release(array);
|
||||
prop_object_release(pkgd);
|
||||
goto out;
|
||||
}
|
||||
if (!xbps_add_obj_to_array(array, pkgd)) {
|
||||
prop_object_release(array);
|
||||
rv = EINVAL;
|
||||
prop_object_release(pkgd);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
if (!xbps_add_obj_to_dict(dict, array, "packages")) {
|
||||
prop_object_release(array);
|
||||
rv = EINVAL;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname);
|
||||
if (pkgd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
newpkg = true;
|
||||
pkgd = prop_dictionary_create();
|
||||
if (!prop_dictionary_set_cstring_nocopy(pkgd,
|
||||
@ -211,16 +206,19 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
||||
}
|
||||
array = prop_dictionary_get(dict, "packages");
|
||||
if (array == NULL) {
|
||||
rv = ENOENT;
|
||||
if (newpkg)
|
||||
prop_object_release(pkgd);
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
if ((rv = set_new_state(pkgd, state)) != 0) {
|
||||
prop_object_release(pkgd);
|
||||
if (newpkg)
|
||||
prop_object_release(pkgd);
|
||||
goto out;
|
||||
}
|
||||
if (newpkg && !xbps_add_obj_to_array(array, pkgd)) {
|
||||
prop_object_release(pkgd);
|
||||
rv = EINVAL;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -229,8 +227,10 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
|
||||
rv = errno;
|
||||
|
||||
out:
|
||||
prop_object_release(dict);
|
||||
free(plist);
|
||||
if (dict)
|
||||
prop_object_release(dict);
|
||||
if (plist)
|
||||
free(plist);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
24
lib/unpack.c
24
lib/unpack.c
@ -40,9 +40,9 @@ int SYMEXPORT
|
||||
xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
|
||||
{
|
||||
prop_string_t filename, repoloc, arch;
|
||||
struct archive *ar;
|
||||
struct archive *ar = NULL;
|
||||
const char *pkgname;
|
||||
char *binfile;
|
||||
char *binfile = NULL;
|
||||
int pkg_fd, rv = 0;
|
||||
|
||||
assert(pkg != NULL);
|
||||
@ -73,8 +73,8 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
|
||||
|
||||
ar = archive_read_new();
|
||||
if (ar == NULL) {
|
||||
rv = ENOMEM;
|
||||
goto out2;
|
||||
rv = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -85,7 +85,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
|
||||
|
||||
if ((rv = archive_read_open_fd(ar, pkg_fd,
|
||||
ARCHIVE_READ_BLOCKSIZE)) != 0)
|
||||
goto out3;
|
||||
goto out;
|
||||
|
||||
rv = unpack_archive_fini(ar, pkg, essential);
|
||||
/*
|
||||
@ -95,7 +95,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
|
||||
if (rv == 0) {
|
||||
if (fsync(pkg_fd) == -1) {
|
||||
rv = errno;
|
||||
goto out3;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Set package state to unpacked.
|
||||
@ -103,12 +103,14 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
|
||||
rv = xbps_set_pkg_state_installed(pkgname,
|
||||
XBPS_PKG_STATE_UNPACKED);
|
||||
}
|
||||
out3:
|
||||
archive_read_finish(ar);
|
||||
out2:
|
||||
(void)close(pkg_fd);
|
||||
|
||||
out:
|
||||
free(binfile);
|
||||
if (ar)
|
||||
archive_read_finish(ar);
|
||||
if (pkg_fd != -1)
|
||||
(void)close(pkg_fd);
|
||||
if (binfile)
|
||||
free(binfile);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
10
lib/util.c
10
lib/util.c
@ -128,7 +128,7 @@ int SYMEXPORT
|
||||
xbps_check_is_installed_pkg(const char *pkg)
|
||||
{
|
||||
prop_dictionary_t dict;
|
||||
const char *instpkgver;
|
||||
const char *instpkgver = NULL;
|
||||
char *pkgname;
|
||||
int rv = 0;
|
||||
pkg_state_t state = 0;
|
||||
@ -142,14 +142,18 @@ xbps_check_is_installed_pkg(const char *pkg)
|
||||
dict = xbps_find_pkg_installed_from_plist(pkgname);
|
||||
if (dict == NULL) {
|
||||
free(pkgname);
|
||||
return 0; /* not installed */
|
||||
if (errno == ENOENT) {
|
||||
errno = 0;
|
||||
return 0; /* not installed */
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that package state is fully installed, not
|
||||
* unpacked or something else.
|
||||
*/
|
||||
if (xbps_get_pkg_state_installed(pkgname, &state) != 0) {
|
||||
if (xbps_get_pkg_state_dictionary(dict, &state) != 0) {
|
||||
prop_object_release(dict);
|
||||
free(pkgname);
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user