diff options
Diffstat (limited to 'src/pacman/add.c')
-rw-r--r-- | src/pacman/add.c | 205 |
1 files changed, 107 insertions, 98 deletions
diff --git a/src/pacman/add.c b/src/pacman/add.c index 2adf8681..e04707f2 100644 --- a/src/pacman/add.c +++ b/src/pacman/add.c @@ -1,8 +1,8 @@ /* * add.c - * - * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> - * + * + * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ @@ -24,33 +24,65 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <libintl.h> #include <alpm.h> #include <alpm_list.h> /* pacman */ -#include "add.h" -#include "log.h" -#include "downloadprog.h" -#include "trans.h" +#include "pacman.h" +#include "callback.h" #include "conf.h" #include "util.h" -extern config_t *config; +/* Free the current transaction and print an error if unsuccessful */ +static int add_cleanup(void) +{ + int ret = alpm_trans_release(); + if(ret != 0) { + pm_printf(PM_LOG_ERROR, _("failed to release transaction (%s)\n"), + alpm_strerrorlast()); + ret = 1; + } + return(ret); +} + +/** + * @brief Upgrade a specified list of packages. + * + * @param targets a list of packages (as strings) to upgrade + * + * @return 0 on success, 1 on failure + */ +int pacman_upgrade(alpm_list_t *targets) +{ + /* this is basically just a remove-then-add process. pacman_add() will */ + /* handle it */ + config->upgrade = 1; + return(pacman_add(targets)); +} + +/** + * @brief Add a specified list of packages which cannot already be installed. + * + * @param targets a list of packages (as strings) to add + * + * @return 0 on success, 1 on failure + */ int pacman_add(alpm_list_t *targets) { - alpm_list_t *i = targets, *data = NULL; + alpm_list_t *i, *data = NULL; + pmtranstype_t transtype = PM_TRANS_TYPE_ADD; int retval = 0; if(targets == NULL) { - return(0); + pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); + return(1); } /* Check for URL targets and process them */ - while(i) { + for(i = targets; i; i = alpm_list_next(i)) { if(strstr(i->data, "://")) { char *str = alpm_fetch_pkgurl(i->data); if(str == NULL) { @@ -60,126 +92,103 @@ int pacman_add(alpm_list_t *targets) i->data = str; } } - i = i->next; } - /* Step 1: create a new transaction - */ - if(alpm_trans_init((config->upgrade == 0) ? PM_TRANS_TYPE_ADD : PM_TRANS_TYPE_UPGRADE, - config->flags, cb_trans_evt, cb_trans_conv, cb_trans_progress) == -1) { - ERR(NL, "%s\n", alpm_strerror(pm_errno)); + /* Step 1: create a new transaction */ + if(config->upgrade == 1) { + /* if upgrade flag was set, change this to an upgrade transaction */ + transtype = PM_TRANS_TYPE_UPGRADE; + } + + if(alpm_trans_init(transtype, config->flags, cb_trans_evt, + cb_trans_conv, cb_trans_progress) == -1) { + /* TODO: error messages should be in the front end, not the back */ + fprintf(stderr, _("error: %s\n"), alpm_strerrorlast()); if(pm_errno == PM_ERR_HANDLE_LOCK) { - MSG(NL, _(" if you're sure a package manager is not already running,\n" - " you can remove %s%s\n"), alpm_option_get_root(), PM_LOCK); + /* TODO this and the 2 other places should probably be on stderr */ + printf(_(" if you're sure a package manager is not already\n" + " running, you can remove %s.\n"), alpm_option_get_lockfile()); } return(1); } - /* and add targets to it */ - MSG(NL, _("loading package data... ")); - for(i = targets; i; i = i->next) { - if(alpm_trans_addtarget(i->data) == -1) { - MSG(NL, "\n"); - ERR(NL, _("failed to add target '%s' (%s)"), (char *)i->data, alpm_strerror(pm_errno)); - retval = 1; - goto cleanup; + /* add targets to the created transaction */ + printf(_("loading package data... ")); + for(i = targets; i; i = alpm_list_next(i)) { + char *targ = alpm_list_getdata(i); + if(alpm_trans_addtarget(targ) == -1) { + fprintf(stderr, _("error: failed to add target '%s' (%s)"), targ, + alpm_strerrorlast()); + add_cleanup(); + return(1); } } - MSG(CL, _("done.\n")); + printf(_("done.\n")); - /* Step 2: "compute" the transaction based on targets and flags - */ + /* Step 2: "compute" the transaction based on targets and flags */ + /* TODO: No, compute nothing. This is stupid. */ if(alpm_trans_prepare(&data) == -1) { - long long *pkgsize, *freespace; - - ERR(NL, _("failed to prepare transaction (%s)\n"), alpm_strerror(pm_errno)); + fprintf(stderr, _("error: failed to prepare transaction (%s)\n"), + alpm_strerrorlast()); switch(pm_errno) { case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); - + pmdepend_t *dep = alpm_miss_get_dep(miss); + char *depstring = alpm_dep_get_string(dep); + /* TODO indicate if the error was a virtual package or not: * :: %s: requires %s, provided by %s */ - MSG(NL, _(":: %s: requires %s"), alpm_dep_get_target(miss), - alpm_dep_get_name(miss)); - switch(alpm_dep_get_mod(miss)) { - case PM_DEP_MOD_ANY: - break; - case PM_DEP_MOD_EQ: - MSG(CL, "=%s", alpm_dep_get_version(miss)); - break; - case PM_DEP_MOD_GE: - MSG(CL, ">=%s", alpm_dep_get_version(miss)); - break; - case PM_DEP_MOD_LE: - MSG(CL, "<=%s", alpm_dep_get_version(miss)); - break; - } - MSG(CL, "\n"); + printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss), + depstring); + free(depstring); } - break; + break; case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { - pmdepmissing_t *miss = alpm_list_getdata(i); - MSG(NL, _(":: %s: conflicts with %s"), - alpm_dep_get_target(miss), alpm_dep_get_name(miss)); + pmconflict_t *conflict = alpm_list_getdata(i); + printf(_(":: %s: conflicts with %s"), + alpm_conflict_get_package1(conflict), alpm_conflict_get_package2(conflict)); } - break; + break; case PM_ERR_FILE_CONFLICTS: for(i = data; i; i = alpm_list_next(i)) { - pmconflict_t *conflict = alpm_list_getdata(i); - switch(alpm_conflict_get_type(conflict)) { - case PM_CONFLICT_TYPE_TARGET: - MSG(NL, _("%s exists in both '%s' and '%s'\n"), - alpm_conflict_get_file(conflict), - alpm_conflict_get_target(conflict), - alpm_conflict_get_ctarget(conflict)); + pmfileconflict_t *conflict = alpm_list_getdata(i); + switch(alpm_fileconflict_get_type(conflict)) { + case PM_FILECONFLICT_TARGET: + printf(_("%s exists in both '%s' and '%s'\n"), + alpm_fileconflict_get_file(conflict), + alpm_fileconflict_get_target(conflict), + alpm_fileconflict_get_ctarget(conflict)); break; - case PM_CONFLICT_TYPE_FILE: - MSG(NL, _("%s: %s exists in filesystem\n"), - alpm_conflict_get_target(conflict), - alpm_conflict_get_file(conflict)); + case PM_FILECONFLICT_FILESYSTEM: + printf(_("%s: %s exists in filesystem\n"), + alpm_fileconflict_get_target(conflict), + alpm_fileconflict_get_file(conflict)); break; } } - MSG(NL, _("\nerrors occurred, no packages were upgraded.\n")); - break; - /* TODO This is gross... we should not return these values in the same list we - * would get conflicts and such with... it's just silly - */ - case PM_ERR_DISK_FULL: - i = data; - pkgsize = alpm_list_getdata(i); - i = alpm_list_next(i); - freespace = alpm_list_getdata(i); - MSG(NL, _(":: %.1f MB required, have %.1f MB"), - (double)(*pkgsize / (1024.0*1024.0)), (double)(*freespace / (1024.0*1024.0))); - break; + printf(_("\nerrors occurred, no packages were upgraded.\n")); + break; default: - break; + break; } - retval=1; - goto cleanup; + add_cleanup(); + alpm_list_free_inner(data, free); + alpm_list_free(data); + return(1); } + alpm_list_free(data); - /* Step 3: actually perform the installation - */ + /* Step 3: perform the installation */ if(alpm_trans_commit(NULL) == -1) { - ERR(NL, _("failed to commit transaction (%s)\n"), alpm_strerror(pm_errno)); - retval=1; - goto cleanup; - } - -cleanup: - if(data) { - alpm_list_free(data); - } - if(alpm_trans_release() == -1) { - ERR(NL, _("failed to release transaction (%s)\n"), alpm_strerror(pm_errno)); - retval=1; + fprintf(stderr, _("error: failed to commit transaction (%s)\n"), alpm_strerrorlast()); + add_cleanup(); + return(1); } + retval = add_cleanup(); return(retval); } |