From 16d98d657748fdbf32ab24db56d3cd4a23447673 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Sun, 19 Apr 2020 02:12:01 -0700 Subject: Convert '-U pkg1 pkg2' codepath to parallel download Installing remote packages using its URL is an interesting case for ALPM API. Unlike package sync ('pacman -S pkg1 pkg2') '-U' does not deal with server mirror list. Thus _alpm_multi_download() should be able to handle file download for payloads that either have 'fileurl' field or pair of fields ('servers' and 'filepath') set. Signature for alpm_fetch_pkgurl() has changed and it accepts an output list that is populated with filepaths to fetched packages. Signed-off-by: Anatol Pomozov --- src/pacman/upgrade.c | 102 ++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c index 5f984e44..840e3a31 100644 --- a/src/pacman/upgrade.c +++ b/src/pacman/upgrade.c @@ -30,6 +30,34 @@ #include "conf.h" #include "util.h" +/* add targets to the created transaction */ +static int load_packages(alpm_list_t *targets, int siglevel) +{ + alpm_list_t *i; + int retval = 0; + + for(i = targets; i; i = alpm_list_next(i)) { + const char *targ = i->data; + alpm_pkg_t *pkg; + + if(alpm_pkg_load(config->handle, targ, 1, siglevel, &pkg) != 0) { + pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", + targ, alpm_strerror(alpm_errno(config->handle))); + retval = 1; + continue; + } + if(alpm_add_pkg(config->handle, pkg) == -1) { + pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", + targ, alpm_strerror(alpm_errno(config->handle))); + alpm_pkg_free(pkg); + retval = 1; + continue; + } + config->explicit_adds = alpm_list_add(config->explicit_adds, pkg); + } + return retval; +} + /** * @brief Upgrade a specified list of packages. * @@ -39,43 +67,30 @@ */ int pacman_upgrade(alpm_list_t *targets) { - int retval = 0, *file_is_remote; + int retval = 0; + alpm_list_t *remote_targets = NULL, *fetched_files = NULL; + alpm_list_t *local_targets = NULL; alpm_list_t *i; - unsigned int n, num_targets; if(targets == NULL) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } - num_targets = alpm_list_count(targets); - - /* Check for URL targets and process them */ - file_is_remote = malloc(num_targets * sizeof(int)); - if(file_is_remote == NULL) { - pm_printf(ALPM_LOG_ERROR, _("memory exhausted\n")); - return 1; - } - - for(i = targets, n = 0; i; i = alpm_list_next(i), n++) { + /* carve out remote targets and move it into a separate list */ + for(i = targets; i; i = alpm_list_next(i)) { if(strstr(i->data, "://")) { - char *str = alpm_fetch_pkgurl(config->handle, i->data); - if(str == NULL) { - pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", - (char *)i->data, alpm_strerror(alpm_errno(config->handle))); - retval = 1; - } else { - free(i->data); - i->data = str; - file_is_remote[n] = 1; - } + remote_targets = alpm_list_add(remote_targets, i->data); } else { - file_is_remote[n] = 0; + local_targets = alpm_list_add(local_targets, i->data); } } - if(retval) { - goto fail_free; + if(remote_targets) { + retval = alpm_fetch_pkgurl(config->handle, remote_targets, &fetched_files); + if(retval) { + goto fail_free; + } } /* Step 1: create a new transaction */ @@ -85,39 +100,16 @@ int pacman_upgrade(alpm_list_t *targets) } printf(_("loading packages...\n")); - /* add targets to the created transaction */ - for(i = targets, n = 0; i; i = alpm_list_next(i), n++) { - const char *targ = i->data; - alpm_pkg_t *pkg; - int siglevel; - - if(file_is_remote[n]) { - siglevel = alpm_option_get_remote_file_siglevel(config->handle); - } else { - siglevel = alpm_option_get_local_file_siglevel(config->handle); - } - - if(alpm_pkg_load(config->handle, targ, 1, siglevel, &pkg) != 0) { - pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", - targ, alpm_strerror(alpm_errno(config->handle))); - retval = 1; - continue; - } - if(alpm_add_pkg(config->handle, pkg) == -1) { - pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", - targ, alpm_strerror(alpm_errno(config->handle))); - alpm_pkg_free(pkg); - retval = 1; - continue; - } - config->explicit_adds = alpm_list_add(config->explicit_adds, pkg); - } + retval |= load_packages(local_targets, alpm_option_get_local_file_siglevel(config->handle)); + retval |= load_packages(fetched_files, alpm_option_get_remote_file_siglevel(config->handle)); if(retval) { goto fail_release; } - free(file_is_remote); + alpm_list_free(remote_targets); + alpm_list_free(local_targets); + FREELIST(fetched_files); /* now that targets are resolved, we can hand it all off to the sync code */ return sync_prepare_execute(); @@ -125,7 +117,9 @@ int pacman_upgrade(alpm_list_t *targets) fail_release: trans_release(); fail_free: - free(file_is_remote); + alpm_list_free(remote_targets); + alpm_list_free(local_targets); + FREELIST(fetched_files); return retval; } -- cgit v1.2.3-54-g00ecf