From fe15380e1bc819f2de19fa14966ccc7d215036c9 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Tue, 18 Jan 2011 18:21:55 +0100 Subject: [PATCH] libxbps: modify the API, new func xbps_get_binpkg_repo_uri(). This function replaces xbps_repository_get_path_from_pkg_dict() and xbps_get_binpkg_local_path(). It takes a pkg dictionary as returned by a repository pkg index or a transaction dictionary and returns a string with the full path to the binary pkg, either in local repos, cachedir or remote repos. Update all code to use this function... sorry I broke ABI compatiblity. --- bin/xbps-bin/install.c | 93 ++++++++++++++++++-------------------- bin/xbps-repo/find-files.c | 2 +- bin/xbps-repo/repository.c | 2 +- include/xbps_api.h | 29 ++---------- lib/package_unpack.c | 9 ++-- lib/repository_plist.c | 37 +-------------- lib/util.c | 33 ++++++++++---- 7 files changed, 79 insertions(+), 126 deletions(-) diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c index 6e7bd716..3e051ebe 100644 --- a/bin/xbps-bin/install.c +++ b/bin/xbps-bin/install.c @@ -70,26 +70,28 @@ show_missing_deps(prop_dictionary_t d) show_missing_dep_cb, NULL); } -static bool +static int check_binpkg_hash(const char *path, const char *filename, const char *sha256) { - int rv = 0; + int rv; printf("Checking %s integrity... ", filename); rv = xbps_check_file_hash(path, sha256); - errno = rv; if (rv != 0 && rv != ERANGE) { fprintf(stderr, "\nxbps-bin: unexpected error: %s\n", strerror(rv)); - return false; + return rv; } else if (rv == ERANGE) { printf("hash mismatch!\n"); - return false; + fprintf(stderr, "Package '%s' has wrong checksum, removing " + "and refetching it again...\n", filename); + (void)remove(path); + return rv; } printf("OK.\n"); - return true; + return 0; } static int @@ -97,85 +99,76 @@ download_package_list(prop_object_iterator_t iter) { prop_object_t obj; const char *pkgver, *repoloc, *filename, *cachedir, *sha256; - char *binfile, *lbinfile; + char *binfile; int rv = 0; + bool cksum; cachedir = xbps_get_cachedir(); if (cachedir == NULL) return EINVAL; +again: while ((obj = prop_object_iterator_next(iter)) != NULL) { + cksum = false; + prop_dictionary_get_bool(obj, "checksum_ok", &cksum); + if (cksum == true) + continue; + prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "filename", &filename); prop_dictionary_get_cstring_nocopy(obj, "filename-sha256", &sha256); - lbinfile = xbps_get_binpkg_local_path(obj, repoloc); - if (lbinfile == NULL) + binfile = xbps_get_binpkg_repo_uri(obj); + if (binfile == NULL) return errno; - - /* - * If package is in a local repository, check its hash - * and pass to next one. - */ - if (!xbps_check_is_repo_string_remote(repoloc)) { - if (!check_binpkg_hash(lbinfile, filename, sha256)) { - free(lbinfile); - return errno; - } - free(lbinfile); - continue; - } /* * If downloaded package is in cachedir, check its hash - * and restart it again if doesn't match. + * and refetch the binpkg again if didn't match. */ - if (access(lbinfile, R_OK) == 0) { - if (check_binpkg_hash(lbinfile, filename, sha256)) { - free(lbinfile); - continue; - } - if (errno && errno != ERANGE) { - free(lbinfile); - return errno; - } else if (errno == ERANGE) { - (void)remove(lbinfile); - printf("Refetching %s again...\n", - filename); - errno = 0; + if (access(binfile, R_OK) == 0) { + rv = check_binpkg_hash(binfile, filename, sha256); + free(binfile); + if (rv != 0 && rv != ERANGE) { + return rv; + } else if (rv == ERANGE) { + break; } + prop_dictionary_set_bool(obj, "checksum_ok", true); + continue; } if (xbps_mkpath(__UNCONST(cachedir), 0755) == -1) { - free(lbinfile); - return errno; - } - binfile = xbps_repository_get_path_from_pkg_dict(obj, repoloc); - if (binfile == NULL) { - free(lbinfile); + free(binfile); return errno; } printf("Downloading %s binary package ...\n", pkgver); rv = xbps_fetch_file(binfile, cachedir, false, NULL); - free(binfile); if (rv == -1) { fprintf(stderr, "xbps-bin: couldn't download `%s'\n", filename); fprintf(stderr, "xbps-bin: %s returned: `%s'\n", repoloc, xbps_fetch_error_string()); - free(lbinfile); + free(binfile); return -1; } - if (!check_binpkg_hash(lbinfile, filename, sha256)) { - fprintf(stderr, "W: removing wrong %s file ...\n", - filename); - (void)remove(lbinfile); - free(lbinfile); + free(binfile); + binfile = xbps_get_binpkg_repo_uri(obj); + if (binfile == NULL) return errno; + + rv = check_binpkg_hash(binfile, filename, sha256); + free(binfile); + if (rv != 0 && rv != ERANGE) { + return rv; + } else if (rv == ERANGE) { + break; } - free(lbinfile); + prop_dictionary_set_bool(obj, "checksum_ok", true); } prop_object_iterator_reset(iter); + if (rv == ERANGE) + goto again; return 0; } diff --git a/bin/xbps-repo/find-files.c b/bin/xbps-repo/find-files.c index ecfeb8fd..15aa11b0 100644 --- a/bin/xbps-repo/find-files.c +++ b/bin/xbps-repo/find-files.c @@ -91,7 +91,7 @@ find_files_in_package(struct repository_pool_index *rpi, void *arg, bool *done) printf("Looking in repository '%s', please wait...\n", rpi->rpi_uri); while ((obj = prop_object_iterator_next(iter))) { - url = xbps_repository_get_path_from_pkg_dict(obj, rpi->rpi_uri); + url = xbps_get_binpkg_repo_uri(obj); if (url == NULL) { rv = -1; break; diff --git a/bin/xbps-repo/repository.c b/bin/xbps-repo/repository.c index d0b78620..1ebc67c8 100644 --- a/bin/xbps-repo/repository.c +++ b/bin/xbps-repo/repository.c @@ -250,7 +250,7 @@ show_pkg_info_from_repolist(const char *pkgname) return errno; prop_dictionary_get_cstring_nocopy(pkgd, "repository", &repoloc); - url = xbps_repository_get_path_from_pkg_dict(pkgd, repoloc); + url = xbps_get_binpkg_repo_uri(pkgd); if (url == NULL) { prop_object_release(pkgd); return errno; diff --git a/include/xbps_api.h b/include/xbps_api.h index f7db8e51..67870abc 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -470,7 +470,7 @@ bool xbps_remove_string_from_array(prop_array_t array, const char *str); * @param[in] pkgname Package name to match. * @param[in] check_state Set it to true to check that package * is in XBPS_PKG_STATE_CONFIG_FILES state. - * + :wq!* * @return 0 on success, otherwise an errno value. */ int xbps_purge_pkg(const char *pkgname, bool check_state); @@ -653,22 +653,6 @@ prop_dictionary_t xbps_repository_get_transaction_dict(void); /** @addtogroup repo_plist */ /*@{*/ -/** - * Returns a malloc(3)ed URI string pointing to a binary package file, - * either from a local or remote repository. - * - * @note The caller is responsible to free(3) the returned buffer. - * - * @param[in] d Package proplib dictionary as returned by the - * transaction dictionary, aka xbps_repository_get_transaction_dict(). - * @param[in] uri URI pointing to a repository. - * - * @return A string with the full path, NULL otherwise and errno - * is set appropiately. - */ -char *xbps_repository_get_path_from_pkg_dict(prop_dictionary_t d, - const char *uri); - /** * Iterate over the the repository pool and search for a plist file * in the binary package named 'pkgname'. The plist file will be @@ -959,20 +943,17 @@ bool xbps_check_is_installed_pkgname(const char *pkgname); bool xbps_check_is_repo_string_remote(const char *uri); /** - * Gets the full path to a binary package file as returned by a - * package transaction dictionary \a pkgd, by looking at the - * repository location \a repoloc. + * Gets the full URI to a binary package file as returned by a + * package dictionary from a repository in \a pkgd, by looking at the + * repository location object "repository" in its dictionary. * * @param[in] pkgd Package dictionary stored in a transaction dictionary. - * @param[in] repoloc Repository location as returned by the object - * repository in the package dictionary of a transaction - * dictionary. * * @return A pointer to a malloc(3)ed string, NULL otherwise and * errno is set appropiately. The pointer should be free(3)d when it's * no longer needed. */ -char *xbps_get_binpkg_local_path(prop_dictionary_t pkgd, const char *repoloc); +char *xbps_get_binpkg_repo_uri(prop_dictionary_t pkgd); /** * Gets the full path to a repository package index plist file, as diff --git a/lib/package_unpack.c b/lib/package_unpack.c index 6fd5b597..5da251d9 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -404,7 +404,7 @@ out: int xbps_unpack_binary_pkg(prop_dictionary_t pkg) { - const char *pkgname, *repoloc, *version; + const char *pkgname, *version; struct archive *ar = NULL; char *binfile = NULL; int pkg_fd, rv = 0; @@ -412,10 +412,9 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg) assert(pkg != NULL); prop_dictionary_get_cstring_nocopy(pkg, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(pkg, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(pkg, "version", &version); - binfile = xbps_get_binpkg_local_path(pkg, repoloc); + binfile = xbps_get_binpkg_repo_uri(pkg); if (binfile == NULL) return EINVAL; @@ -423,8 +422,10 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg) rv = errno; xbps_dbg_printf("cannot open '%s' for unpacking %s\n", binfile, strerror(errno)); + free(binfile); goto out; } + free(binfile); ar = archive_read_new(); if (ar == NULL) { @@ -457,8 +458,6 @@ out: archive_read_finish(ar); if (pkg_fd != -1) (void)close(pkg_fd); - if (binfile) - free(binfile); return rv; } diff --git a/lib/repository_plist.c b/lib/repository_plist.c index 0f31cbf0..7898bc44 100644 --- a/lib/repository_plist.c +++ b/lib/repository_plist.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2010 Juan Romero Pardines. + * Copyright (c) 2009-2011 Juan Romero Pardines. * Copyright (c) 2008, 2009 Joerg Sonnenberger * All rights reserved. * @@ -143,37 +143,6 @@ open_archive(const char *url) return a; } -static char * -binpkg_in_cachedir(prop_dictionary_t d, const char *uri) -{ - char *lbinfile; - - lbinfile = xbps_get_binpkg_local_path(d, uri); - if (lbinfile == NULL) - return NULL; - - if (access(lbinfile, R_OK) == 0) - return lbinfile; - - return NULL; -} - -char * -xbps_repository_get_path_from_pkg_dict(prop_dictionary_t d, const char *uri) -{ - const char *arch, *filen; - char *path = NULL; - - path = binpkg_in_cachedir(d, uri); - if (path) - return path; - - prop_dictionary_get_cstring_nocopy(d, "architecture", &arch); - prop_dictionary_get_cstring_nocopy(d, "filename", &filen); - - return xbps_xasprintf("%s/%s/%s", uri, arch, filen); -} - prop_dictionary_t xbps_repository_get_pkg_plist_dict_from_url(const char *url, const char *plistf) { @@ -225,7 +194,6 @@ prop_dictionary_t xbps_repository_get_pkg_plist_dict(const char *pkgname, const char *plistf) { prop_dictionary_t pkgd = NULL, plistd = NULL; - const char *repoloc; char *url; int rv = 0; @@ -246,8 +214,7 @@ xbps_repository_get_pkg_plist_dict(const char *pkgname, const char *plistf) if (pkgd == NULL) goto out; - prop_dictionary_get_cstring_nocopy(pkgd, "repository", &repoloc); - url = xbps_repository_get_path_from_pkg_dict(pkgd, repoloc); + url = xbps_get_binpkg_repo_uri(pkgd); if (url == NULL) { errno = EINVAL; goto out; diff --git a/lib/util.c b/lib/util.c index 38df7c13..18acbdd5 100644 --- a/lib/util.c +++ b/lib/util.c @@ -374,22 +374,35 @@ xbps_get_pkg_index_plist(const char *uri) } char * -xbps_get_binpkg_local_path(prop_dictionary_t pkgd, const char *repoloc) +xbps_get_binpkg_repo_uri(prop_dictionary_t pkg_repod) { - const char *filen, *arch, *cdir; + const char *filen, *arch, *cdir, *repoloc; + char *lbinpkg = NULL; + + prop_dictionary_get_cstring_nocopy(pkg_repod, "filename", &filen); + prop_dictionary_get_cstring_nocopy(pkg_repod, "architecture", &arch); + prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc); - prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen); - prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch); cdir = xbps_get_cachedir(); if (cdir == NULL) return NULL; - if (!xbps_check_is_repo_string_remote(repoloc)) { - /* local repo */ - return xbps_xasprintf("%s/%s/%s", repoloc, arch, filen); - } - /* cachedir */ - return xbps_xasprintf("%s/%s", cdir, filen); + /* + * First check if binpkg is available in cachedir. + */ + lbinpkg = xbps_xasprintf("%s/%s", cdir, filen); + if (lbinpkg == NULL) + return NULL; + + if (access(lbinpkg, R_OK) == 0) + return lbinpkg; + + free(lbinpkg); + + /* + * Local and remote repositories use the same path. + */ + return xbps_xasprintf("%s/%s/%s", repoloc, arch, filen); } bool