From c2eed68471c87bc98369ce7014a898cc6fbe33e5 Mon Sep 17 00:00:00 2001
From: Juan RP <xtraeme@gmail.com>
Date: Thu, 10 Nov 2011 23:14:50 +0100
Subject: [PATCH] libxbps: add xbps_repository_pool_sync, to sync repoidx from
 all remotes.

---
 bin/xbps-repo/defs.h        |  1 -
 bin/xbps-repo/main.c        |  2 +-
 bin/xbps-repo/repository.c  | 38 ------------------
 include/xbps_api.h          | 15 +++++--
 lib/repository_pool.c       | 78 +++++++++++++++++++++----------------
 lib/repository_sync_index.c |  4 +-
 6 files changed, 61 insertions(+), 77 deletions(-)

diff --git a/bin/xbps-repo/defs.h b/bin/xbps-repo/defs.h
index 82ec4c12..0e0c33a1 100644
--- a/bin/xbps-repo/defs.h
+++ b/bin/xbps-repo/defs.h
@@ -38,7 +38,6 @@ int	repo_genindex(const char *);
 /* From repository.c */
 int	show_pkg_info_from_repolist(const char *, const char *);
 int	show_pkg_deps_from_repolist(const char *);
-int	repository_sync(void);
 
 /* From find-files.c */
 int	repo_find_files_in_packages(const char *);
diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c
index 2cbe7fa8..efc849a1 100644
--- a/bin/xbps-repo/main.c
+++ b/bin/xbps-repo/main.c
@@ -266,7 +266,7 @@ main(int argc, char **argv)
 		if (argc != 1)
 			usage(xhp);
 
-		rv = repository_sync();
+		rv = xbps_repository_pool_sync();
 		if (rv == ENOTSUP) {
 			xbps_error_printf("xbps-repo: no repositories "
 			    "currently registered!\n");
diff --git a/bin/xbps-repo/repository.c b/bin/xbps-repo/repository.c
index 4fbfe14d..d50a68f1 100644
--- a/bin/xbps-repo/repository.c
+++ b/bin/xbps-repo/repository.c
@@ -82,41 +82,3 @@ show_pkg_deps_from_repolist(const char *pkgname)
 	prop_object_release(pkgd);
 	return 0;
 }
-
-static int
-repo_sync_pkg_index_cb(struct repository_pool_index *rpi, void *arg, bool *done)
-{
-	prop_dictionary_t d;
-	const char *idxver;
-	uint64_t totalpkgs;
-	char *plist;
-	int rv = 0;
-
-	(void)arg;
-	(void)done;
-
-	if ((rv = xbps_repository_sync_pkg_index(rpi->rpi_uri)) == 0) {
-		printf("Package index file is up to date.\n");
-		return 0;
-	} else if (rv == -1)
-		return rv;
-
-	if ((plist = xbps_pkg_index_plist(rpi->rpi_uri)) == NULL)
-		return EINVAL;
-
-	d = prop_dictionary_internalize_from_zfile(plist);
-	prop_dictionary_get_cstring_nocopy(d, "pkgindex-version", &idxver);
-	prop_dictionary_get_uint64(d, "total-pkgs", &totalpkgs);
-	printf("Updated package index at %s (v%s) with %ju packages.\n",
-	    rpi->rpi_uri, idxver, totalpkgs);
-	prop_object_release(d);
-	free(plist);
-
-	return 0;
-}
-
-int
-repository_sync(void)
-{
-	return xbps_repository_pool_foreach(repo_sync_pkg_index_cb, NULL);
-}
diff --git a/include/xbps_api.h b/include/xbps_api.h
index 874370f8..33053a34 100644
--- a/include/xbps_api.h
+++ b/include/xbps_api.h
@@ -55,7 +55,7 @@
  */
 #define XBPS_PKGINDEX_VERSION	"1.3"
 
-#define XBPS_API_VERSION	"20111109"
+#define XBPS_API_VERSION	"20111110"
 #define XBPS_VERSION		"0.11.0"
 
 /**
@@ -183,8 +183,8 @@ void		xbps_warn_printf(const char *, ...);
  *
  * <b>XBPS_TRANS_STATE_REGISTER</b>: a package is being registered.
  *
- * <b>XBPS_TRANS_STATE_REPOSYNC</b>. a remote repository's
- * pkg index is being synced.
+ * <b>XBPS_TRANS_STATE_REPOSYNC</b>: a remote repository's
+ * pkg index is being synchronized.
  */
 typedef enum trans_state {
 	XBPS_TRANS_STATE_UNKNOWN = 0,
@@ -1249,6 +1249,15 @@ struct repository_pool_index {
 	char *rpi_uri;
 };
 
+/**
+ * Synchronizes the package index file for all remote repositories
+ * as specified in the configuration file, repositories.plist.
+ *
+ * @return 0 on success, ENOTSUP if no repositories were found in
+ * the configuration file.
+ */
+int xbps_repository_pool_sync(void);
+
 /**
  * Iterates over the repository pool and executes the \a fn function
  * callback passing in the void * \a arg argument to it. The bool pointer
diff --git a/lib/repository_pool.c b/lib/repository_pool.c
index eb62e364..b4086be2 100644
--- a/lib/repository_pool.c
+++ b/lib/repository_pool.c
@@ -48,20 +48,6 @@ static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue =
 
 static bool repolist_initialized;
 
-static int
-sync_remote_repo(const char *plist, const char *repourl)
-{
-	/* if file is there, continue */
-	if (access(plist, R_OK) == 0)
-		return 0;
-
-	/* file not found, fetch it */
-	if (xbps_repository_sync_pkg_index(repourl) == -1)
-		return -1;
-
-	return 0;
-}
-
 /*
  * Returns true if repository URI contains "noarch" or matching architecture
  * in last component, false otherwise.
@@ -141,20 +127,6 @@ xbps_repository_pool_init(void)
 			nmissing++;
 			continue;
 		}
-		plist = xbps_pkg_index_plist(repouri);
-		if (plist == NULL) {
-			rv = errno;
-			goto out;
-		}
-		/*
-		 * If it's a remote repository and index file is not available,
-		 * fetch it for the first time.
-		 */
-		if (sync_remote_repo(plist, repouri) == -1) {
-			nmissing++;
-			free(plist);
-			continue;
-		}
 		/*
 		 * Internalize repository's index dictionary and add it
 		 * into the queue.
@@ -162,14 +134,12 @@ xbps_repository_pool_init(void)
 		rpool = malloc(sizeof(struct repository_pool));
 		if (rpool == NULL) {
 			rv = errno;
-			free(plist);
 			goto out;
 		}
 
 		rpool->rpi = malloc(sizeof(struct repository_pool_index));
 		if (rpool->rpi == NULL) {
 			rv = errno;
-			free(plist);
 			free(rpool);
 			goto out;
 		}
@@ -179,7 +149,11 @@ xbps_repository_pool_init(void)
 			rv = errno;
 			free(rpool->rpi);
 			free(rpool);
-			free(plist);
+			goto out;
+		}
+		plist = xbps_pkg_index_plist(repouri);
+		if (plist == NULL) {
+			rv = errno;
 			goto out;
 		}
 		rpool->rpi->rpi_repod =
@@ -191,8 +165,8 @@ xbps_repository_pool_init(void)
 			free(plist);
 			if (errno == ENOENT) {
 				errno = 0;
-				xbps_dbg_printf("[rpool] missing index file "
-				    "for '%s' repository.\n", repouri);
+				xbps_dbg_printf("[rpool] `%s' missing "
+				    "index file, ignoring.\n", repouri);
 				nmissing++;
 				continue;
 			}
@@ -248,6 +222,44 @@ xbps_repository_pool_release(void)
 	xbps_dbg_printf("[rpool] released ok.\n");
 }
 
+int
+xbps_repository_pool_sync(void)
+{
+	const struct xbps_handle *xhp;
+	const char *repouri;
+	size_t i;
+	int rv;
+
+	xhp = xbps_handle_get();
+	if (xhp->repos_array == NULL)
+		return ENOTSUP;
+
+	if (prop_array_count(xhp->repos_array) == 0)
+		return ENOTSUP;
+
+	for (i = 0; i < prop_array_count(xhp->repos_array); i++) {
+		prop_array_get_cstring_nocopy(xhp->repos_array, i, &repouri);
+		/*
+		 * Check if repository doesn't match our architecture.
+		 */
+		if (!check_repo_arch(repouri)) {
+			xbps_dbg_printf("[rpool] `%s' arch not matched, "
+			    "ignoring.\n", repouri);
+			continue;
+		}
+		/*
+		 * Fetch repository index file.
+		 */
+		rv = xbps_repository_sync_pkg_index(repouri);
+		if (rv == -1) {
+			xbps_dbg_printf("[rpool] `%s' failed to fetch: %s\n",
+			    repouri, xbps_fetch_error_string());
+			continue;
+		}
+	}
+	return 0;
+}
+
 int
 xbps_repository_pool_foreach(
 		int (*fn)(struct repository_pool_index *, void *, bool *),
diff --git a/lib/repository_sync_index.c b/lib/repository_sync_index.c
index cab4fc84..5458b1ba 100644
--- a/lib/repository_sync_index.c
+++ b/lib/repository_sync_index.c
@@ -165,6 +165,7 @@ xbps_repository_sync_pkg_index(const char *uri)
 	} else
 		fetch_outputdir = metadir;
 
+	/* reposync start cb */
 	if (xhp->xbps_transaction_cb) {
 		xhp->xtcd->state = XBPS_TRANS_STATE_REPOSYNC;
 		xhp->xtcd->repourl = uri;
@@ -174,6 +175,7 @@ xbps_repository_sync_pkg_index(const char *uri)
 	 * Download index.plist file from repository.
 	 */
 	if (xbps_fetch_file(rpidx, fetch_outputdir, true, NULL) == -1) {
+		/* reposync error cb */
 		if (xhp->xbps_transaction_err_cb) {
 			xhp->xtcd->state = XBPS_TRANS_STATE_REPOSYNC;
 			xhp->xtcd->repourl = uri;
@@ -192,7 +194,7 @@ xbps_repository_sync_pkg_index(const char *uri)
 	 */
 	tmpd = prop_dictionary_internalize_from_zfile(tmp_metafile);
 	if (tmpd == NULL) {
-		xbps_error_printf("[rsyncidx] downloaded index.plist "
+		xbps_dbg_printf("[rsyncidx] downloaded index.plist "
 		    "file cannot be read! removing...\n");
 		(void)unlink(tmp_metafile);
 		rv = -1;