This patch is primarily a fix for FS#9228. The -Sy operation was moved to its own transaction, which allows us to do the following steps : 1) refresh the database if asked 2) check if a new pacman version if available if yes, initialize a "-S pacman" transaction. If no, initialize the original -S or -Su transaction. Note that the newversion check was extended to the "-S target" operation, which is helpful in case of syncdb syntax change (see versioned provisions for example) Original-work-by: Nagy Gabor <ngaba@bibl.u-szeged.hu> Signed-off-by: Chantry Xavier <shiningxc@gmail.com> --- src/pacman/sync.c | 129 +++++++++++++++++++++++++++-------------------------- 1 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 27218d6..2dd03f3 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -202,6 +202,17 @@ static int sync_synctree(int level, alpm_list_t *syncs) alpm_list_t *i; int success = 0, ret; + if(alpm_trans_init(PM_TRANS_TYPE_SYNC, 0, cb_trans_evt, + cb_trans_conv, cb_trans_progress) == -1) { + fprintf(stderr, _("error: failed to init transaction (%s)\n"), + alpm_strerrorlast()); + if(pm_errno == PM_ERR_HANDLE_LOCK) { + printf(_(" if you're sure a package manager is not already\n" + " running, you can remove %s.\n"), alpm_option_get_lockfile()); + } + return(0); + } + for(i = syncs; i; i = alpm_list_next(i)) { pmdb_t *db = alpm_list_getdata(i); @@ -229,10 +240,18 @@ static int sync_synctree(int level, alpm_list_t *syncs) } } + if(alpm_trans_release() == -1) { + fprintf(stderr, _("error: failed to release transaction (%s)\n"), + alpm_strerrorlast()); + return(0); + } /* We should always succeed if at least one DB was upgraded - we may possibly * fail later with unresolved deps, but that should be rare, and would be * expected */ + if(!success) { + fprintf(stderr, _("error: failed to synchronize any databases\n")); + } return(success > 0); } @@ -469,7 +488,22 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) return(0); } -static int sync_trans(alpm_list_t *targets, int sync_only) +static int pacman_isoutofdate(void) +{ + pmpkg_t *pacman = alpm_db_get_pkg(alpm_option_get_localdb(), "pacman"); + if(pacman == NULL) { + printf(_("Warning: no installed pacman package was found\n")); + return(0); + } + + if(alpm_sync_newversion(pacman, alpm_option_get_syncdbs())) { + return(1); + } else { + return(0); + } +} + +static int sync_trans(alpm_list_t *targets) { int retval = 0; alpm_list_t *data = NULL; @@ -487,23 +521,8 @@ static int sync_trans(alpm_list_t *targets, int sync_only) return(1); } - if(config->op_s_sync) { - /* grab a fresh package list */ - printf(_(":: Synchronizing package databases...\n")); - alpm_logaction("synchronizing package lists\n"); - if(!sync_synctree(config->op_s_sync, sync_dbs)) { - fprintf(stderr, _("error: failed to synchronize any databases\n")); - retval = 1; - goto cleanup; - } - if(sync_only) { - goto cleanup; - } - } - if(config->op_s_upgrade) { - alpm_list_t *pkgs, *i; - + /* sysupgrade */ printf(_(":: Starting full system upgrade...\n")); alpm_logaction("starting full system upgrade\n"); if(alpm_trans_sysupgrade() == -1) { @@ -511,46 +530,6 @@ static int sync_trans(alpm_list_t *targets, int sync_only) retval = 1; goto cleanup; } - - if(!(alpm_trans_get_flags() & (PM_TRANS_FLAG_DOWNLOADONLY | PM_TRANS_FLAG_PRINTURIS))) { - /* check if pacman itself is one of the packages to upgrade. - * this can prevent some of the "syntax error" problems users can have - * when sysupgrade'ing with an older version of pacman. - */ - pkgs = alpm_trans_get_pkgs(); - for(i = pkgs; i; i = alpm_list_next(i)) { - pmsyncpkg_t *sync = alpm_list_getdata(i); - pmpkg_t *spkg = alpm_sync_get_pkg(sync); - /* TODO pacman name should probably not be hardcoded. In addition, we - * have problems on an -Syu if pacman has to pull in deps, so recommend - * an '-S pacman' operation */ - if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) { - printf("\n"); - printf(_(":: pacman has detected a newer version of itself.\n")); - if(yesno(_(":: Do you want to cancel the current operation\n" - ":: and install the new pacman version now? [Y/n] "))) { - if(alpm_trans_release() == -1) { - fprintf(stderr, _("error: failed to release transaction (%s)\n"), - alpm_strerrorlast()); - retval = 1; - goto cleanup; - } - if(alpm_trans_init(PM_TRANS_TYPE_SYNC, config->flags, - cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { - fprintf(stderr, _("error: failed to init transaction (%s)\n"), - alpm_strerrorlast()); - return(1); - } - if(alpm_trans_addtarget("pacman") == -1) { - fprintf(stderr, _("error: pacman: %s\n"), alpm_strerrorlast()); - retval = 1; - goto cleanup; - } - break; - } - } - } - } } else { alpm_list_t *i; @@ -756,7 +735,6 @@ cleanup: int pacman_sync(alpm_list_t *targets) { alpm_list_t *sync_dbs = NULL; - int sync_only = 0; /* clean the cache */ if(config->op_s_clean) { @@ -772,18 +750,43 @@ int pacman_sync(alpm_list_t *targets) return(1); } - if(config->op_s_search || config->group - || config->op_s_info || config->op_q_list) { - sync_only = 1; - } else if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade)) { + if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade)) { /* don't proceed here unless we have an operation that doesn't require * a target list */ pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return(1); } + if(config->op_s_sync) { + /* grab a fresh package list */ + printf(_(":: Synchronizing package databases...\n")); + alpm_logaction("synchronizing package lists\n"); + if(!sync_synctree(config->op_s_sync, sync_dbs)) { + return(1); + } + config->op_s_sync = 0; + } + if(needs_transaction()) { - if(sync_trans(targets, sync_only) == 1) { + alpm_list_t *targs = alpm_list_strdup(targets); + if(!(config->flags & (PM_TRANS_FLAG_DOWNLOADONLY | PM_TRANS_FLAG_PRINTURIS))) { + /* check for new pacman version */ + if(pacman_isoutofdate()) { + printf("\n"); + printf(_(":: pacman has detected a newer version of itself.\n")); + if(yesno(_(":: Do you want to cancel the current operation\n" + ":: and install the new pacman version now? [Y/n] "))) { + FREELIST(targs); + targs = alpm_list_add(targs, strdup("pacman")); + config->flags = 0; + config->op_s_upgrade = 0; + } + } + } + + int ret = sync_trans(targs); + FREELIST(targs); + if(ret == 1) { return(1); } } -- 1.5.4