From 5fc3ecf7f8807c47aeab798f1f496a3fc02b8f69 Mon Sep 17 00:00:00 2001
From: Dave Reisner <dreisner@archlinux.org>
Date: Mon, 15 Aug 2011 13:43:34 -0400
Subject: lib/sync: ignore download errors for as long as possible

Previously, the behavior was such that if a sync operation required
packages from multiple repos, a download error in the first repo would
cause a hard repo, ignoring the remainder of the repositories. Change
this behavior so that we do a better job of fetching as many packages as
possible before aborting the transaction.

There's a little bit of refactoring mixed in here to get rid of some
useless variables. Since we now depend heavily on the value of
handle->pm_errno being accurate the determine the function's return
value, we clear it when the transaction state is set.

Fixes FS#25532.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
---
 lib/libalpm/sync.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index 3d581661..0c19efed 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -738,10 +738,11 @@ static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
 	const char *cachedir;
 	alpm_list_t *i, *j;
 	alpm_list_t *files = NULL;
-	int errors = 0;
+	enum _alpm_errno_t errsv = 0;
 
 	cachedir = _alpm_filecache_setup(handle);
 	handle->trans->state = STATE_DOWNLOADING;
+	handle->pm_errno = 0;
 
 	/* Total progress - figure out the total download size if required to
 	 * pass to the callback. This function is called once, and it is up to the
@@ -820,21 +821,15 @@ static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
 					}
 				}
 				if(ret == -1) {
-					errors++;
+					_alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
+							current->treename);
+					errsv = ALPM_ERR_RETRIEVE;
 				}
 			}
 
 			alpm_list_free_inner(files, (alpm_list_fn_free)_alpm_dload_payload_free);
 			alpm_list_free(files);
 			files = NULL;
-			if(errors) {
-				_alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
-						current->treename);
-				if(handle->pm_errno == 0) {
-					handle->pm_errno = ALPM_ERR_RETRIEVE;
-				}
-				return -1;
-			}
 		}
 	}
 
@@ -848,7 +843,14 @@ static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
 	if(handle->totaldlcb) {
 		handle->totaldlcb(0);
 	}
-	return 0;
+
+	/* set errno accordingly. an error occuring in the downloader itself will
+	 * take precedence over a general retrieval error */
+	if(handle->pm_errno == 0) {
+		handle->pm_errno = errsv;
+	}
+
+	return handle->pm_errno > 0 ? -1 : 0;
 }
 
 int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
-- 
cgit v1.2.3-70-g09d2