diff --git a/bin/xbps-bin/check.c b/bin/xbps-bin/check.c index 95d12070..6bca8abe 100644 --- a/bin/xbps-bin/check.c +++ b/bin/xbps-bin/check.c @@ -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; diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c index 9956f2bf..a213c490 100644 --- a/bin/xbps-bin/install.c +++ b/bin/xbps-bin/install.c @@ -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); /* diff --git a/bin/xbps-bin/main.c b/bin/xbps-bin/main.c index 7ed0c1bc..fefe4348 100644 --- a/bin/xbps-bin/main.c +++ b/bin/xbps-bin/main.c @@ -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); } diff --git a/bin/xbps-bin/show-deps.c b/bin/xbps-bin/show-deps.c index 8360562f..eea714e8 100644 --- a/bin/xbps-bin/show-deps.c +++ b/bin/xbps-bin/show-deps.c @@ -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; } diff --git a/bin/xbps-repo/index.c b/bin/xbps-repo/index.c index 0ef4a500..d28081ea 100644 --- a/bin/xbps-repo/index.c +++ b/bin/xbps-repo/index.c @@ -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); diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index a37ebd0d..fdecfe0e 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -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); } diff --git a/bin/xbps-repo/repository.c b/bin/xbps-repo/repository.c index a516acb0..41f8d4bd 100644 --- a/bin/xbps-repo/repository.c +++ b/bin/xbps-repo/repository.c @@ -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, diff --git a/bin/xbps-repo/util.c b/bin/xbps-repo/util.c index c5bc34cb..9d31ded9 100644 --- a/bin/xbps-repo/util.c +++ b/bin/xbps-repo/util.c @@ -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) diff --git a/include/xbps_api.h b/include/xbps_api.h index 61844909..27e6c040 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -38,7 +38,7 @@ #include /* 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 *); diff --git a/lib/Makefile b/lib/Makefile index b34c7932..9b92b6c0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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 diff --git a/lib/configure.c b/lib/configure.c index c99a95e6..7ae0ffda 100644 --- a/lib/configure.c +++ b/lib/configure.c @@ -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", diff --git a/lib/depends.c b/lib/depends.c index 0b381abb..53b75033 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -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; } } diff --git a/lib/findpkg.c b/lib/findpkg.c index 8a6251af..cb018da2 100644 --- a/lib/findpkg.c +++ b/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; } diff --git a/lib/orphans.c b/lib/orphans.c index 48614ee7..52f56f74 100644 --- a/lib/orphans.c +++ b/lib/orphans.c @@ -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; } diff --git a/lib/plist.c b/lib/plist.c index 4de0d10b..b5f02068 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -31,9 +31,6 @@ #include -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) diff --git a/lib/purge.c b/lib/purge.c index 53bad4c0..f5e0d8b4 100644 --- a/lib/purge.c +++ b/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; } diff --git a/lib/register.c b/lib/register.c index b44b7a2f..86841822 100644 --- a/lib/register.c +++ b/lib/register.c @@ -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, diff --git a/lib/regpkgs_dictionary.c b/lib/regpkgs_dictionary.c new file mode 100644 index 00000000..1b819514 --- /dev/null +++ b/lib/regpkgs_dictionary.c @@ -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 +#include +#include +#include +#include + +#include + +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__)); +} diff --git a/lib/repository_plist.c b/lib/repository_plist.c index cf119e0d..1d2b6869 100644 --- a/lib/repository_plist.c +++ b/lib/repository_plist.c @@ -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; diff --git a/lib/repository_pool.c b/lib/repository_pool.c new file mode 100644 index 00000000..682da627 --- /dev/null +++ b/lib/repository_pool.c @@ -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 +#include +#include +#include +#include + +#include + +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__)); +} diff --git a/lib/requiredby.c b/lib/requiredby.c index a7eb7ae9..6a3087c8 100644 --- a/lib/requiredby.c +++ b/lib/requiredby.c @@ -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; } diff --git a/lib/state.c b/lib/state.c index fa436ce3..b4282af5 100644 --- a/lib/state.c +++ b/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; } diff --git a/lib/unpack.c b/lib/unpack.c index e156499a..d52fa02e 100644 --- a/lib/unpack.c +++ b/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; } diff --git a/lib/util.c b/lib/util.c index 72081eaf..12441cb1 100644 --- a/lib/util.c +++ b/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;