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:
Juan RP 2009-11-26 02:22:50 +00:00
parent fa7e3a3a7e
commit 87a216fd11
24 changed files with 495 additions and 334 deletions

View File

@ -50,29 +50,33 @@ xbps_check_pkg_integrity_all(void)
{ {
prop_dictionary_t d; prop_dictionary_t d;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter = NULL;
const char *pkgname, *version; const char *pkgname, *version;
int rv = 0; int rv = 0;
size_t npkgs = 0, nbrokenpkgs = 0; size_t npkgs = 0, nbrokenpkgs = 0;
d = xbps_prepare_regpkgdb_dict(); d = xbps_regpkgs_dictionary_init();
if (d == NULL) if (d == NULL)
return ENODEV; return ENODEV;
iter = xbps_get_array_iter_from_dict(d, "packages"); iter = xbps_get_array_iter_from_dict(d, "packages");
if (iter == NULL) if (iter == NULL) {
return ENOENT; rv = ENOENT;
goto out;
}
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &pkgname)) { "pkgname", &pkgname)) {
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
return errno; rv = errno;
goto out;
} }
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"version", &version)) { "version", &version)) {
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
return errno; rv = errno;
goto out;
} }
printf("Checking %s-%s ...\n", pkgname, version); printf("Checking %s-%s ...\n", pkgname, version);
if ((rv = xbps_check_pkg_integrity(pkgname)) != 0) if ((rv = xbps_check_pkg_integrity(pkgname)) != 0)
@ -80,11 +84,15 @@ xbps_check_pkg_integrity_all(void)
npkgs++; npkgs++;
printf("\033[1A\033[K"); printf("\033[1A\033[K");
} }
prop_object_iterator_release(iter);
printf("%zu package%s processed: %zu broken.\n", npkgs, printf("%zu package%s processed: %zu broken.\n", npkgs,
npkgs == 1 ? "" : "s", nbrokenpkgs); npkgs == 1 ? "" : "s", nbrokenpkgs);
out:
if (iter)
prop_object_iterator_release(iter);
xbps_regpkgs_dictionary_release();
return rv; return rv;
} }
@ -312,7 +320,6 @@ out1:
prop_object_release(propsd); prop_object_release(propsd);
out: out:
prop_object_release(pkgd); prop_object_release(pkgd);
xbps_release_regpkgdb_dict();
if (broken) if (broken)
rv = EINVAL; rv = EINVAL;

View File

@ -246,7 +246,9 @@ show_transaction_sizes(prop_object_iterator_t iter)
uint64_t tsize = 0, dlsize = 0, instsize = 0; uint64_t tsize = 0, dlsize = 0, instsize = 0;
const char *tract; const char *tract;
char size[64]; 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 * 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; trans_inst = true;
else if (strcmp(tract, "update") == 0) else if (strcmp(tract, "update") == 0)
trans_up = true; trans_up = true;
else if (strcmp(tract, "configure") == 0)
trans_conf = true;
} }
prop_object_iterator_reset(iter); prop_object_iterator_reset(iter);
@ -291,6 +295,11 @@ show_transaction_sizes(prop_object_iterator_t iter)
show_package_list(iter, "update"); show_package_list(iter, "update");
printf("\n\n"); 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. * 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); "repository pool.\n", pkgname);
return rv; return rv;
} else if (rv != 0 && rv != ENOENT) { } else if (rv != 0 && rv != ENOENT) {
printf("Unexpected error: %s", strerror(rv)); printf("Unexpected error: %s", strerror(errno));
return rv; return rv;
} }
} }
@ -410,13 +419,6 @@ xbps_exec_transaction(const char *pkgname, bool force, bool update)
show_missing_deps(trans->dict, pkgname); show_missing_deps(trans->dict, pkgname);
goto out2; goto out2;
} }
if (!prop_dictionary_get_cstring_nocopy(trans->dict,
"origin", &trans->originpkgname)) {
rv = errno;
goto out2;
}
if (update) { if (update) {
/* /*
* Sort the package transaction dictionary. * Sort the package transaction dictionary.
@ -426,8 +428,13 @@ xbps_exec_transaction(const char *pkgname, bool force, bool update)
strerror(rv)); strerror(rv));
goto out2; 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! * It's time to run the transaction!
*/ */
@ -654,13 +661,6 @@ exec_transaction(struct transaction *trans)
return rv; return rv;
} }
autoinst = false; 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); prop_object_iterator_reset(trans->iter);
/* /*

View File

@ -157,7 +157,7 @@ main(int argc, char **argv)
sigaction(SIGTERM, &sa, NULL); sigaction(SIGTERM, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL);
if ((dict = xbps_prepare_regpkgdb_dict()) == NULL) { if ((dict = xbps_regpkgs_dictionary_init()) == NULL) {
if (errno != ENOENT) { if (errno != ENOENT) {
rv = errno; rv = errno;
printf("Couldn't initialized regpkgdb dict: %s\n", printf("Couldn't initialized regpkgdb dict: %s\n",
@ -319,8 +319,6 @@ out:
static void static void
cleanup(int signum) cleanup(int signum)
{ {
xbps_release_repolist_data(); xbps_regpkgs_dictionary_release();
xbps_release_regpkgdb_dict();
exit(signum); exit(signum);
} }

View File

@ -69,8 +69,6 @@ xbps_show_pkg_deps(const char *pkgname)
prop_object_release(propsd); prop_object_release(propsd);
prop_object_release(pkgd); prop_object_release(pkgd);
xbps_release_regpkgdb_dict();
return rv; return rv;
} }
@ -89,7 +87,6 @@ xbps_show_pkg_reverse_deps(const char *pkgname)
rv = xbps_callback_array_iter_in_dict(pkgd, "requiredby", rv = xbps_callback_array_iter_in_dict(pkgd, "requiredby",
list_strings_sep_in_array, NULL); list_strings_sep_in_array, NULL);
prop_object_release(pkgd); prop_object_release(pkgd);
xbps_release_regpkgdb_dict();
return rv; return rv;
} }

View File

@ -129,7 +129,13 @@ xbps_repo_addpkg_index(prop_dictionary_t idxdict, const char *filedir,
* pass to the next one. * pass to the next one.
*/ */
curpkgd = xbps_find_pkg_in_dict(idxdict, "packages", pkgname); 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, if (!prop_dictionary_get_cstring_nocopy(curpkgd,
"version", &regver)) { "version", &regver)) {
prop_object_release(newpkgd); prop_object_release(newpkgd);

View File

@ -96,7 +96,7 @@ main(int argc, char **argv)
if (argc < 1) if (argc < 1)
usage(); usage();
if ((rv = xbps_prepare_repolist_data()) != 0) { if ((rv = xbps_repository_pool_init()) != 0) {
if (rv != ENOENT) { if (rv != ENOENT) {
printf("E: cannot get repository list pool! %s\n", printf("E: cannot get repository list pool! %s\n",
strerror(rv)); strerror(rv));
@ -202,6 +202,6 @@ main(int argc, char **argv)
} }
out: out:
xbps_release_repolist_data(); xbps_repository_pool_release();
exit(rv ? EXIT_FAILURE : EXIT_SUCCESS); exit(rv ? EXIT_FAILURE : EXIT_SUCCESS);
} }

View File

@ -207,7 +207,10 @@ show_pkg_info_from_repolist(const char *pkgname)
repo_pkgd = xbps_find_pkg_in_dict(rd->rd_repod, repo_pkgd = xbps_find_pkg_in_dict(rd->rd_repod,
"packages", pkgname); "packages", pkgname);
if (repo_pkgd == NULL) { if (repo_pkgd == NULL) {
errno = ENOENT; if (errno && errno != ENOENT) {
rv = errno;
break;
}
continue; continue;
} }
url = xbps_get_path_from_pkg_dict_repo(repo_pkgd, rd->rd_uri); 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) { SIMPLEQ_FOREACH(rd, &repodata_queue, chain) {
pkgd = xbps_find_pkg_in_dict(rd->rd_repod, "packages", pkgname); pkgd = xbps_find_pkg_in_dict(rd->rd_repod, "packages", pkgname);
if (pkgd == NULL) { if (pkgd == NULL) {
errno = ENOENT; if (errno != ENOENT) {
rv = errno;
break;
}
continue; continue;
} }
if (!prop_dictionary_get_cstring_nocopy(pkgd, if (!prop_dictionary_get_cstring_nocopy(pkgd,

View File

@ -113,7 +113,7 @@ show_pkg_info(prop_dictionary_t dict)
obj = prop_dictionary_get(dict, "short_desc"); obj = prop_dictionary_get(dict, "short_desc");
if (obj && prop_object_type(obj) == PROP_TYPE_STRING) 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"); obj = prop_dictionary_get(dict, "long_desc");
if (obj && prop_object_type(obj) == PROP_TYPE_STRING) if (obj && prop_object_type(obj) == PROP_TYPE_STRING)

View File

@ -38,7 +38,7 @@
#include <archive_entry.h> #include <archive_entry.h>
/* Current release version */ /* Current release version */
#define XBPS_RELVER "20091125" #define XBPS_RELVER "20091126"
/* Default root PATH for xbps to store metadata info. */ /* Default root PATH for xbps to store metadata info. */
#define XBPS_META_PATH "/var/db/xbps" #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); int, int);
/* From lib/findpkg.c */ /* 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_prepare_pkg(const char *);
int SYMEXPORT xbps_find_new_pkg(const char *, prop_dictionary_t); int SYMEXPORT xbps_find_new_pkg(const char *, prop_dictionary_t);
int SYMEXPORT xbps_find_new_packages(void); 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); prop_dictionary_t SYMEXPORT xbps_get_pkg_props(void);
/* From lib/depends.c */ /* From lib/depends.c */
@ -156,8 +147,6 @@ prop_dictionary_t SYMEXPORT
xbps_find_pkg_installed_from_plist(const char *); xbps_find_pkg_installed_from_plist(const char *);
bool SYMEXPORT xbps_find_string_in_array(prop_array_t, 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 prop_object_iterator_t SYMEXPORT
xbps_get_array_iter_from_dict(prop_dictionary_t, const char *); 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_register_pkg(prop_dictionary_t, bool);
int SYMEXPORT xbps_unregister_pkg(const char *); 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 */ /* From lib/remove.c */
int SYMEXPORT xbps_remove_pkg(const char *, const char *, bool); int SYMEXPORT xbps_remove_pkg(const char *, const char *, bool);
@ -192,6 +185,17 @@ prop_dictionary_t SYMEXPORT
prop_dictionary_t SYMEXPORT prop_dictionary_t SYMEXPORT
xbps_get_pkg_plist_dict_from_url(const char *, const char *); 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 */ /* From lib/requiredby.c */
int SYMEXPORT xbps_requiredby_pkg_add(prop_array_t, prop_dictionary_t); int SYMEXPORT xbps_requiredby_pkg_add(prop_array_t, prop_dictionary_t);
int SYMEXPORT xbps_requiredby_pkg_remove(const char *); int SYMEXPORT xbps_requiredby_pkg_remove(const char *);

View File

@ -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 += 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 += repository.o requiredby.o sha256.o sortdeps.o state.o
OBJS += sync_remote_pkgidx.o unpack.o util.o pkgmatch.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 .PHONY: all
all: libfetch libxbps.so libxbps.a all: libfetch libxbps.so libxbps.a

View File

@ -43,13 +43,14 @@ xbps_configure_all_pkgs(void)
int rv = 0; int rv = 0;
pkg_state_t state = 0; pkg_state_t state = 0;
d = xbps_prepare_regpkgdb_dict(); if ((d = xbps_regpkgs_dictionary_init()) == NULL)
if (d == NULL) return errno;
return ENODEV;
iter = xbps_get_array_iter_from_dict(d, "packages"); iter = xbps_get_array_iter_from_dict(d, "packages");
if (iter == NULL) if (iter == NULL) {
return ENOENT; rv = errno;
goto out;
}
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
@ -70,6 +71,8 @@ xbps_configure_all_pkgs(void)
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
out:
xbps_regpkgs_dictionary_release();
return rv; 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); pkgd = xbps_find_pkg_installed_from_plist(pkgname);
if (pkgd == NULL) if (pkgd == NULL)
return ENOENT; return errno;
if (!prop_dictionary_get_cstring_nocopy(pkgd, if (!prop_dictionary_get_cstring_nocopy(pkgd,
"version", &lver)) { "version", &lver)) {
@ -131,8 +134,10 @@ xbps_configure_pkg(const char *pkgname, const char *version, bool check_state)
if (strcmp(rootdir, "") == 0) if (strcmp(rootdir, "") == 0)
rootdir = "/"; rootdir = "/";
if (chdir(rootdir) == -1) if (chdir(rootdir) == -1) {
free(buf);
return errno; return errno;
}
if (access(buf, X_OK) == 0) { if (access(buf, X_OK) == 0) {
if ((rv = xbps_file_chdir_exec(rootdir, buf, "post", if ((rv = xbps_file_chdir_exec(rootdir, buf, "post",

View File

@ -89,12 +89,6 @@ store_dependency(prop_dictionary_t master, prop_dictionary_t depd,
prop_object_release(dict); prop_object_release(dict);
return errno; 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. * Add the dictionary into the array.
@ -112,12 +106,16 @@ add_missing_reqdep(prop_dictionary_t master, const char *pkgname,
const char *version) const char *version)
{ {
prop_array_t missing_rdeps; prop_array_t missing_rdeps;
prop_dictionary_t mdepd; prop_dictionary_t mdepd, tmpd;
assert(array != NULL); assert(array != NULL);
assert(reqdep != 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; return EEXIST;
mdepd = prop_dictionary_create(); 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)) if (!prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname))
return errno; return errno;
if ((rv = xbps_repository_pool_init()) != 0)
return rv;
DPRINTF(("Checking rundeps for %s.\n", pkgname)); DPRINTF(("Checking rundeps for %s.\n", pkgname));
/* /*
* Iterate over the repository pool and find out if we have * 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, if ((rv = find_repo_deps(master, rdata->rd_repod,
rdata->rd_uri, pkg_rdeps)) != 0) { rdata->rd_uri, pkg_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking rundeps!\n", DPRINTF(("Error '%s' while checking rundeps!\n",
strerror(rv))); strerror(errno)));
return rv; 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"); missing_rdeps = prop_dictionary_get(master, "missing_deps");
if (prop_array_count(missing_rdeps) == 0) if (prop_array_count(missing_rdeps) == 0)
return 0; goto out;
/* /*
* Iterate one more time, but this time with missing deps * 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, if ((rv = find_repo_deps(master, rdata->rd_repod,
rdata->rd_uri, missing_rdeps)) != 0) { rdata->rd_uri, missing_rdeps)) != 0) {
DPRINTF(("Error '%s' while checking for" DPRINTF(("Error '%s' while checking for"
"missing rundeps!\n", strerror(rv))); "missing rundeps!\n", strerror(errno)));
return rv; goto out;
} }
} }
out:
xbps_repository_pool_release();
return rv; return rv;
} }
@ -210,6 +213,7 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
prop_array_t curpkg_rdeps; prop_array_t curpkg_rdeps;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
pkg_state_t state = 0;
const char *reqpkg, *reqvers, *pkg_queued; const char *reqpkg, *reqvers, *pkg_queued;
char *pkgname; char *pkgname;
int rv = 0; int rv = 0;
@ -260,7 +264,13 @@ find_repo_deps(prop_dictionary_t master, prop_dictionary_t repo,
* dependency pattern is matched. * dependency pattern is matched.
*/ */
curpkgd = xbps_find_pkg_in_dict(master, "unsorted_deps", pkgname); 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, if (!prop_dictionary_get_cstring_nocopy(curpkgd,
"pkgver", &pkg_queued)) { "pkgver", &pkg_queued)) {
DPRINTF(("pkgver failed %s\n", reqpkg)); 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); curpkgd = xbps_find_pkg_in_dict(repo, "packages", pkgname);
if (curpkgd == NULL) { if (curpkgd == NULL) {
if (errno && errno != ENOENT) {
free(pkgname);
rv = errno;
break;
}
rv = add_missing_reqdep(master, pkgname, reqvers); rv = add_missing_reqdep(master, pkgname, reqvers);
if (rv != 0 && rv != EEXIST) { if (rv != 0 && rv != EEXIST) {
DPRINTF(("add missing reqdep failed %s\n", 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 * If package is installed but version doesn't satisfy
* the dependency mark it as an update, otherwise as * 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); tmpd = xbps_find_pkg_installed_from_plist(pkgname);
if (tmpd != NULL) { if (tmpd == NULL) {
prop_dictionary_set_cstring_nocopy(curpkgd, if (errno && errno != ENOENT) {
"trans-action", "update"); free(pkgname);
prop_object_release(tmpd); rv = errno;
} else { break;
}
prop_dictionary_set_cstring_nocopy(curpkgd, prop_dictionary_set_cstring_nocopy(curpkgd,
"trans-action", "install"); "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. * 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, if ((rv = find_repo_deps(master, repo, repoloc,
curpkg_rdeps)) != 0) { curpkg_rdeps)) != 0) {
DPRINTF(("Error checking %s rundeps %s\n", DPRINTF(("Error checking %s rundeps %s\n",
reqpkg, strerror(rv))); reqpkg, strerror(errno)));
break; break;
} }
} }

View File

@ -93,111 +93,6 @@ xbps_get_pkg_props(void)
return pkg_props; 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 int SYMEXPORT
xbps_find_new_packages(void) xbps_find_new_packages(void)
{ {
@ -211,19 +106,21 @@ xbps_find_new_packages(void)
/* /*
* Prepare dictionary with all registered packages. * Prepare dictionary with all registered packages.
*/ */
dict = xbps_prepare_regpkgdb_dict(); dict = xbps_regpkgs_dictionary_init();
if (dict == NULL) if (dict == NULL)
return ENOENT; return ENOENT;
/* /*
* Prepare dictionary with all registered repositories. * Prepare simpleq with all registered repositories.
*/ */
if ((rv = xbps_prepare_repolist_data()) != 0) if ((rv = xbps_repository_pool_init()) != 0)
return rv; goto out;
iter = xbps_get_array_iter_from_dict(dict, "packages"); iter = xbps_get_array_iter_from_dict(dict, "packages");
if (iter == NULL) if (iter == NULL) {
return EINVAL; rv = EINVAL;
goto out;
}
/* /*
* Find out if there is a newer version for all currently * 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) if (rv != ENOENT && !newpkg_found)
rv = ENOPKG; rv = ENOPKG;
out:
xbps_repository_pool_release();
xbps_regpkgs_dictionary_release();
return rv; return rv;
} }
@ -268,9 +168,9 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
assert(instpkg != NULL); 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; return rv;
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { 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, pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
"packages", pkgname); "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 * Check if version in repository is greater than
* the version currently installed. * the version currently installed.
@ -305,14 +212,16 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
pkgname, repover, rdata->rd_uri)); pkgname, repover, rdata->rd_uri));
continue; continue;
} }
DPRINTF(("Package %s not found in repo %s.\n",
pkgname, rdata->rd_uri));
} }
if (!newpkg_found) if (!newpkg_found) {
return EEXIST; rv = EEXIST;
goto out;
}
if (pkgrd == NULL) if (pkgrd == NULL) {
return ENOENT; rv = ENOENT;
goto out;
}
/* /*
* Create master pkg dictionary. * Create master pkg dictionary.
*/ */
@ -360,8 +269,7 @@ xbps_find_new_pkg(const char *pkgname, prop_dictionary_t instpkg)
rv = errno; rv = errno;
out: out:
if (rv != 0) xbps_repository_pool_release();
xbps_release_repolist_data();
return rv; 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); rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_NOT_INSTALLED);
if (rv != 0) if (rv != 0)
return rv; return rv;
/* /*
* Overwrite package state in dictionary if it was unpacked * Overwrite package state in dictionary if it was unpacked
* previously. * previously.
@ -393,14 +300,14 @@ set_pkg_state(prop_dictionary_t pkgd, const char *pkgname)
int SYMEXPORT int SYMEXPORT
xbps_prepare_pkg(const char *pkgname) xbps_prepare_pkg(const char *pkgname)
{ {
prop_dictionary_t pkgrd = NULL; prop_dictionary_t origin_pkgrd = NULL, pkgrd = NULL;
prop_array_t pkgs_array; prop_array_t pkgs_array;
struct repository_data *rdata; struct repository_data *rdata;
int rv = 0; int rv = 0;
assert(pkgname != NULL); assert(pkgname != NULL);
if ((rv = xbps_prepare_repolist_data()) != 0) if ((rv = xbps_repository_pool_init()) != 0)
return rv; return rv;
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { 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, pkgrd = xbps_find_pkg_in_dict(rdata->rd_repod,
"packages", pkgname); "packages", pkgname);
if (pkgrd != NULL) if (pkgrd == NULL) {
if (errno && errno != ENOENT) {
rv = errno;
goto out;
}
} else if (pkgrd != NULL)
break; break;
} }
if (pkgrd == NULL) { if (pkgrd == NULL) {
@ -431,11 +343,12 @@ xbps_prepare_pkg(const char *pkgname)
rv = errno; rv = errno;
goto out; goto out;
} }
origin_pkgrd = prop_dictionary_copy(pkgrd);
if (!prop_dictionary_set_cstring(pkg_props, "origin", pkgname)) { if (!prop_dictionary_set_cstring(pkg_props, "origin", pkgname)) {
rv = errno; rv = errno;
goto out; goto out;
} }
/* /*
* Check if this package needs dependencies. * 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) if ((rv = xbps_find_deps_in_pkg(pkg_props, pkgrd)) != 0)
goto out; goto out;
/* /*
* Sort the dependency chain for this package. * Sort the dependency chain for this package.
*/ */
@ -478,25 +390,22 @@ xbps_prepare_pkg(const char *pkgname)
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if ((rv = set_pkg_state(origin_pkgrd, pkgname)) != 0)
/*
* Always set "not-installed" package state. Will be overwritten
* to its correct state later.
*/
if ((rv = set_pkg_state(pkgrd, pkgname)) != 0)
goto out; goto out;
if (!prop_dictionary_set_cstring_nocopy(pkgrd, if (!prop_dictionary_set_cstring_nocopy(origin_pkgrd,
"trans-action", "install")) { "trans-action", "install")) {
rv = errno; rv = errno;
goto out; goto out;
} }
if (!prop_array_add(pkgs_array, origin_pkgrd))
if (!prop_array_add(pkgs_array, pkgrd))
rv = errno; rv = errno;
out: out:
xbps_release_repolist_data(); if (origin_pkgrd)
prop_object_release(origin_pkgrd);
xbps_repository_pool_release();
return rv; return rv;
} }

View File

@ -125,6 +125,7 @@ cleanup(void)
prop_object_release(orphan->dict); prop_object_release(orphan->dict);
free(orphan); free(orphan);
} }
xbps_regpkgs_dictionary_release();
} }
prop_array_t SYMEXPORT prop_array_t SYMEXPORT
@ -135,7 +136,7 @@ xbps_find_orphan_packages(void)
struct orphan_pkg *orphan; struct orphan_pkg *orphan;
int rv = 0; int rv = 0;
if ((dict = xbps_prepare_regpkgdb_dict()) == NULL) if ((dict = xbps_regpkgs_dictionary_init()) == NULL)
return NULL; return NULL;
/* /*
* Find out all orphans by looking at the * Find out all orphans by looking at the
@ -166,6 +167,7 @@ xbps_find_orphan_packages(void)
prop_object_release(orphan->dict); prop_object_release(orphan->dict);
free(orphan); free(orphan);
} }
xbps_regpkgs_dictionary_release();
return array; return array;
} }

View File

@ -31,9 +31,6 @@
#include <xbps_api.h> #include <xbps_api.h>
static prop_dictionary_t regpkgdb_dict;
static bool regpkgdb_initialized;
bool SYMEXPORT bool SYMEXPORT
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)
@ -134,15 +131,12 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
assert(pkgname != NULL); assert(pkgname != NULL);
dict = prop_dictionary_internalize_from_file(plist); dict = prop_dictionary_internalize_from_file(plist);
if (dict == NULL) { if (dict == NULL)
errno = ENOENT;
return NULL; return NULL;
}
obj = xbps_find_pkg_in_dict(dict, "packages", pkgname); obj = xbps_find_pkg_in_dict(dict, "packages", pkgname);
if (obj == NULL) { if (obj == NULL) {
prop_object_release(dict); prop_object_release(dict);
errno = ENOENT;
return NULL; return NULL;
} }
@ -158,24 +152,27 @@ xbps_find_pkg_installed_from_plist(const char *pkgname)
prop_dictionary_t d, pkgd; prop_dictionary_t d, pkgd;
pkg_state_t state = 0; pkg_state_t state = 0;
d = xbps_prepare_regpkgdb_dict(); if ((d = xbps_regpkgs_dictionary_init()) == NULL)
if (d == NULL)
return NULL; return NULL;
pkgd = xbps_find_pkg_in_dict(d, "packages", pkgname); pkgd = xbps_find_pkg_in_dict(d, "packages", pkgname);
if (pkgd == NULL) if (pkgd == NULL)
return NULL; goto fail;
if (xbps_get_pkg_state_installed(pkgname, &state) != 0) if (xbps_get_pkg_state_dictionary(pkgd, &state) != 0)
return NULL; goto fail;
switch (state) { switch (state) {
case XBPS_PKG_STATE_INSTALLED: case XBPS_PKG_STATE_INSTALLED:
case XBPS_PKG_STATE_UNPACKED: case XBPS_PKG_STATE_UNPACKED:
xbps_regpkgs_dictionary_release();
return prop_dictionary_copy(pkgd); return prop_dictionary_copy(pkgd);
default: default:
return NULL; break;
} }
fail:
xbps_regpkgs_dictionary_release();
return NULL;
} }
prop_dictionary_t SYMEXPORT prop_dictionary_t SYMEXPORT
@ -183,7 +180,7 @@ xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
const char *pkgname) const char *pkgname)
{ {
prop_object_iterator_t iter; prop_object_iterator_t iter;
prop_object_t obj; prop_object_t obj = NULL;
const char *dpkgn; const char *dpkgn;
assert(dict != NULL); 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))) { while ((obj = prop_object_iterator_next(iter))) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &dpkgn)) { "pkgname", &dpkgn))
obj = NULL;
break; break;
}
if (strcmp(dpkgn, pkgname) == 0) if (strcmp(dpkgn, pkgname) == 0)
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
if (obj == NULL)
errno = ENOENT;
return obj; 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 bool SYMEXPORT
xbps_find_string_in_array(prop_array_t array, const char *val) 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); iter = prop_array_iterator(array);
if (iter == NULL) if (iter == NULL)
return ENOMEM; return errno;
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (prop_object_type(obj) != PROP_TYPE_STRING) if (prop_object_type(obj) != PROP_TYPE_STRING)

View File

@ -44,13 +44,14 @@ xbps_purge_all_pkgs(void)
int rv = 0; int rv = 0;
pkg_state_t state = 0; pkg_state_t state = 0;
d = xbps_prepare_regpkgdb_dict(); if ((d = xbps_regpkgs_dictionary_init()) == NULL)
if (d == NULL) return errno;
return ENODEV;
iter = xbps_get_array_iter_from_dict(d, "packages"); iter = xbps_get_array_iter_from_dict(d, "packages");
if (iter == NULL) if (iter == NULL) {
return ENOENT; rv = errno;
goto out;
}
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
@ -66,6 +67,8 @@ xbps_purge_all_pkgs(void)
break; break;
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
out:
xbps_regpkgs_dictionary_release();
return rv; return rv;
} }

View File

@ -61,11 +61,10 @@ xbps_register_pkg(prop_dictionary_t pkgrd, bool automatic)
return EINVAL; return EINVAL;
} }
dict = prop_dictionary_internalize_from_file(plist); if ((dict = prop_dictionary_internalize_from_file(plist)) != NULL) {
if (dict != NULL) {
pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname); pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname);
if (pkgd == NULL) { if (pkgd == NULL) {
rv = ENOENT; rv = errno;
goto out; goto out;
} }
if (!prop_dictionary_set_cstring_nocopy(pkgd, if (!prop_dictionary_set_cstring_nocopy(pkgd,

73
lib/regpkgs_dictionary.c Normal file
View 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__));
}

View File

@ -200,7 +200,7 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
char *url = NULL; char *url = NULL;
int rv = 0; int rv = 0;
if ((rv = xbps_prepare_repolist_data()) != 0) { if ((rv = xbps_repository_pool_init()) != 0) {
errno = rv; errno = rv;
return NULL; return NULL;
} }
@ -215,9 +215,13 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
* libfetch! * libfetch!
*/ */
SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) { SIMPLEQ_FOREACH(rdata, &repodata_queue, chain) {
if ((pkgd = xbps_find_pkg_in_dict(rdata->rd_repod, pkgd = xbps_find_pkg_in_dict(rdata->rd_repod,
"packages", pkgname)) == NULL) "packages", pkgname);
if (pkgd == NULL) {
if (errno != ENOENT)
break;
continue; continue;
}
url = xbps_get_path_from_pkg_dict_repo(pkgd, rdata->rd_uri); url = xbps_get_path_from_pkg_dict_repo(pkgd, rdata->rd_uri);
if (url == NULL) if (url == NULL)
break; break;
@ -229,7 +233,7 @@ xbps_get_pkg_plist_dict_from_repo(const char *pkgname, const char *plistf)
free(url); free(url);
} }
xbps_release_repolist_data(); xbps_repository_pool_release();
if (plistd == NULL) if (plistd == NULL)
errno = ENOENT; errno = ENOENT;

148
lib/repository_pool.c Normal file
View 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__));
}

View File

@ -133,8 +133,7 @@ xbps_requiredby_pkg_remove(const char *pkgname)
if (plist == NULL) if (plist == NULL)
return EINVAL; return EINVAL;
dict = prop_dictionary_internalize_from_file(plist); if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
if (dict == NULL) {
free(plist); free(plist);
return errno; return errno;
} }

View File

@ -34,7 +34,7 @@
static int static int
set_new_state(prop_dictionary_t dict, pkg_state_t state) set_new_state(prop_dictionary_t dict, pkg_state_t state)
{ {
const char *state_str; const char *pkgname, *state_str;
assert(dict != NULL); 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)) if (!prop_dictionary_set_cstring_nocopy(dict, "state", state_str))
return -1; return -1;
if (prop_dictionary_get_cstring_nocopy(dict, "pkgname", &pkgname)) {
DPRINTF(("%s: changed pkg state to '%s'.\n",
pkgname, state_str));
}
return 0; return 0;
} }
@ -94,33 +99,17 @@ get_state(prop_dictionary_t dict)
int SYMEXPORT int SYMEXPORT
xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state) xbps_get_pkg_state_installed(const char *pkgname, pkg_state_t *state)
{ {
prop_dictionary_t dict, pkgd; prop_dictionary_t pkgd;
char *plist;
assert(pkgname != NULL); assert(pkgname != NULL);
plist = xbps_xasprintf("%s/%s/%s", xbps_get_rootdir(),
XBPS_META_PATH, XBPS_REGPKGDB); pkgd = xbps_find_pkg_installed_from_plist(pkgname);
if (plist == NULL) if (pkgd == NULL)
return errno; 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); *state = get_state(pkgd);
if (*state == 0) { if (*state == 0)
prop_object_release(dict);
return EINVAL; return EINVAL;
}
prop_object_release(dict);
return 0; return 0;
} }
@ -147,7 +136,7 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
int SYMEXPORT int SYMEXPORT
xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state) 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; prop_array_t array;
char *plist; char *plist;
int rv = 0; int rv = 0;
@ -158,16 +147,15 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
if (plist == NULL) if (plist == NULL)
return EINVAL; return EINVAL;
dict = prop_dictionary_internalize_from_file(plist); if ((dict = prop_dictionary_internalize_from_file(plist)) == NULL) {
if (dict == NULL) {
dict = prop_dictionary_create(); dict = prop_dictionary_create();
if (dict == NULL) { if (dict == NULL) {
free(plist); rv = errno;
return ENOMEM; goto out;
} }
array = prop_array_create(); array = prop_array_create();
if (array == NULL) { if (array == NULL) {
rv = ENOMEM; rv = errno;
goto out; goto out;
} }
pkgd = prop_dictionary_create(); 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", if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgname",
pkgname)) { pkgname)) {
prop_object_release(array); prop_object_release(array);
prop_object_release(pkgd);
rv = errno; rv = errno;
goto out; goto out;
} }
if ((rv = set_new_state(pkgd, state)) != 0) { if ((rv = set_new_state(pkgd, state)) != 0) {
prop_object_release(array); prop_object_release(array);
prop_object_release(pkgd);
goto out; goto out;
} }
if (!xbps_add_obj_to_array(array, pkgd)) { if (!xbps_add_obj_to_array(array, pkgd)) {
prop_object_release(array); prop_object_release(array);
rv = EINVAL; prop_object_release(pkgd);
rv = errno;
goto out; goto out;
} }
if (!xbps_add_obj_to_dict(dict, array, "packages")) { if (!xbps_add_obj_to_dict(dict, array, "packages")) {
prop_object_release(array); prop_object_release(array);
rv = EINVAL; rv = errno;
goto out; goto out;
} }
} else { } else {
pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname); pkgd = xbps_find_pkg_in_dict(dict, "packages", pkgname);
if (pkgd == NULL) { if (pkgd == NULL) {
if (errno && errno != ENOENT) {
rv = errno;
goto out;
}
newpkg = true; newpkg = true;
pkgd = prop_dictionary_create(); pkgd = prop_dictionary_create();
if (!prop_dictionary_set_cstring_nocopy(pkgd, 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"); array = prop_dictionary_get(dict, "packages");
if (array == NULL) { if (array == NULL) {
rv = ENOENT; if (newpkg)
prop_object_release(pkgd);
rv = errno;
goto out; goto out;
} }
if ((rv = set_new_state(pkgd, state)) != 0) { if ((rv = set_new_state(pkgd, state)) != 0) {
prop_object_release(pkgd); if (newpkg)
prop_object_release(pkgd);
goto out; goto out;
} }
if (newpkg && !xbps_add_obj_to_array(array, pkgd)) { if (newpkg && !xbps_add_obj_to_array(array, pkgd)) {
prop_object_release(pkgd); prop_object_release(pkgd);
rv = EINVAL; rv = errno;
goto out; goto out;
} }
} }
@ -229,8 +227,10 @@ xbps_set_pkg_state_installed(const char *pkgname, pkg_state_t state)
rv = errno; rv = errno;
out: out:
prop_object_release(dict); if (dict)
free(plist); prop_object_release(dict);
if (plist)
free(plist);
return rv; return rv;
} }

View File

@ -40,9 +40,9 @@ int SYMEXPORT
xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential) xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
{ {
prop_string_t filename, repoloc, arch; prop_string_t filename, repoloc, arch;
struct archive *ar; struct archive *ar = NULL;
const char *pkgname; const char *pkgname;
char *binfile; char *binfile = NULL;
int pkg_fd, rv = 0; int pkg_fd, rv = 0;
assert(pkg != NULL); assert(pkg != NULL);
@ -73,8 +73,8 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg, bool essential)
ar = archive_read_new(); ar = archive_read_new();
if (ar == NULL) { if (ar == NULL) {
rv = ENOMEM; rv = errno;
goto out2; 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, if ((rv = archive_read_open_fd(ar, pkg_fd,
ARCHIVE_READ_BLOCKSIZE)) != 0) ARCHIVE_READ_BLOCKSIZE)) != 0)
goto out3; goto out;
rv = unpack_archive_fini(ar, pkg, essential); 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 (rv == 0) {
if (fsync(pkg_fd) == -1) { if (fsync(pkg_fd) == -1) {
rv = errno; rv = errno;
goto out3; goto out;
} }
/* /*
* Set package state to unpacked. * 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, rv = xbps_set_pkg_state_installed(pkgname,
XBPS_PKG_STATE_UNPACKED); XBPS_PKG_STATE_UNPACKED);
} }
out3:
archive_read_finish(ar);
out2:
(void)close(pkg_fd);
out: out:
free(binfile); if (ar)
archive_read_finish(ar);
if (pkg_fd != -1)
(void)close(pkg_fd);
if (binfile)
free(binfile);
return rv; return rv;
} }

View File

@ -128,7 +128,7 @@ int SYMEXPORT
xbps_check_is_installed_pkg(const char *pkg) xbps_check_is_installed_pkg(const char *pkg)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
const char *instpkgver; const char *instpkgver = NULL;
char *pkgname; char *pkgname;
int rv = 0; int rv = 0;
pkg_state_t state = 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); dict = xbps_find_pkg_installed_from_plist(pkgname);
if (dict == NULL) { if (dict == NULL) {
free(pkgname); 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 * Check that package state is fully installed, not
* unpacked or something else. * 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); prop_object_release(dict);
free(pkgname); free(pkgname);
return -1; return -1;