/*- * Copyright (c) 2009-2013 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 #include #include "xbps_api_impl.h" struct rpool { SIMPLEQ_ENTRY(rpool) entries; struct xbps_repo *repo; }; static SIMPLEQ_HEAD(rpool_head, rpool) rpool_queue = SIMPLEQ_HEAD_INITIALIZER(rpool_queue); /** * @file lib/rpool.c * @brief Repository pool routines * @defgroup repopool Repository pool functions */ int HIDDEN xbps_rpool_init(struct xbps_handle *xhp) { struct rpool *rp; const char *repouri; bool foundrepo = false; int rv = 0; assert(xhp); if (xhp->rpool_initialized) return 0; for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { rp = malloc(sizeof(struct rpool)); assert(rp); xbps_array_get_cstring_nocopy(xhp->repositories, i, &repouri); if ((rp->repo = xbps_repo_open(xhp, repouri)) == NULL) { rp->repo = calloc(1, sizeof(struct xbps_repo)); assert(rp->repo); } rp->repo->idx = xbps_repo_get_plist(rp->repo, XBPS_PKGINDEX); rp->repo->uri = repouri; rp->repo->xhp = xhp; SIMPLEQ_INSERT_TAIL(&rpool_queue, rp, entries); foundrepo = true; xbps_dbg_printf(xhp, "[rpool] `%s' registered.\n", repouri); } if (!foundrepo) { /* no repositories available, error out */ rv = ENOTSUP; goto out; } xhp->rpool_initialized = true; xbps_dbg_printf(xhp, "[rpool] initialized ok.\n"); out: if (rv != 0) xbps_rpool_release(xhp); return rv; } void HIDDEN xbps_rpool_release(struct xbps_handle *xhp) { struct rpool *rp; if (!xhp->rpool_initialized) return; while ((rp = SIMPLEQ_FIRST(&rpool_queue))) { SIMPLEQ_REMOVE(&rpool_queue, rp, rpool, entries); xbps_repo_close(rp->repo); free(rp); } xhp->rpool_initialized = false; xbps_dbg_printf(xhp, "[rpool] released ok.\n"); } int xbps_rpool_sync(struct xbps_handle *xhp, const char *uri) { const char *repouri; for (unsigned int i = 0; i < xbps_array_count(xhp->repositories); i++) { xbps_array_get_cstring_nocopy(xhp->repositories, i, &repouri); /* If argument was set just process that repository */ if (uri && strcmp(repouri, uri)) continue; if (xbps_repo_sync(xhp, repouri) == -1) { xbps_dbg_printf(xhp, "[rpool] `%s' failed to fetch repository data: %s\n", repouri, fetchLastErrCode == 0 ? strerror(errno) : xbps_fetch_error_string()); continue; } } return 0; } int xbps_rpool_foreach(struct xbps_handle *xhp, int (*fn)(struct xbps_repo *, void *, bool *), void *arg) { struct rpool *rp; int rv = 0; bool done = false; assert(fn != NULL); /* Initialize repository pool */ if ((rv = xbps_rpool_init(xhp)) != 0) { if (rv == ENOTSUP) { xbps_dbg_printf(xhp, "[rpool] empty repository list.\n"); } else if (rv != ENOENT && rv != ENOTSUP) { xbps_dbg_printf(xhp, "[rpool] couldn't initialize: %s\n", strerror(rv)); } return rv; } /* Iterate over repository pool */ SIMPLEQ_FOREACH(rp, &rpool_queue, entries) { /* ignore invalid repos */ if (rp->repo->idx == NULL) continue; rv = (*fn)(rp->repo, arg, &done); if (rv != 0 || done) break; } return rv; }