Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
diff -Nur a/etc/pacman.conf.in b/etc/pacman.conf.in
--- a/etc/pacman.conf.in 2013-04-30 13:05:45.000000000 +0200
+++ b/etc/pacman.conf.in 2014-12-23 11:43:38.039141449 +0100
@@ -15,6 +15,8 @@
#LogFile = @localstatedir@/log/pacman.log
#GPGDir = @sysconfdir@/pacman.d/gnupg/
HoldPkg = pacman glibc
+# If upgrades are available for these packages they will be asked for first
+SyncFirst = pacman
#XferCommand = /usr/bin/curl -L -C - -f -o %o %u
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
diff -Nur a/src/pacman/conf.c b/src/pacman/conf.c
--- a/src/pacman/conf.c 2014-12-19 04:48:00.000000000 +0100
+++ b/src/pacman/conf.c 2014-12-23 11:45:05.435334649 +0100
@@ -132,6 +132,7 @@
alpm_list_free(oldconfig->explicit_removes);
FREELIST(oldconfig->holdpkg);
+ FREELIST(oldconfig->syncfirst);
FREELIST(oldconfig->ignorepkg);
FREELIST(oldconfig->ignoregrp);
FREELIST(oldconfig->assumeinstalled);
@@ -513,6 +514,8 @@
setrepeatingoption(value, "IgnoreGroup", &(config->ignoregrp));
} else if(strcmp(key, "HoldPkg") == 0) {
setrepeatingoption(value, "HoldPkg", &(config->holdpkg));
+ } else if(strcmp(key, "SyncFirst") == 0) {
+ setrepeatingoption(value, "SyncFirst", &(config->syncfirst));
} else if(strcmp(key, "CacheDir") == 0) {
setrepeatingoption(value, "CacheDir", &(config->cachedirs));
} else if(strcmp(key, "Architecture") == 0) {
diff -Nur a/src/pacman/conf.h b/src/pacman/conf.h
--- a/src/pacman/conf.h 2014-10-14 02:44:20.000000000 +0200
+++ b/src/pacman/conf.h 2014-12-23 11:45:38.021824780 +0100
@@ -99,6 +99,7 @@
/* select -Sc behavior */
unsigned short cleanmethod;
alpm_list_t *holdpkg;
+ alpm_list_t *syncfirst;
alpm_list_t *ignorepkg;
alpm_list_t *ignoregrp;
alpm_list_t *assumeinstalled;
diff -Nur a/src/pacman/sync.c b/src/pacman/sync.c
--- a/src/pacman/sync.c 2014-12-19 04:48:00.000000000 +0100
+++ b/src/pacman/sync.c 2014-12-23 11:51:26.049939350 +0100
@@ -548,6 +548,26 @@
return ret;
}
+static alpm_list_t *syncfirst(void) {
+ alpm_list_t *i, *res = NULL;
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
+ alpm_list_t *syncdbs = alpm_get_syncdbs(config->handle);
+
+ for(i = config->syncfirst; i; i = alpm_list_next(i)) {
+ const char *pkgname = i->data;
+ alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname);
+ if(pkg == NULL) {
+ continue;
+ }
+
+ if(alpm_sync_get_new_version(pkg, syncdbs)) {
+ res = alpm_list_add(res, strdup(pkgname));
+ }
+ }
+
+ return res;
+}
+
static alpm_db_t *get_db(const char *dbname)
{
alpm_list_t *i;
@@ -959,6 +979,53 @@
}
}
+ /* check for syncfirsts */
+ if(!config->op_s_downloadonly && !config->print) {
+ /* check for newer versions of packages to be upgraded first */
+ alpm_list_t *i, *j, *syncfirsts = syncfirst();
+ if(syncfirsts) {
+ /* Do not ask user if all the -S targets are SyncFirst packages, see FS#15810 */
+ alpm_list_t *targets_diff = alpm_list_diff(targets, syncfirsts, (alpm_list_fn_cmp)strcmp);
+ if(config->op_s_upgrade || targets_diff) {
+ int syncfirst_ret = 1;
+ colon_printf(_("Some packages should be upgraded first...\n"));
+ if(trans_init(0, 1) == 0) {
+ for(i = syncfirsts; i; i = alpm_list_next(i)) {
+ syncfirst_ret = process_targname(alpm_get_syncdbs(config->handle), i->data, 0);
+ if (syncfirst_ret == 1) {
+ break;
+ }
+ }
+ }
+ if (syncfirst_ret == 0) {
+ syncfirst_ret = sync_prepare_execute();
+ } else {
+ trans_release();
+ }
+ if (syncfirst_ret == 0) {
+ /* reinitialize handle to take care of changes */
+ parseconfig(config->configfile);
+ /* remove syncfirsts from targets */
+ alpm_list_t *i = targets;
+ while(i) {
+ for(j = syncfirsts; j; j = alpm_list_next(j)) {
+ if(strcmp(i->data, j->data) == 0) {
+ targets = alpm_list_remove_item(targets, i);
+ break;
+ }
+ }
+ i = i->next;
+ }
+ }
+ printf("\n");
+ } else {
+ pm_printf(ALPM_LOG_DEBUG, "skipping SyncFirst\n");
+ }
+ alpm_list_free(targets_diff);
+ FREELIST(syncfirsts);
+ }
+ }
+
return sync_trans(targets);
}