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_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;

View File

@ -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);
/*

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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", &regver)) {
prop_object_release(newpkgd);

View File

@ -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);
}

View File

@ -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,

View File

@ -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)

View File

@ -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 *);

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 += 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

View File

@ -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",

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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
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;
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
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)
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;