4 * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
5 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include <alpm_list.h>
36 * @brief Upgrade a specified list of packages.
38 * @param targets a list of packages (as strings) to upgrade
40 * @return 0 on success, 1 on failure
42 int pacman_upgrade(alpm_list_t
*targets
)
44 alpm_list_t
*i
, *data
= NULL
;
45 pgp_verify_t check_sig
= alpm_option_get_default_sigverify(config
->handle
);
49 pm_printf(PM_LOG_ERROR
, _("no targets specified (use -h for help)\n"));
53 /* Check for URL targets and process them
55 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
56 if(strstr(i
->data
, "://")) {
57 char *str
= alpm_fetch_pkgurl(config
->handle
, i
->data
);
59 pm_fprintf(stderr
, PM_LOG_ERROR
, "'%s': %s\n",
60 (char *)i
->data
, alpm_strerror(alpm_errno(config
->handle
)));
69 /* Step 1: create a new transaction */
70 if(trans_init(config
->flags
) == -1) {
74 /* add targets to the created transaction */
75 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
76 char *targ
= alpm_list_getdata(i
);
79 if(alpm_pkg_load(config
->handle
, targ
, 1, check_sig
, &pkg
) != 0) {
80 pm_fprintf(stderr
, PM_LOG_ERROR
, "'%s': %s\n",
81 targ
, alpm_strerror(alpm_errno(config
->handle
)));
85 if(alpm_add_pkg(config
->handle
, pkg
) == -1) {
86 pm_fprintf(stderr
, PM_LOG_ERROR
, "'%s': %s\n",
87 targ
, alpm_strerror(alpm_errno(config
->handle
)));
94 /* Step 2: "compute" the transaction based on targets and flags */
95 /* TODO: No, compute nothing. This is stupid. */
96 if(alpm_trans_prepare(config
->handle
, &data
) == -1) {
97 enum _alpm_errno_t err
= alpm_errno(config
->handle
);
98 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to prepare transaction (%s)\n"),
101 case PM_ERR_PKG_INVALID_ARCH
:
102 for(i
= data
; i
; i
= alpm_list_next(i
)) {
103 char *pkg
= alpm_list_getdata(i
);
104 printf(_(":: package %s does not have a valid architecture\n"), pkg
);
107 case PM_ERR_UNSATISFIED_DEPS
:
108 for(i
= data
; i
; i
= alpm_list_next(i
)) {
109 alpm_depmissing_t
*miss
= alpm_list_getdata(i
);
110 char *depstring
= alpm_dep_compute_string(miss
->depend
);
112 /* TODO indicate if the error was a virtual package or not:
113 * :: %s: requires %s, provided by %s
115 printf(_(":: %s: requires %s\n"), miss
->target
, depstring
);
119 case PM_ERR_CONFLICTING_DEPS
:
120 for(i
= data
; i
; i
= alpm_list_next(i
)) {
121 alpm_conflict_t
*conflict
= alpm_list_getdata(i
);
122 if(strcmp(conflict
->package1
, conflict
->reason
) == 0 ||
123 strcmp(conflict
->package2
, conflict
->reason
) == 0) {
124 printf(_(":: %s and %s are in conflict\n"),
125 conflict
->package1
, conflict
->package2
);
127 printf(_(":: %s and %s are in conflict (%s)\n"),
128 conflict
->package1
, conflict
->package2
, conflict
->reason
);
140 /* Step 3: perform the installation */
141 alpm_list_t
*packages
= alpm_trans_get_add(config
->handle
);
144 print_packages(packages
);
149 /* print targets and ask user confirmation */
150 if(packages
== NULL
) { /* we are done */
151 printf(_(" there is nothing to do\n"));
155 display_targets(alpm_trans_get_remove(config
->handle
), 0);
156 display_targets(alpm_trans_get_add(config
->handle
), 1);
158 int confirm
= yesno(_("Proceed with installation?"));
164 if(alpm_trans_commit(config
->handle
, &data
) == -1) {
165 enum _alpm_errno_t err
= alpm_errno(config
->handle
);
166 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to commit transaction (%s)\n"),
169 case PM_ERR_FILE_CONFLICTS
:
170 for(i
= data
; i
; i
= alpm_list_next(i
)) {
171 alpm_fileconflict_t
*conflict
= alpm_list_getdata(i
);
172 switch(conflict
->type
) {
173 case PM_FILECONFLICT_TARGET
:
174 printf(_("%s exists in both '%s' and '%s'\n"),
175 conflict
->file
, conflict
->target
, conflict
->ctarget
);
177 case PM_FILECONFLICT_FILESYSTEM
:
178 printf(_("%s: %s exists in filesystem\n"),
179 conflict
->target
, conflict
->file
);
184 case PM_ERR_PKG_INVALID
:
185 case PM_ERR_DLT_INVALID
:
186 for(i
= data
; i
; i
= alpm_list_next(i
)) {
187 char *filename
= alpm_list_getdata(i
);
188 printf(_("%s is invalid or corrupted\n"), filename
);
199 if(trans_release() == -1) {
205 /* vim: set ts=2 sw=2 noet: */