diff --git a/bin/xbps-bin.c b/bin/xbps-bin.c index 5460e59e84..172d6bac23 100644 --- a/bin/xbps-bin.c +++ b/bin/xbps-bin.c @@ -273,9 +273,27 @@ main(int argc, char **argv) if (argc != 3) usage(); - rv = xbps_install_binary_pkg(argv[2], "/home/juan/root_xbps"); +#if 0 + dict = getrepolist_dict(); + if (!xbps_callback_array_iter_in_dict(dict, "repository-list", + xbps_install_binary_pkg_from_repolist, argv[2])) { + prop_object_release(dict); + printf("ERROR: unable to find a binary package " + "for %s.\n", argv[2]); + exit(EINVAL); + } +#endif + + dict = prop_dictionary_internalize_from_file("/storage/xbps/binpkgs/pkg-index.plist"); + if (dict == NULL) + exit(EINVAL); + + rv = xbps_install_binary_pkg(dict, argv[2], + "/home/juan/root_xbps"); if (rv) exit(rv); + prop_object_release(dict); + } else { usage(); } diff --git a/include/plist.h b/include/plist.h index e5817c961f..fe92f05c06 100644 --- a/include/plist.h +++ b/include/plist.h @@ -150,16 +150,18 @@ bool xbps_remove_string_from_array(prop_object_t, void *, bool *); bool xbps_show_pkg_info_from_repolist(prop_object_t obj, void *, bool *); bool xbps_show_pkg_namedesc(prop_object_t, void *, bool *); bool xbps_search_string_in_pkgs(prop_object_t, void *, bool *); -int xbps_install_binary_pkg(const char *, const char *); -int xbps_unpack_binary_pkg(const char *, int (*cb)(struct archive *)); -int xbps_check_reqdeps_in_pkg(const char *, prop_dictionary_t); /* Utils */ -bool xbps_append_full_path(char *, const char *, const char *); -int xbps_check_is_installed_pkg(const char *, const char *); -int xbps_cmpver_packages(const char *, const char *); -int xbps_cmpver_versions(const char *, const char *); +bool xbps_append_full_path(char *, const char *, const char *); +int xbps_check_is_installed_pkg(const char *, const char *); +int xbps_cmpver_packages(const char *, const char *); +int xbps_cmpver_versions(const char *, const char *); const char * xbps_get_pkg_version(const char *); char * xbps_get_pkg_name(const char *); +int xbps_install_pkg_deps(prop_dictionary_t, prop_dictionary_t); +int xbps_install_binary_pkg(prop_dictionary_t, const char *, + const char *); +int xbps_unpack_binary_pkg(prop_dictionary_t, int (*cb)(struct archive *)); +int xbps_unpack_archive_cb(struct archive *); #endif /* !_XBPS_PLIST_H_ */ diff --git a/include/xbps_api.h b/include/xbps_api.h index 6347a9c3c5..3c91487a32 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -28,6 +28,7 @@ #include #include +#define NDEBUG #include #include diff --git a/lib/depends.c b/lib/depends.c index 9409dc3014..a9098af03e 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -97,11 +97,13 @@ xbps_add_pkg_dependency(const char *pkgname, prop_dictionary_t dict) len = strlen(pkgname) + 1; dep->name = malloc(len); - if (dep->name == NULL) + if (dep->name == NULL) { + free(dep); return; + } - memcpy(dep->name, pkgname, len); - dep->name[len + 1] = '\0'; + memcpy(dep->name, pkgname, len - 1); + dep->name[len - 1] = '\0'; dep->dict = prop_dictionary_copy(dict); LIST_INSERT_HEAD(&pkg_deps_list, dep, deps); @@ -122,12 +124,13 @@ pkg_has_rundeps(prop_dictionary_t pkg) } static int -find_deps_in_pkg(const char *plist, prop_dictionary_t pkg) +find_deps_in_pkg(prop_dictionary_t repo, prop_dictionary_t pkg) { prop_dictionary_t pkgdict; prop_array_t array; + prop_string_t name; prop_object_t obj; - prop_object_iterator_t iter; + prop_object_iterator_t iter = NULL; const char *reqpkg; char *pkgname; @@ -139,24 +142,23 @@ find_deps_in_pkg(const char *plist, prop_dictionary_t pkg) if (iter == NULL) return -1; + name = prop_dictionary_get(pkg, "pkgname"); + xbps_add_pkg_dependency(prop_string_cstring_nocopy(name), pkg); + /* Iterate over the list of required run dependencies for a pkg */ while ((obj = prop_object_iterator_next(iter))) { reqpkg = prop_string_cstring_nocopy(obj); pkgname = xbps_get_pkg_name(reqpkg); - pkgdict = xbps_find_pkg_from_plist(plist, pkgname); + pkgdict = xbps_find_pkg_in_dict(repo, pkgname); xbps_add_pkg_dependency(pkgname, pkgdict); free(pkgname); /* Iterate on required pkg to find more deps */ if (pkg_has_rundeps(pkgdict)) { /* more deps? */ - prop_object_iterator_release(iter); - if (!find_deps_in_pkg(plist, pkgdict)) { - prop_object_release(pkgdict); - return 0; - } + if (!find_deps_in_pkg(repo, pkgdict)) + continue; } - prop_object_release(pkgdict); } prop_object_iterator_release(iter); @@ -165,30 +167,47 @@ find_deps_in_pkg(const char *plist, prop_dictionary_t pkg) } int -xbps_check_reqdeps_in_pkg(const char *plist, prop_dictionary_t pkg) +xbps_install_pkg_deps(prop_dictionary_t repo, prop_dictionary_t pkg) { - char repolist[PATH_MAX]; + pkg_dep_t *dep; + prop_string_t pkgname, version; + int rv = 0; assert(pkg != NULL); + assert(repo != NULL); assert(prop_object_type(pkg) == PROP_TYPE_DICTIONARY); - assert(prop_dictionary_count(pkg) != 0); - assert(plist != NULL); + assert(prop_object_type(repo) == PROP_TYPE_DICTIONARY); if (!pkg_has_rundeps(pkg)) { - /* Package has no required rundeps */ + /* Package has no required dependencies. */ return 0; } - if (!xbps_append_full_path(repolist, - "/storage/xbps/binpkgs", XBPS_PKGINDEX)) { - errno = ENOENT; - return -1; - } - - if (find_deps_in_pkg(repolist, pkg) == -1) { + /* Check what dependencies are required. */ + if (find_deps_in_pkg(repo, pkg) == -1) { errno = XBPS_PKG_EINDEPS; return -1; } + /* + * Iterate over the list of dependencies and install them. + */ + LIST_FOREACH(dep, &pkg_deps_list, deps) { + pkgname = prop_dictionary_get(dep->dict, "pkgname"); + version = prop_dictionary_get(dep->dict, "version"); + printf("Required package: %s >= %s\n", + prop_string_cstring_nocopy(pkgname), + prop_string_cstring_nocopy(version)); + (void)fflush(stdout); + + rv = xbps_unpack_binary_pkg(dep->dict, xbps_unpack_archive_cb); + if (rv != 0) + break; + + LIST_REMOVE(dep, deps); + free(dep->name); + prop_object_release(dep->dict); + } + return 1; } diff --git a/lib/install.c b/lib/install.c index 412330beef..d5f37a801b 100644 --- a/lib/install.c +++ b/lib/install.c @@ -32,15 +32,13 @@ #include -static int unpack_archive_cb(struct archive *); - int -xbps_install_binary_pkg(const char *pkgname, const char *dest) +xbps_install_binary_pkg(prop_dictionary_t repo, const char *pkgname, + const char *dest) { - prop_dictionary_t repo_dict, pkg_rdict, dict; + prop_dictionary_t pkg_rdict, dict; prop_object_t obj; - const char *repo = "/storage/xbps/binpkgs/pkg-index.plist"; - char dbfile[PATH_MAX], binfile[PATH_MAX]; + char dbfile[PATH_MAX]; int rv = 0; assert(pkgname != NULL); @@ -50,70 +48,50 @@ xbps_install_binary_pkg(const char *pkgname, const char *dest) } /* Get pkg metadata from a repository */ - repo_dict = prop_dictionary_internalize_from_file(repo); - if (repo_dict == NULL) - return -1; - - pkg_rdict = xbps_find_pkg_in_dict(repo_dict, pkgname); - if (pkg_rdict == NULL) { - prop_object_release(repo_dict); + pkg_rdict = xbps_find_pkg_in_dict(repo, pkgname); + if (pkg_rdict == NULL) return XBPS_PKG_ENOTINREPO; - } - - if (!xbps_append_full_path(dbfile, NULL, XBPS_REGPKGDB)) { - prop_object_release(repo_dict); - return EINVAL; - } /* Check if package is already installed. */ + if (!xbps_append_full_path(dbfile, NULL, XBPS_REGPKGDB)) + return EINVAL; + dict = prop_dictionary_internalize_from_file(dbfile); if (dict && xbps_find_pkg_in_dict(dict, pkgname)) { - prop_object_release(repo_dict); prop_object_release(dict); return XBPS_PKG_EEXIST; } - /* Append filename to the full path for binary pkg */ - obj = prop_dictionary_get(pkg_rdict, "filename"); - if (!xbps_append_full_path(binfile, "/storage/xbps/binpkgs", - prop_string_cstring_nocopy(obj))) { - prop_object_release(repo_dict); - return EINVAL; - } - obj = prop_dictionary_get(pkg_rdict, "version"); - printf("=> Found package: %s-%s.", + printf("Available package: %s-%s.\n", pkgname, prop_string_cstring_nocopy(obj)); - printf("\n"); - (void)fflush(stdout); - printf("==> Checking dependencies... "); (void)fflush(stdout); - /* Looks like it's not, check dependencies and install */ - switch (xbps_check_reqdeps_in_pkg(dbfile, pkg_rdict)) { + /* + * Install the package, and its dependencies if there are. + */ + switch (xbps_install_pkg_deps(repo, pkg_rdict)) { case -1: - /* There was an error checking pkg deps */ - prop_object_release(repo_dict); - printf("error, exiting!\n"); - fflush(stdout); return XBPS_PKG_EINDEPS; case 0: - /* Package has no deps, just install it */ - printf("none, unpacking... "); - (void)fflush(stdout); - rv = xbps_unpack_binary_pkg(binfile, unpack_archive_cb); + /* + * Package has no dependencies, just install it. + */ + rv = xbps_unpack_binary_pkg(pkg_rdict, xbps_unpack_archive_cb); break; case 1: - /* Package needs deps */ + /* + * 1 means that package has dependencies, but + * xbps_install_pkg_deps() takes care of it. + */ break; } - prop_object_release(repo_dict); return rv; } -static int -unpack_archive_cb(struct archive *ar) +int +xbps_unpack_archive_cb(struct archive *ar) { struct archive_entry *entry; int rv = 0; @@ -125,18 +103,35 @@ unpack_archive_cb(struct archive *ar) } } - printf("done.\n"); archive_read_finish(ar); return rv; } int -xbps_unpack_binary_pkg(const char *filename, int (*cb)(struct archive *)) +xbps_unpack_binary_pkg(prop_dictionary_t pkg, int (*cb)(struct archive *)) { + prop_string_t pkgname, version, filename; struct archive *ar; + char binfile[PATH_MAX]; int rv; - assert(filename != NULL); + assert(pkg != NULL); + + /* Append filename to the full path for binary pkg */ + filename = prop_dictionary_get(pkg, "filename"); + if (!xbps_append_full_path(binfile, "/storage/xbps/binpkgs", + prop_string_cstring_nocopy(filename))) + return EINVAL; + + pkgname = prop_dictionary_get(pkg, "pkgname"); + version = prop_dictionary_get(pkg, "version"); + + printf("Unpacking %s-%s (from %s)... ", + prop_string_cstring_nocopy(pkgname), + prop_string_cstring_nocopy(version), + prop_string_cstring_nocopy(filename)); + + (void)fflush(stdout); ar = archive_read_new(); if (ar == NULL) @@ -146,10 +141,13 @@ xbps_unpack_binary_pkg(const char *filename, int (*cb)(struct archive *)) archive_read_support_compression_all(ar); archive_read_support_format_all(ar); - if ((rv = archive_read_open_filename(ar, filename, 2048)) != 0) { + if ((rv = archive_read_open_filename(ar, binfile, 2048)) != 0) { archive_read_finish(ar); return rv; } - return (*cb)(ar); + if ((rv = (*cb)(ar)) == 0) + printf("done.\n"); + + return rv; } diff --git a/lib/plist.c b/lib/plist.c index b4de1c8b6b..fe9e097f94 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -99,7 +99,7 @@ prop_dictionary_t xbps_find_pkg_from_plist(const char *plist, const char *pkgname) { prop_dictionary_t dict; - prop_dictionary_t obj; + prop_dictionary_t obj, res; assert(plist != NULL); assert(pkgname != NULL); @@ -117,7 +117,10 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname) return NULL; } - return obj; + res = prop_dictionary_copy(obj); + prop_object_release(dict); + + return res; } prop_dictionary_t diff --git a/vars.mk b/vars.mk index 7e30b5626c..3f267c4a0b 100644 --- a/vars.mk +++ b/vars.mk @@ -6,4 +6,4 @@ LIBDIR ?= $(PREFIX)/lib CPPFLAGS += -I../include CFLAGS += -Wstack-protector -fstack-protector-all -CFLAGS += -ggdb -O2 -Wall -Werror -fPIC -DPIC +CFLAGS += -O2 -Wall -Werror -fPIC -DPIC