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.
This commit is contained in:
Juan RP 2011-01-18 18:21:55 +01:00
parent 6d7121c5bd
commit fe15380e1b
7 changed files with 79 additions and 126 deletions

View File

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

View File

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

View File

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

View File

@ -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
* <em>repository</em> 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

View File

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

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009-2010 Juan Romero Pardines.
* Copyright (c) 2009-2011 Juan Romero Pardines.
* Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg (at) NetBSD.org>
* 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;

View File

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