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/>.
32 #include <alpm_list.h>
40 /* if keep_used != 0, then the db files which match an used syncdb
42 static int sync_cleandb(const char *dbpath
, int keep_used
) {
46 dir
= opendir(dbpath
);
48 pm_fprintf(stderr
, PM_LOG_ERROR
, _("could not access database directory\n"));
53 /* step through the directory one file at a time */
54 while((ent
= readdir(dir
)) != NULL
) {
57 alpm_list_t
*syncdbs
= NULL
, *i
;
59 const char *dname
= ent
->d_name
;
62 if(strcmp(dname
, ".") == 0 || strcmp(dname
, "..") == 0) {
65 /* skip the local and sync directories */
66 if(strcmp(dname
, "sync") == 0 || strcmp(dname
, "local") == 0) {
69 /* skip the db.lck file */
70 if(strcmp(dname
, "db.lck") == 0) {
74 /* build the full path */
75 snprintf(path
, PATH_MAX
, "%s%s", dbpath
, dname
);
77 /* remove all non-skipped directories and non-database files */
80 if(S_ISDIR(buf
.st_mode
) || strcmp(path
+(len
-3),".db") != 0) {
82 pm_fprintf(stderr
, PM_LOG_ERROR
,
83 _("could not remove %s\n"), path
);
92 char *dbname
= strndup(dname
, len
-3);
93 syncdbs
= alpm_option_get_syncdbs();
94 for(i
= syncdbs
; i
&& !found
; i
= alpm_list_next(i
)) {
95 pmdb_t
*db
= alpm_list_getdata(i
);
96 found
= !strcmp(dbname
, alpm_db_get_name(db
));
100 /* We have a database that doesn't match any syncdb.
101 * Ask the user if he wants to remove it. */
103 if(!yesno(_("Do you want to remove %s?"), path
)) {
108 pm_fprintf(stderr
, PM_LOG_ERROR
,
109 _("could not remove %s\n"), path
);
119 static int sync_cleandb_all(void) {
121 char newdbpath
[PATH_MAX
];
124 dbpath
= alpm_option_get_dbpath();
125 printf(_("Database directory: %s\n"), dbpath
);
126 if(!yesno(_("Do you want to remove unused repositories?"))) {
129 /* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
130 * so we will clean everything in dbpath/ (except dbpath/local/ and dbpath/sync/
131 * and db.lck) and only the unused sync dbs in dbpath/sync/ */
132 ret
+= sync_cleandb(dbpath
, 0);
134 sprintf(newdbpath
, "%s%s", dbpath
, "sync/");
135 ret
+= sync_cleandb(newdbpath
, 1);
137 printf(_("Database directory cleaned up\n"));
141 static int sync_cleancache(int level
)
144 alpm_list_t
*sync_dbs
= alpm_option_get_syncdbs();
145 pmdb_t
*db_local
= alpm_option_get_localdb();
148 for(i
= alpm_option_get_cachedirs(); i
; i
= alpm_list_next(i
)) {
149 printf(_("Cache directory: %s\n"), (char*)alpm_list_getdata(i
));
153 switch(config
->cleanmethod
) {
154 case PM_CLEAN_KEEPINST
:
155 if(!yesno(_("Do you want to remove uninstalled packages from cache?"))) {
159 case PM_CLEAN_KEEPCUR
:
160 if(!yesno(_("Do you want to remove outdated packages from cache?"))) {
165 /* this should not happen : the config parsing doesn't set any other value */
168 printf(_("removing old packages from cache...\n"));
170 if(!noyes(_("Do you want to remove ALL files from cache?"))) {
173 printf(_("removing all files from cache...\n"));
176 for(i
= alpm_option_get_cachedirs(); i
; i
= alpm_list_next(i
)) {
177 const char *cachedir
= alpm_list_getdata(i
);
178 DIR *dir
= opendir(cachedir
);
182 pm_fprintf(stderr
, PM_LOG_ERROR
,
183 _("could not access cache directory %s\n"), cachedir
);
189 /* step through the directory one file at a time */
190 while((ent
= readdir(dir
)) != NULL
) {
193 pmpkg_t
*localpkg
= NULL
, *pkg
= NULL
;
196 if(strcmp(ent
->d_name
, ".") == 0 || strcmp(ent
->d_name
, "..") == 0) {
199 /* build the full filepath */
200 snprintf(path
, PATH_MAX
, "%s%s", cachedir
, ent
->d_name
);
202 /* short circuit for removing all packages from cache */
208 /* attempt to load the package, prompt removal on failures as we may have
209 * files here that aren't valid packages. we also don't need a full
210 * load of the package, just the metadata. */
211 if(alpm_pkg_load(path
, 0, &localpkg
) != 0 || localpkg
== NULL
) {
212 if(yesno(_("File %s does not seem to be a valid package, remove it?"), path
)) {
214 alpm_pkg_free(localpkg
);
220 switch(config
->cleanmethod
) {
221 case PM_CLEAN_KEEPINST
:
222 /* check if this package is in the local DB */
223 pkg
= alpm_db_get_pkg(db_local
, alpm_pkg_get_name(localpkg
));
224 if(pkg
!= NULL
&& alpm_pkg_vercmp(alpm_pkg_get_version(localpkg
),
225 alpm_pkg_get_version(pkg
)) == 0) {
226 /* package was found in local DB and version matches, keep it */
230 case PM_CLEAN_KEEPCUR
:
231 /* check if this package is in a sync DB */
232 for(j
= sync_dbs
; j
&& delete; j
= alpm_list_next(j
)) {
233 pmdb_t
*db
= alpm_list_getdata(j
);
234 pkg
= alpm_db_get_pkg(db
, alpm_pkg_get_name(localpkg
));
235 if(pkg
!= NULL
&& alpm_pkg_vercmp(alpm_pkg_get_version(localpkg
),
236 alpm_pkg_get_version(pkg
)) == 0) {
237 /* package was found in a sync DB and version matches, keep it */
243 /* this should not happen : the config parsing doesn't set any other value */
247 /* free the local file package */
248 alpm_pkg_free(localpkg
);
260 static int sync_synctree(int level
, alpm_list_t
*syncs
)
263 int success
= 0, ret
;
265 if(trans_init(0) == -1) {
269 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
270 pmdb_t
*db
= alpm_list_getdata(i
);
272 ret
= alpm_db_update((level
< 2 ? 0 : 1), db
);
274 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to update %s (%s)\n"),
275 alpm_db_get_name(db
), alpm_strerrorlast());
276 } else if(ret
== 1) {
277 printf(_(" %s is up to date\n"), alpm_db_get_name(db
));
284 if(trans_release() == -1) {
287 /* We should always succeed if at least one DB was upgraded - we may possibly
288 * fail later with unresolved deps, but that should be rare, and would be
292 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to synchronize any databases\n"));
297 static void print_installed(pmdb_t
*db_local
, pmpkg_t
*pkg
)
299 const char *pkgname
= alpm_pkg_get_name(pkg
);
300 const char *pkgver
= alpm_pkg_get_version(pkg
);
301 pmpkg_t
*lpkg
= alpm_db_get_pkg(db_local
, pkgname
);
303 const char *lpkgver
= alpm_pkg_get_version(lpkg
);
304 if(strcmp(lpkgver
,pkgver
) == 0) {
305 printf(" [%s]", _("installed"));
307 printf(" [%s: %s]", _("installed"), lpkgver
);
312 /* search the sync dbs for a matching package */
313 static int sync_search(alpm_list_t
*syncs
, alpm_list_t
*targets
)
315 alpm_list_t
*i
, *j
, *ret
;
318 pmdb_t
*db_local
= alpm_option_get_localdb();
320 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
321 pmdb_t
*db
= alpm_list_getdata(i
);
322 /* if we have a targets list, search for packages matching it */
324 ret
= alpm_db_search(db
, targets
);
327 ret
= alpm_db_get_pkgcache(db
);
335 for(j
= ret
; j
; j
= alpm_list_next(j
)) {
337 pmpkg_t
*pkg
= alpm_list_getdata(j
);
339 if (!config
->quiet
) {
340 printf("%s/%s %s", alpm_db_get_name(db
), alpm_pkg_get_name(pkg
),
341 alpm_pkg_get_version(pkg
));
343 printf("%s", alpm_pkg_get_name(pkg
));
346 /* print the package size with the output if ShowSize option set */
347 if(!config
->quiet
&& config
->showsize
) {
348 /* Convert byte size to MB */
349 double mbsize
= (double)alpm_pkg_get_size(pkg
) / (1024.0 * 1024.0);
351 printf(" [%.2f MB]", mbsize
);
354 if (!config
->quiet
) {
355 if((grp
= alpm_pkg_get_groups(pkg
)) != NULL
) {
358 for(k
= grp
; k
; k
= alpm_list_next(k
)) {
359 const char *group
= alpm_list_getdata(k
);
361 if(alpm_list_next(k
)) {
362 /* only print a spacer if there are more groups */
369 print_installed(db_local
, pkg
);
371 /* we need a newline and initial indent first */
373 indentprint(alpm_pkg_get_desc(pkg
), 4);
377 /* we only want to free if the list was a search list */
386 static int sync_group(int level
, alpm_list_t
*syncs
, alpm_list_t
*targets
)
388 alpm_list_t
*i
, *j
, *k
;
391 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
392 const char *grpname
= alpm_list_getdata(i
);
393 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
394 pmdb_t
*db
= alpm_list_getdata(j
);
395 pmgrp_t
*grp
= alpm_db_readgrp(db
, grpname
);
398 /* get names of packages in group */
399 for(k
= alpm_grp_get_pkgs(grp
); k
; k
= alpm_list_next(k
)) {
401 printf("%s %s\n", grpname
,
402 alpm_pkg_get_name(alpm_list_getdata(k
)));
404 printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(k
)));
411 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
412 pmdb_t
*db
= alpm_list_getdata(i
);
414 for(j
= alpm_db_get_grpcache(db
); j
; j
= alpm_list_next(j
)) {
415 pmgrp_t
*grp
= alpm_list_getdata(j
);
416 const char *grpname
= alpm_grp_get_name(grp
);
419 for(k
= alpm_grp_get_pkgs(grp
); k
; k
= alpm_list_next(k
)) {
420 printf("%s %s\n", grpname
,
421 alpm_pkg_get_name(alpm_list_getdata(k
)));
424 /* print grp names only, no package names */
425 printf("%s\n", grpname
);
434 static int sync_info(alpm_list_t
*syncs
, alpm_list_t
*targets
)
436 alpm_list_t
*i
, *j
, *k
;
440 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
444 char target
[512]; /* TODO is this enough space? */
445 char *repo
= NULL
, *pkgstr
= NULL
;
447 strncpy(target
, i
->data
, 512);
448 pkgstr
= strchr(target
, '/');
454 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
455 db
= alpm_list_getdata(j
);
456 if(strcmp(repo
, alpm_db_get_name(db
)) == 0) {
463 pm_fprintf(stderr
, PM_LOG_ERROR
,
464 _("repository '%s' does not exist\n"), repo
);
468 for(k
= alpm_db_get_pkgcache(db
); k
; k
= alpm_list_next(k
)) {
469 pmpkg_t
*pkg
= alpm_list_getdata(k
);
471 if(strcmp(alpm_pkg_get_name(pkg
), pkgstr
) == 0) {
472 dump_pkg_sync(pkg
, alpm_db_get_name(db
), config
->op_s_info
);
479 pm_fprintf(stderr
, PM_LOG_ERROR
,
480 _("package '%s' was not found in repository '%s'\n"), pkgstr
, repo
);
486 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
487 pmdb_t
*db
= alpm_list_getdata(j
);
489 for(k
= alpm_db_get_pkgcache(db
); k
; k
= alpm_list_next(k
)) {
490 pmpkg_t
*pkg
= alpm_list_getdata(k
);
492 if(strcmp(alpm_pkg_get_name(pkg
), pkgstr
) == 0) {
493 dump_pkg_sync(pkg
, alpm_db_get_name(db
), config
->op_s_info
);
500 pm_fprintf(stderr
, PM_LOG_ERROR
,
501 _("package '%s' was not found\n"), pkgstr
);
507 for(i
= syncs
; i
; i
= alpm_list_next(i
)) {
508 pmdb_t
*db
= alpm_list_getdata(i
);
510 for(j
= alpm_db_get_pkgcache(db
); j
; j
= alpm_list_next(j
)) {
511 dump_pkg_sync(alpm_list_getdata(j
), alpm_db_get_name(db
), config
->op_s_info
);
519 static int sync_list(alpm_list_t
*syncs
, alpm_list_t
*targets
)
521 alpm_list_t
*i
, *j
, *ls
= NULL
;
522 pmdb_t
*db_local
= alpm_option_get_localdb();
525 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
526 const char *repo
= alpm_list_getdata(i
);
529 for(j
= syncs
; j
; j
= alpm_list_next(j
)) {
530 pmdb_t
*d
= alpm_list_getdata(j
);
532 if(strcmp(repo
, alpm_db_get_name(d
)) == 0) {
539 pm_fprintf(stderr
, PM_LOG_ERROR
,
540 _("repository \"%s\" was not found.\n"),repo
);
545 ls
= alpm_list_add(ls
, db
);
551 for(i
= ls
; i
; i
= alpm_list_next(i
)) {
552 pmdb_t
*db
= alpm_list_getdata(i
);
554 for(j
= alpm_db_get_pkgcache(db
); j
; j
= alpm_list_next(j
)) {
555 pmpkg_t
*pkg
= alpm_list_getdata(j
);
557 if (!config
->quiet
) {
558 printf("%s %s %s", alpm_db_get_name(db
), alpm_pkg_get_name(pkg
),
559 alpm_pkg_get_version(pkg
));
560 print_installed(db_local
, pkg
);
563 printf("%s\n", alpm_pkg_get_name(pkg
));
575 static alpm_list_t
*syncfirst(void) {
576 alpm_list_t
*i
, *res
= NULL
;
578 for(i
= config
->syncfirst
; i
; i
= alpm_list_next(i
)) {
579 char *pkgname
= alpm_list_getdata(i
);
580 pmpkg_t
*pkg
= alpm_db_get_pkg(alpm_option_get_localdb(), pkgname
);
585 if(alpm_sync_newversion(pkg
, alpm_option_get_syncdbs())) {
586 res
= alpm_list_add(res
, strdup(pkgname
));
593 static pmdb_t
*get_db(const char *dbname
)
596 for(i
= alpm_option_get_syncdbs(); i
; i
= i
->next
) {
597 pmdb_t
*db
= i
->data
;
598 if(strcmp(alpm_db_get_name(db
), dbname
) == 0) {
605 static int process_pkg(pmpkg_t
*pkg
)
607 int ret
= alpm_add_pkg(pkg
);
610 if(pm_errno
== PM_ERR_TRANS_DUP_TARGET
611 || pm_errno
== PM_ERR_PKG_IGNORED
) {
612 /* just skip duplicate or ignored targets */
613 pm_printf(PM_LOG_WARNING
, _("skipping target: %s\n"), alpm_pkg_get_name(pkg
));
616 pm_fprintf(stderr
, PM_LOG_ERROR
, "'%s': %s\n", alpm_pkg_get_name(pkg
),
617 alpm_strerrorlast());
624 static int process_group(alpm_list_t
*dbs
, char *group
)
628 alpm_list_t
*pkgs
= alpm_find_grp_pkgs(dbs
, group
);
629 int count
= alpm_list_count(pkgs
);
632 pm_fprintf(stderr
, PM_LOG_ERROR
, _("target not found: %s\n"), group
);
636 printf(_(":: There are %d members in group %s:\n"), count
,
638 select_display(pkgs
);
639 char *array
= malloc(count
);
640 multiselect_question(array
, count
);
642 for(i
= pkgs
; i
; i
= alpm_list_next(i
)) {
645 pmpkg_t
*pkg
= alpm_list_getdata(i
);
647 if(process_pkg(pkg
) == 1) {
653 alpm_list_free(pkgs
);
658 static int process_targname(alpm_list_t
*dblist
, char *targname
)
660 pmpkg_t
*pkg
= alpm_find_dbs_satisfier(dblist
, targname
);
663 return(process_pkg(pkg
));
665 /* fallback on group */
666 return(process_group(dblist
, targname
));
669 static int process_target(char *target
)
671 /* process targets */
672 char *targstring
= strdup(target
);
673 char *targname
= strchr(targstring
, '/');
676 alpm_list_t
*dblist
= NULL
;
686 pm_fprintf(stderr
, PM_LOG_ERROR
, _("database not found: %s\n"),
691 dblist
= alpm_list_add(dblist
, db
);
692 ret
= process_targname(dblist
, targname
);
693 alpm_list_free(dblist
);
695 targname
= targstring
;
696 dblist
= alpm_option_get_syncdbs();
697 ret
= process_targname(dblist
, targname
);
704 static int sync_trans(alpm_list_t
*targets
)
707 alpm_list_t
*data
= NULL
;
708 alpm_list_t
*packages
= NULL
;
711 /* Step 1: create a new transaction... */
712 if(trans_init(config
->flags
) == -1) {
716 /* process targets */
717 for(i
= targets
; i
; i
= alpm_list_next(i
)) {
718 char *targ
= alpm_list_getdata(i
);
719 if(process_target(targ
) == 1) {
725 if(config
->op_s_upgrade
) {
726 printf(_(":: Starting full system upgrade...\n"));
727 alpm_logaction("starting full system upgrade\n");
728 if(alpm_sync_sysupgrade(config
->op_s_upgrade
>= 2) == -1) {
729 pm_fprintf(stderr
, PM_LOG_ERROR
, "%s\n", alpm_strerrorlast());
735 /* Step 2: "compute" the transaction based on targets and flags */
736 if(alpm_trans_prepare(&data
) == -1) {
737 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to prepare transaction (%s)\n"),
738 alpm_strerrorlast());
741 case PM_ERR_PKG_INVALID_ARCH
:
742 for(i
= data
; i
; i
= alpm_list_next(i
)) {
743 char *pkg
= alpm_list_getdata(i
);
744 printf(_(":: package %s does not have a valid architecture\n"), pkg
);
747 case PM_ERR_UNSATISFIED_DEPS
:
748 for(i
= data
; i
; i
= alpm_list_next(i
)) {
749 pmdepmissing_t
*miss
= alpm_list_getdata(i
);
750 pmdepend_t
*dep
= alpm_miss_get_dep(miss
);
751 char *depstring
= alpm_dep_compute_string(dep
);
752 printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss
),
757 case PM_ERR_CONFLICTING_DEPS
:
758 for(i
= data
; i
; i
= alpm_list_next(i
)) {
759 pmconflict_t
*conflict
= alpm_list_getdata(i
);
760 const char *package1
= alpm_conflict_get_package1(conflict
);
761 const char *package2
= alpm_conflict_get_package2(conflict
);
762 const char *reason
= alpm_conflict_get_reason(conflict
);
763 /* only print reason if it contains new information */
764 if(strcmp(package1
, reason
) == 0 || strcmp(package2
, reason
) == 0) {
765 printf(_(":: %s and %s are in conflict\n"), package1
, package2
);
767 printf(_(":: %s and %s are in conflict (%s)\n"), package1
, package2
, reason
);
778 packages
= alpm_trans_get_add();
779 if(packages
== NULL
) {
780 /* nothing to do: just exit without complaining */
781 printf(_(" there is nothing to do\n"));
785 /* Step 3: actually perform the operation */
787 print_packages(packages
);
791 display_targets(alpm_trans_get_remove(), 0);
792 display_targets(alpm_trans_get_add(), 1);
796 if(config
->op_s_downloadonly
) {
797 confirm
= yesno(_("Proceed with download?"));
799 confirm
= yesno(_("Proceed with installation?"));
805 if(alpm_trans_commit(&data
) == -1) {
806 pm_fprintf(stderr
, PM_LOG_ERROR
, _("failed to commit transaction (%s)\n"),
807 alpm_strerrorlast());
810 case PM_ERR_FILE_CONFLICTS
:
811 for(i
= data
; i
; i
= alpm_list_next(i
)) {
812 pmfileconflict_t
*conflict
= alpm_list_getdata(i
);
813 switch(alpm_fileconflict_get_type(conflict
)) {
814 case PM_FILECONFLICT_TARGET
:
815 printf(_("%s exists in both '%s' and '%s'\n"),
816 alpm_fileconflict_get_file(conflict
),
817 alpm_fileconflict_get_target(conflict
),
818 alpm_fileconflict_get_ctarget(conflict
));
820 case PM_FILECONFLICT_FILESYSTEM
:
821 printf(_("%s: %s exists in filesystem\n"),
822 alpm_fileconflict_get_target(conflict
),
823 alpm_fileconflict_get_file(conflict
));
828 case PM_ERR_PKG_INVALID
:
829 case PM_ERR_DLT_INVALID
:
830 for(i
= data
; i
; i
= alpm_list_next(i
)) {
831 char *filename
= alpm_list_getdata(i
);
832 printf(_("%s is invalid or corrupted\n"), filename
);
839 printf(_("Errors occurred, no packages were upgraded.\n"));
844 /* Step 4: release transaction resources */
849 if(trans_release() == -1) {
856 int pacman_sync(alpm_list_t
*targets
)
858 alpm_list_t
*sync_dbs
= NULL
;
860 /* clean the cache */
861 if(config
->op_s_clean
) {
864 if(trans_init(0) == -1) {
868 ret
+= sync_cleancache(config
->op_s_clean
);
870 ret
+= sync_cleandb_all();
872 if(trans_release() == -1) {
879 /* ensure we have at least one valid sync db set up */
880 sync_dbs
= alpm_option_get_syncdbs();
881 if(sync_dbs
== NULL
|| alpm_list_count(sync_dbs
) == 0) {
882 pm_printf(PM_LOG_ERROR
, _("no usable package repositories configured.\n"));
886 if(config
->op_s_sync
) {
887 /* grab a fresh package list */
888 printf(_(":: Synchronizing package databases...\n"));
889 alpm_logaction("synchronizing package lists\n");
890 if(!sync_synctree(config
->op_s_sync
, sync_dbs
)) {
895 /* search for a package */
896 if(config
->op_s_search
) {
897 return(sync_search(sync_dbs
, targets
));
900 /* look for groups */
902 return(sync_group(config
->group
, sync_dbs
, targets
));
905 /* get package info */
906 if(config
->op_s_info
) {
907 return(sync_info(sync_dbs
, targets
));
910 /* get a listing of files in sync DBs */
911 if(config
->op_q_list
) {
912 return(sync_list(sync_dbs
, targets
));
915 if(targets
== NULL
) {
916 if(config
->op_s_upgrade
) {
918 } else if(config
->op_s_sync
) {
921 /* don't proceed here unless we have an operation that doesn't require a
923 pm_printf(PM_LOG_ERROR
, _("no targets specified (use -h for help)\n"));
928 alpm_list_t
*targs
= alpm_list_strdup(targets
);
929 if(!(config
->flags
& PM_TRANS_FLAG_DOWNLOADONLY
) && !config
->print
) {
930 /* check for newer versions of packages to be upgraded first */
931 alpm_list_t
*packages
= syncfirst();
933 /* Do not ask user if all the -S targets are SyncFirst packages, see FS#15810 */
934 alpm_list_t
*tmp
= NULL
;
935 if(config
->op_s_upgrade
|| (tmp
= alpm_list_diff(targets
, packages
, (alpm_list_fn_cmp
)strcmp
))) {
937 printf(_(":: The following packages should be upgraded first :\n"));
938 list_display(" ", packages
);
939 if(yesno(_(":: Do you want to cancel the current operation\n"
940 ":: and upgrade these packages now?"))) {
944 config
->op_s_upgrade
= 0;
950 pm_printf(PM_LOG_DEBUG
, "skipping SyncFirst dialog\n");
956 int ret
= sync_trans(targs
);
962 /* vim: set ts=2 sw=2 noet: */