1 diff -Nuar -uar a/src/pacman/conf.c b/src/pacman/conf.c
2 --- a/src/pacman/conf.c 2020-06-22 19:33:22.000000000 +1100
3 +++ b/src/pacman/conf.c 2020-12-24 20:01:21.885850894 +1100
5 alpm_list_free(config->repos);
7 FREELIST(oldconfig->holdpkg);
8 + FREELIST(oldconfig->syncfirst);
9 FREELIST(oldconfig->ignorepkg);
10 FREELIST(oldconfig->ignoregrp);
11 FREELIST(oldconfig->assumeinstalled);
13 setrepeatingoption(value, "IgnoreGroup", &(config->ignoregrp));
14 } else if(strcmp(key, "HoldPkg") == 0) {
15 setrepeatingoption(value, "HoldPkg", &(config->holdpkg));
16 + } else if(strcmp(key, "SyncFirst") == 0) {
17 + setrepeatingoption(value, "SyncFirst", &(config->syncfirst));
18 } else if(strcmp(key, "CacheDir") == 0) {
19 setrepeatingoption(value, "CacheDir", &(config->cachedirs));
20 } else if(strcmp(key, "HookDir") == 0) {
21 diff -Nuar -uar a/src/pacman/conf.h b/src/pacman/conf.h
22 --- a/src/pacman/conf.h 2020-06-22 19:33:22.000000000 +1100
23 +++ b/src/pacman/conf.h 2020-12-24 20:01:38.349183872 +1100
25 /* select -Sc behavior */
26 unsigned short cleanmethod;
28 + alpm_list_t *syncfirst;
29 alpm_list_t *ignorepkg;
30 alpm_list_t *ignoregrp;
31 alpm_list_t *assumeinstalled;
32 diff -Nuar -uar a/src/pacman/sync.c b/src/pacman/sync.c
33 --- a/src/pacman/sync.c 2020-06-22 19:33:22.000000000 +1100
34 +++ b/src/pacman/sync.c 2020-12-24 20:03:25.629181556 +1100
39 +static alpm_list_t *syncfirst(void) {
40 + alpm_list_t *i, *res = NULL;
41 + alpm_db_t *db_local = alpm_get_localdb(config->handle);
42 + alpm_list_t *syncdbs = alpm_get_syncdbs(config->handle);
44 + for(i = config->syncfirst; i; i = alpm_list_next(i)) {
45 + const char *pkgname = i->data;
46 + alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname);
51 + if(alpm_sync_get_new_version(pkg, syncdbs)) {
52 + res = alpm_list_add(res, strdup(pkgname));
59 static int process_group(alpm_list_t *dbs, const char *group, int error)
66 + /* check for syncfirsts */
67 + if(!config->op_s_downloadonly && !config->print) {
68 + /* check for newer versions of packages to be upgraded first */
69 + alpm_list_t *i, *j, *syncfirsts = syncfirst();
71 + /* Do not ask user if all the -S targets are SyncFirst packages, see FS#15810 */
72 + alpm_list_t *targets_diff = alpm_list_diff(targets, syncfirsts, (alpm_list_fn_cmp)strcmp);
73 + if(config->op_s_upgrade || targets_diff) {
74 + int syncfirst_ret = 1;
75 + colon_printf(_("Some packages should be upgraded first...\n"));
76 + if(trans_init(0, 1) == 0) {
77 + for(i = syncfirsts; i; i = alpm_list_next(i)) {
78 + syncfirst_ret = process_targname(alpm_get_syncdbs(config->handle), i->data, 0);
79 + if (syncfirst_ret == 1) {
84 + if (syncfirst_ret == 0) {
85 + syncfirst_ret = sync_prepare_execute();
89 + if (syncfirst_ret == 0) {
90 + /* reinitialize handle to take care of changes */
91 + parseconfig(config->configfile);
92 + /* remove syncfirsts from targets */
93 + alpm_list_t *i = targets;
95 + for(j = syncfirsts; j; j = alpm_list_next(j)) {
96 + if(strcmp(i->data, j->data) == 0) {
97 + targets = alpm_list_remove_item(targets, i);
106 + pm_printf(ALPM_LOG_DEBUG, "skipping SyncFirst\n");
108 + alpm_list_free(targets_diff);
109 + FREELIST(syncfirsts);
113 return sync_trans(targets);