Commit | Line | Data |
---|---|---|
1479465f GJ |
1 | /* |
2 | * dpkg - main program for package management | |
3 | * depcon.c - dependency and conflict checking | |
4 | * | |
5 | * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk> | |
6 | * Copyright © 2006-2014 Guillem Jover <guillem@debian.org> | |
7 | * Copyright © 2011 Linaro Limited | |
8 | * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org> | |
9 | * | |
10 | * This is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; either version 2 of the License, or | |
13 | * (at your option) any later version. | |
14 | * | |
15 | * This is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU General Public License | |
21 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
22 | */ | |
23 | ||
24 | #include <config.h> | |
25 | #include <compat.h> | |
26 | ||
27 | #include <sys/types.h> | |
28 | #include <sys/stat.h> | |
29 | ||
30 | #include <assert.h> | |
31 | #include <errno.h> | |
32 | #include <stdlib.h> | |
33 | #include <unistd.h> | |
34 | ||
35 | #include <dpkg/i18n.h> | |
36 | #include <dpkg/dpkg.h> | |
37 | #include <dpkg/dpkg-db.h> | |
38 | ||
39 | #include "filesdb.h" | |
40 | #include "infodb.h" | |
41 | #include "main.h" | |
42 | ||
43 | struct deppossi_pkg_iterator { | |
44 | struct deppossi *possi; | |
45 | struct pkginfo *pkg_next; | |
46 | enum which_pkgbin which_pkgbin; | |
47 | }; | |
48 | ||
49 | struct deppossi_pkg_iterator * | |
50 | deppossi_pkg_iter_new(struct deppossi *possi, enum which_pkgbin wpb) | |
51 | { | |
52 | struct deppossi_pkg_iterator *iter; | |
53 | ||
54 | iter = m_malloc(sizeof(*iter)); | |
55 | iter->possi = possi; | |
56 | iter->pkg_next = &possi->ed->pkg; | |
57 | iter->which_pkgbin = wpb; | |
58 | ||
59 | return iter; | |
60 | } | |
61 | ||
62 | struct pkginfo * | |
63 | deppossi_pkg_iter_next(struct deppossi_pkg_iterator *iter) | |
64 | { | |
65 | struct pkginfo *pkg_cur; | |
66 | struct pkgbin *pkgbin; | |
67 | ||
68 | while ((pkg_cur = iter->pkg_next)) { | |
69 | iter->pkg_next = pkg_cur->arch_next; | |
70 | ||
71 | switch (iter->which_pkgbin) { | |
72 | case wpb_installed: | |
73 | pkgbin = &pkg_cur->installed; | |
74 | break; | |
75 | case wpb_available: | |
76 | pkgbin = &pkg_cur->available; | |
77 | break; | |
78 | case wpb_by_istobe: | |
79 | if (pkg_cur->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) | |
80 | pkgbin = &pkg_cur->available; | |
81 | else | |
82 | pkgbin = &pkg_cur->installed; | |
83 | break; | |
84 | default: | |
85 | internerr("unknown which_pkgbin %d", iter->which_pkgbin); | |
86 | } | |
87 | ||
88 | if (archsatisfied(pkgbin, iter->possi)) | |
89 | return pkg_cur; | |
90 | } | |
91 | ||
92 | return NULL; | |
93 | } | |
94 | ||
95 | void | |
96 | deppossi_pkg_iter_free(struct deppossi_pkg_iterator *iter) | |
97 | { | |
98 | free(iter); | |
99 | } | |
100 | ||
101 | struct cyclesofarlink { | |
102 | struct cyclesofarlink *prev; | |
103 | struct pkginfo *pkg; | |
104 | struct deppossi *possi; | |
105 | }; | |
106 | ||
107 | static bool findbreakcyclerecursive(struct pkginfo *pkg, | |
108 | struct cyclesofarlink *sofar); | |
109 | ||
110 | static bool | |
111 | foundcyclebroken(struct cyclesofarlink *thislink, struct cyclesofarlink *sofar, | |
112 | struct pkginfo *dependedon, struct deppossi *possi) | |
113 | { | |
114 | struct cyclesofarlink *sol; | |
115 | ||
116 | if(!possi) | |
117 | return false; | |
118 | ||
119 | /* We're investigating the dependency ‘possi’ to see if it | |
120 | * is part of a loop. To this end we look to see whether the | |
121 | * depended-on package is already one of the packages whose | |
122 | * dependencies we're searching. */ | |
123 | for (sol = sofar; sol && sol->pkg != dependedon; sol = sol->prev); | |
124 | ||
125 | /* If not, we do a recursive search on it to see what we find. */ | |
126 | if (!sol) | |
127 | return findbreakcyclerecursive(dependedon, thislink); | |
128 | ||
129 | debug(dbg_depcon,"found cycle"); | |
130 | /* Right, we now break one of the links. We prefer to break | |
131 | * a dependency of a package without a postinst script, as | |
132 | * this is a null operation. If this is not possible we break | |
133 | * the other link in the recursive calling tree which mentions | |
134 | * this package (this being the first package involved in the | |
135 | * cycle). It doesn't particularly matter which we pick, but if | |
136 | * we break the earliest dependency we came across we may be | |
137 | * able to do something straight away when findbreakcycle returns. */ | |
138 | sofar= thislink; | |
139 | for (sol = sofar; !(sol != sofar && sol->pkg == dependedon); sol = sol->prev) { | |
140 | if (!pkg_infodb_has_file(sol->pkg, &sol->pkg->installed, POSTINSTFILE)) | |
141 | break; | |
142 | } | |
143 | ||
144 | /* Now we have either a package with no postinst, or the other | |
145 | * occurrence of the current package in the list. */ | |
146 | sol->possi->cyclebreak = true; | |
147 | ||
148 | debug(dbg_depcon, "cycle broken at %s -> %s", | |
149 | pkg_name(sol->possi->up->up, pnaw_always), sol->possi->ed->name); | |
150 | ||
151 | return true; | |
152 | } | |
153 | ||
154 | /** | |
155 | * Cycle breaking works recursively down the package dependency tree. | |
156 | * | |
157 | * ‘sofar’ is the list of packages we've descended down already - if we | |
158 | * encounter any of its packages again in a dependency we have found a cycle. | |
159 | */ | |
160 | static bool | |
161 | findbreakcyclerecursive(struct pkginfo *pkg, struct cyclesofarlink *sofar) | |
162 | { | |
163 | struct cyclesofarlink thislink, *sol; | |
164 | struct dependency *dep; | |
165 | struct deppossi *possi, *providelink; | |
166 | struct pkginfo *provider, *pkg_pos; | |
167 | ||
168 | if (pkg->clientdata->color == PKG_CYCLE_BLACK) | |
169 | return false; | |
170 | pkg->clientdata->color = PKG_CYCLE_GRAY; | |
171 | ||
172 | if (debug_has_flag(dbg_depcondetail)) { | |
173 | struct varbuf str_pkgs = VARBUF_INIT; | |
174 | ||
175 | for (sol = sofar; sol; sol = sol->prev) { | |
176 | varbuf_add_str(&str_pkgs, " <- "); | |
177 | varbuf_add_pkgbin_name(&str_pkgs, sol->pkg, &sol->pkg->installed, pnaw_nonambig); | |
178 | } | |
179 | varbuf_end_str(&str_pkgs); | |
180 | debug(dbg_depcondetail, "findbreakcyclerecursive %s %s", | |
181 | pkg_name(pkg, pnaw_always), str_pkgs.buf); | |
182 | varbuf_destroy(&str_pkgs); | |
183 | } | |
184 | thislink.pkg= pkg; | |
185 | thislink.prev = sofar; | |
186 | thislink.possi = NULL; | |
187 | for (dep= pkg->installed.depends; dep; dep= dep->next) { | |
188 | if (dep->type != dep_depends && dep->type != dep_predepends) continue; | |
189 | for (possi= dep->list; possi; possi= possi->next) { | |
190 | struct deppossi_pkg_iterator *possi_iter; | |
191 | ||
192 | /* Don't find the same cycles again. */ | |
193 | if (possi->cyclebreak) continue; | |
194 | thislink.possi= possi; | |
195 | ||
196 | possi_iter = deppossi_pkg_iter_new(possi, wpb_installed); | |
197 | while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) | |
198 | if (foundcyclebroken(&thislink, sofar, pkg_pos, possi)) { | |
199 | deppossi_pkg_iter_free(possi_iter); | |
200 | return true; | |
201 | } | |
202 | deppossi_pkg_iter_free(possi_iter); | |
203 | ||
204 | /* Right, now we try all the providers ... */ | |
205 | for (providelink = possi->ed->depended.installed; | |
206 | providelink; | |
207 | providelink = providelink->rev_next) { | |
208 | if (providelink->up->type != dep_provides) continue; | |
209 | provider= providelink->up->up; | |
210 | if (provider->clientdata->istobe == PKG_ISTOBE_NORMAL) | |
211 | continue; | |
212 | /* We don't break things at ‘provides’ links, so ‘possi’ is | |
213 | * still the one we use. */ | |
214 | if (foundcyclebroken(&thislink, sofar, provider, possi)) | |
215 | return true; | |
216 | } | |
217 | } | |
218 | } | |
219 | /* Nope, we didn't find a cycle to break. */ | |
220 | pkg->clientdata->color = PKG_CYCLE_BLACK; | |
221 | return false; | |
222 | } | |
223 | ||
224 | bool | |
225 | findbreakcycle(struct pkginfo *pkg) | |
226 | { | |
227 | struct pkgiterator *iter; | |
228 | struct pkginfo *tpkg; | |
229 | ||
230 | /* Clear the visited flag of all packages before we traverse them. */ | |
231 | iter = pkg_db_iter_new(); | |
232 | while ((tpkg = pkg_db_iter_next_pkg(iter))) { | |
233 | ensure_package_clientdata(tpkg); | |
234 | tpkg->clientdata->color = PKG_CYCLE_WHITE; | |
235 | } | |
236 | pkg_db_iter_free(iter); | |
237 | ||
238 | return findbreakcyclerecursive(pkg, NULL); | |
239 | } | |
240 | ||
241 | void describedepcon(struct varbuf *addto, struct dependency *dep) { | |
242 | const char *fmt; | |
243 | struct varbuf depstr = VARBUF_INIT; | |
244 | ||
245 | switch (dep->type) { | |
246 | case dep_depends: | |
247 | fmt = _("%s depends on %s"); | |
248 | break; | |
249 | case dep_predepends: | |
250 | fmt = _("%s pre-depends on %s"); | |
251 | break; | |
252 | case dep_recommends: | |
253 | fmt = _("%s recommends %s"); | |
254 | break; | |
255 | case dep_suggests: | |
256 | fmt = _("%s suggests %s"); | |
257 | break; | |
258 | case dep_breaks: | |
259 | fmt = _("%s breaks %s"); | |
260 | break; | |
261 | case dep_conflicts: | |
262 | fmt = _("%s conflicts with %s"); | |
263 | break; | |
264 | case dep_enhances: | |
265 | fmt = _("%s enhances %s"); | |
266 | break; | |
267 | default: | |
268 | internerr("unknown deptype '%d'", dep->type); | |
269 | } | |
270 | ||
271 | varbufdependency(&depstr, dep); | |
272 | varbuf_end_str(&depstr); | |
273 | ||
274 | varbuf_printf(addto, fmt, pkg_name(dep->up, pnaw_nonambig), depstr.buf); | |
275 | varbuf_destroy(&depstr); | |
276 | } | |
277 | ||
278 | /* | |
279 | * *whynot must already have been initialized; it need not be | |
280 | * empty though - it will be reset before use. | |
281 | * | |
282 | * If depisok returns false for ‘not OK’ it will contain a description, | |
283 | * newline-terminated BUT NOT NUL-TERMINATED, of the reason. | |
284 | * | |
285 | * If depisok returns true it will contain garbage. | |
286 | * allowunconfigd should be non-zero during the ‘Pre-Depends’ checking | |
287 | * before a package is unpacked, when it is sufficient for the package | |
288 | * to be unpacked provided that both the unpacked and previously-configured | |
289 | * versions are acceptable. | |
290 | * | |
291 | * On false return (‘not OK’), *canfixbyremove refers to a package which | |
292 | * if removed (dep_conflicts) or deconfigured (dep_breaks) will fix | |
293 | * the problem. Caller may pass NULL for canfixbyremove and need not | |
294 | * initialize *canfixbyremove. | |
295 | * | |
296 | * On false return (‘not OK’), *canfixbytrigaw refers to a package which | |
297 | * can fix the problem if all the packages listed in Triggers-Awaited have | |
298 | * their triggers processed. Caller may pass NULL for canfixbytrigaw and | |
299 | * need not initialize *canfixbytrigaw. | |
300 | */ | |
301 | bool | |
302 | depisok(struct dependency *dep, struct varbuf *whynot, | |
303 | struct pkginfo **canfixbyremove, struct pkginfo **canfixbytrigaw, | |
304 | bool allowunconfigd) | |
305 | { | |
306 | struct deppossi *possi; | |
307 | struct deppossi *provider; | |
308 | struct pkginfo *pkg_pos; | |
309 | int nconflicts; | |
310 | ||
311 | /* Use this buffer so that when internationalisation comes along we | |
312 | * don't have to rewrite the code completely, only redo the sprintf strings | |
313 | * (assuming we have the fancy argument-number-specifiers). | |
314 | * Allow 250x3 for package names, versions, &c, + 250 for ourselves. */ | |
315 | char linebuf[1024]; | |
316 | ||
317 | assert(dep->type == dep_depends || dep->type == dep_predepends || | |
318 | dep->type == dep_breaks || dep->type == dep_conflicts || | |
319 | dep->type == dep_recommends || dep->type == dep_suggests || | |
320 | dep->type == dep_enhances); | |
321 | ||
322 | if (canfixbyremove) | |
323 | *canfixbyremove = NULL; | |
324 | if (canfixbytrigaw) | |
325 | *canfixbytrigaw = NULL; | |
326 | ||
327 | /* The dependency is always OK if we're trying to remove the depend*ing* | |
328 | * package. */ | |
329 | switch (dep->up->clientdata->istobe) { | |
330 | case PKG_ISTOBE_REMOVE: | |
331 | case PKG_ISTOBE_DECONFIGURE: | |
332 | return true; | |
333 | case PKG_ISTOBE_NORMAL: | |
334 | /* Only installed packages can be make dependency problems. */ | |
335 | switch (dep->up->status) { | |
336 | case PKG_STAT_INSTALLED: | |
337 | case PKG_STAT_TRIGGERSPENDING: | |
338 | case PKG_STAT_TRIGGERSAWAITED: | |
339 | break; | |
340 | case PKG_STAT_HALFCONFIGURED: | |
341 | case PKG_STAT_UNPACKED: | |
342 | case PKG_STAT_HALFINSTALLED: | |
343 | if (dep->type == dep_predepends || | |
344 | dep->type == dep_conflicts || | |
345 | dep->type == dep_breaks) | |
346 | break; | |
347 | /* Fall through. */ | |
348 | case PKG_STAT_CONFIGFILES: | |
349 | case PKG_STAT_NOTINSTALLED: | |
350 | return true; | |
351 | default: | |
352 | internerr("unknown status depending '%d'", dep->up->status); | |
353 | } | |
354 | break; | |
355 | case PKG_ISTOBE_INSTALLNEW: | |
356 | case PKG_ISTOBE_PREINSTALL: | |
357 | break; | |
358 | default: | |
359 | internerr("unknown istobe depending '%d'", dep->up->clientdata->istobe); | |
360 | } | |
361 | ||
362 | /* Describe the dependency, in case we have to moan about it. */ | |
363 | varbuf_reset(whynot); | |
364 | varbuf_add_char(whynot, ' '); | |
365 | describedepcon(whynot, dep); | |
366 | varbuf_add_char(whynot, '\n'); | |
367 | ||
368 | /* TODO: Check dep_enhances as well. */ | |
369 | if (dep->type == dep_depends || dep->type == dep_predepends || | |
370 | dep->type == dep_recommends || dep->type == dep_suggests ) { | |
371 | /* Go through the alternatives. As soon as we find one that | |
372 | * we like, we return ‘true’ straight away. Otherwise, when we get to | |
373 | * the end we'll have accumulated all the reasons in whynot and | |
374 | * can return ‘false’. */ | |
375 | ||
376 | for (possi= dep->list; possi; possi= possi->next) { | |
377 | struct deppossi_pkg_iterator *possi_iter; | |
378 | ||
379 | possi_iter = deppossi_pkg_iter_new(possi, wpb_by_istobe); | |
380 | while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) { | |
381 | switch (pkg_pos->clientdata->istobe) { | |
382 | case PKG_ISTOBE_REMOVE: | |
383 | sprintf(linebuf, _(" %.250s is to be removed.\n"), | |
384 | pkg_name(pkg_pos, pnaw_nonambig)); | |
385 | break; | |
386 | case PKG_ISTOBE_DECONFIGURE: | |
387 | sprintf(linebuf, _(" %.250s is to be deconfigured.\n"), | |
388 | pkg_name(pkg_pos, pnaw_nonambig)); | |
389 | break; | |
390 | case PKG_ISTOBE_INSTALLNEW: | |
391 | if (versionsatisfied(&pkg_pos->available, possi)) { | |
392 | deppossi_pkg_iter_free(possi_iter); | |
393 | return true; | |
394 | } | |
395 | sprintf(linebuf, _(" %.250s is to be installed, but is version " | |
396 | "%.250s.\n"), | |
397 | pkgbin_name(pkg_pos, &pkg_pos->available, pnaw_nonambig), | |
398 | versiondescribe(&pkg_pos->available.version, vdew_nonambig)); | |
399 | break; | |
400 | case PKG_ISTOBE_NORMAL: | |
401 | case PKG_ISTOBE_PREINSTALL: | |
402 | switch (pkg_pos->status) { | |
403 | case PKG_STAT_INSTALLED: | |
404 | case PKG_STAT_TRIGGERSPENDING: | |
405 | if (versionsatisfied(&pkg_pos->installed, possi)) { | |
406 | deppossi_pkg_iter_free(possi_iter); | |
407 | return true; | |
408 | } | |
409 | sprintf(linebuf, _(" %.250s is installed, but is version " | |
410 | "%.250s.\n"), | |
411 | pkg_name(pkg_pos, pnaw_nonambig), | |
412 | versiondescribe(&pkg_pos->installed.version, vdew_nonambig)); | |
413 | break; | |
414 | case PKG_STAT_NOTINSTALLED: | |
415 | /* Don't say anything about this yet - it might be a virtual package. | |
416 | * Later on, if nothing has put anything in linebuf, we know that it | |
417 | * isn't and issue a diagnostic then. */ | |
418 | *linebuf = '\0'; | |
419 | break; | |
420 | case PKG_STAT_TRIGGERSAWAITED: | |
421 | if (canfixbytrigaw && versionsatisfied(&pkg_pos->installed, possi)) | |
422 | *canfixbytrigaw = pkg_pos; | |
423 | /* Fall through. */ | |
424 | case PKG_STAT_UNPACKED: | |
425 | case PKG_STAT_HALFCONFIGURED: | |
426 | if (allowunconfigd) { | |
427 | if (!dpkg_version_is_informative(&pkg_pos->configversion)) { | |
428 | sprintf(linebuf, _(" %.250s is unpacked, but has never been " | |
429 | "configured.\n"), | |
430 | pkg_name(pkg_pos, pnaw_nonambig)); | |
431 | break; | |
432 | } else if (!versionsatisfied(&pkg_pos->installed, possi)) { | |
433 | sprintf(linebuf, _(" %.250s is unpacked, but is version " | |
434 | "%.250s.\n"), | |
435 | pkg_name(pkg_pos, pnaw_nonambig), | |
436 | versiondescribe(&pkg_pos->installed.version, | |
437 | vdew_nonambig)); | |
438 | break; | |
439 | } else if (!dpkg_version_relate(&pkg_pos->configversion, | |
440 | possi->verrel, | |
441 | &possi->version)) { | |
442 | sprintf(linebuf, _(" %.250s latest configured version is " | |
443 | "%.250s.\n"), | |
444 | pkg_name(pkg_pos, pnaw_nonambig), | |
445 | versiondescribe(&pkg_pos->configversion, vdew_nonambig)); | |
446 | break; | |
447 | } else { | |
448 | deppossi_pkg_iter_free(possi_iter); | |
449 | return true; | |
450 | } | |
451 | } | |
452 | /* Fall through. */ | |
453 | default: | |
454 | sprintf(linebuf, _(" %.250s is %s.\n"), | |
455 | pkg_name(pkg_pos, pnaw_nonambig), | |
456 | gettext(statusstrings[pkg_pos->status])); | |
457 | break; | |
458 | } | |
459 | break; | |
460 | default: | |
461 | internerr("unknown istobe depended '%d'", pkg_pos->clientdata->istobe); | |
462 | } | |
463 | varbuf_add_str(whynot, linebuf); | |
464 | } | |
465 | deppossi_pkg_iter_free(possi_iter); | |
466 | ||
467 | /* See if the package we're about to install Provides it. */ | |
468 | for (provider = possi->ed->depended.available; | |
469 | provider; | |
470 | provider = provider->rev_next) { | |
471 | if (provider->up->type != dep_provides) continue; | |
472 | if (!pkg_virtual_deppossi_satisfied(possi, provider)) | |
473 | continue; | |
474 | if (provider->up->up->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) | |
475 | return true; | |
476 | } | |
477 | ||
478 | /* Now look at the packages already on the system. */ | |
479 | for (provider = possi->ed->depended.installed; | |
480 | provider; | |
481 | provider = provider->rev_next) { | |
482 | if (provider->up->type != dep_provides) continue; | |
483 | if (!pkg_virtual_deppossi_satisfied(possi, provider)) | |
484 | continue; | |
485 | ||
486 | switch (provider->up->up->clientdata->istobe) { | |
487 | case PKG_ISTOBE_INSTALLNEW: | |
488 | /* Don't pay any attention to the Provides field of the | |
489 | * currently-installed version of the package we're trying | |
490 | * to install. We dealt with that by using the available | |
491 | * information above. */ | |
492 | continue; | |
493 | case PKG_ISTOBE_REMOVE: | |
494 | sprintf(linebuf, _(" %.250s provides %.250s but is to be removed.\n"), | |
495 | pkg_name(provider->up->up, pnaw_nonambig), | |
496 | possi->ed->name); | |
497 | break; | |
498 | case PKG_ISTOBE_DECONFIGURE: | |
499 | sprintf(linebuf, _(" %.250s provides %.250s but is to be deconfigured.\n"), | |
500 | pkg_name(provider->up->up, pnaw_nonambig), | |
501 | possi->ed->name); | |
502 | break; | |
503 | case PKG_ISTOBE_NORMAL: | |
504 | case PKG_ISTOBE_PREINSTALL: | |
505 | if (provider->up->up->status == PKG_STAT_INSTALLED || | |
506 | provider->up->up->status == PKG_STAT_TRIGGERSPENDING) | |
507 | return true; | |
508 | if (provider->up->up->status == PKG_STAT_TRIGGERSAWAITED) | |
509 | *canfixbytrigaw = provider->up->up; | |
510 | sprintf(linebuf, _(" %.250s provides %.250s but is %s.\n"), | |
511 | pkg_name(provider->up->up, pnaw_nonambig), | |
512 | possi->ed->name, | |
513 | gettext(statusstrings[provider->up->up->status])); | |
514 | break; | |
515 | default: | |
516 | internerr("unknown istobe provider '%d'", | |
517 | provider->up->up->clientdata->istobe); | |
518 | } | |
519 | varbuf_add_str(whynot, linebuf); | |
520 | } | |
521 | ||
522 | if (!*linebuf) { | |
523 | /* If the package wasn't installed at all, and we haven't said | |
524 | * yet why this isn't satisfied, we should say so now. */ | |
525 | sprintf(linebuf, _(" %.250s is not installed.\n"), possi->ed->name); | |
526 | varbuf_add_str(whynot, linebuf); | |
527 | } | |
528 | } | |
529 | ||
530 | return false; | |
531 | } else { | |
532 | /* It's conflicts or breaks. There's only one main alternative, | |
533 | * but we also have to consider Providers. We return ‘false’ as soon | |
534 | * as we find something that matches the conflict, and only describe | |
535 | * it then. If we get to the end without finding anything we return | |
536 | * ‘true’. */ | |
537 | ||
538 | possi= dep->list; | |
539 | nconflicts= 0; | |
540 | ||
541 | if (possi->ed != possi->up->up->set) { | |
542 | struct deppossi_pkg_iterator *possi_iter; | |
543 | ||
544 | /* If the package conflicts with or breaks itself it must mean | |
545 | * other packages which provide the same virtual name. We | |
546 | * therefore don't look at the real package and go on to the | |
547 | * virtual ones. */ | |
548 | ||
549 | possi_iter = deppossi_pkg_iter_new(possi, wpb_by_istobe); | |
550 | while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) { | |
551 | switch (pkg_pos->clientdata->istobe) { | |
552 | case PKG_ISTOBE_REMOVE: | |
553 | break; | |
554 | case PKG_ISTOBE_INSTALLNEW: | |
555 | if (!versionsatisfied(&pkg_pos->available, possi)) | |
556 | break; | |
557 | sprintf(linebuf, _(" %.250s (version %.250s) is to be installed.\n"), | |
558 | pkgbin_name(pkg_pos, &pkg_pos->available, pnaw_nonambig), | |
559 | versiondescribe(&pkg_pos->available.version, vdew_nonambig)); | |
560 | varbuf_add_str(whynot, linebuf); | |
561 | if (!canfixbyremove) { | |
562 | deppossi_pkg_iter_free(possi_iter); | |
563 | return false; | |
564 | } | |
565 | nconflicts++; | |
566 | *canfixbyremove = pkg_pos; | |
567 | break; | |
568 | case PKG_ISTOBE_DECONFIGURE: | |
569 | if (dep->type == dep_breaks) | |
570 | break; /* Already deconfiguring this. */ | |
571 | /* Fall through. */ | |
572 | case PKG_ISTOBE_NORMAL: | |
573 | case PKG_ISTOBE_PREINSTALL: | |
574 | switch (pkg_pos->status) { | |
575 | case PKG_STAT_NOTINSTALLED: | |
576 | case PKG_STAT_CONFIGFILES: | |
577 | break; | |
578 | case PKG_STAT_HALFINSTALLED: | |
579 | case PKG_STAT_UNPACKED: | |
580 | case PKG_STAT_HALFCONFIGURED: | |
581 | if (dep->type == dep_breaks) | |
582 | break; /* No problem. */ | |
583 | /* Fall through. */ | |
584 | case PKG_STAT_INSTALLED: | |
585 | case PKG_STAT_TRIGGERSPENDING: | |
586 | case PKG_STAT_TRIGGERSAWAITED: | |
587 | if (!versionsatisfied(&pkg_pos->installed, possi)) | |
588 | break; | |
589 | sprintf(linebuf, _(" %.250s (version %.250s) is present and %s.\n"), | |
590 | pkg_name(pkg_pos, pnaw_nonambig), | |
591 | versiondescribe(&pkg_pos->installed.version, vdew_nonambig), | |
592 | gettext(statusstrings[pkg_pos->status])); | |
593 | varbuf_add_str(whynot, linebuf); | |
594 | if (!canfixbyremove) { | |
595 | deppossi_pkg_iter_free(possi_iter); | |
596 | return false; | |
597 | } | |
598 | nconflicts++; | |
599 | *canfixbyremove = pkg_pos; | |
600 | } | |
601 | break; | |
602 | default: | |
603 | internerr("unknown istobe conflict '%d'", pkg_pos->clientdata->istobe); | |
604 | } | |
605 | } | |
606 | deppossi_pkg_iter_free(possi_iter); | |
607 | } | |
608 | ||
609 | /* See if the package we're about to install Provides it. */ | |
610 | for (provider = possi->ed->depended.available; | |
611 | provider; | |
612 | provider = provider->rev_next) { | |
613 | if (provider->up->type != dep_provides) continue; | |
614 | if (provider->up->up->clientdata->istobe != PKG_ISTOBE_INSTALLNEW) | |
615 | continue; | |
616 | if (provider->up->up->set == dep->up->set) | |
617 | continue; /* Conflicts and provides the same. */ | |
618 | if (!pkg_virtual_deppossi_satisfied(possi, provider)) | |
619 | continue; | |
620 | sprintf(linebuf, _(" %.250s provides %.250s and is to be installed.\n"), | |
621 | pkgbin_name(provider->up->up, &provider->up->up->available, | |
622 | pnaw_nonambig), possi->ed->name); | |
623 | varbuf_add_str(whynot, linebuf); | |
624 | /* We can't remove the one we're about to install: */ | |
625 | if (canfixbyremove) | |
626 | *canfixbyremove = NULL; | |
627 | return false; | |
628 | } | |
629 | ||
630 | /* Now look at the packages already on the system. */ | |
631 | for (provider = possi->ed->depended.installed; | |
632 | provider; | |
633 | provider = provider->rev_next) { | |
634 | if (provider->up->type != dep_provides) continue; | |
635 | ||
636 | if (provider->up->up->set == dep->up->set) | |
637 | continue; /* Conflicts and provides the same. */ | |
638 | ||
639 | if (!pkg_virtual_deppossi_satisfied(possi, provider)) | |
640 | continue; | |
641 | ||
642 | switch (provider->up->up->clientdata->istobe) { | |
643 | case PKG_ISTOBE_INSTALLNEW: | |
644 | /* Don't pay any attention to the Provides field of the | |
645 | * currently-installed version of the package we're trying | |
646 | * to install. We dealt with that package by using the | |
647 | * available information above. */ | |
648 | continue; | |
649 | case PKG_ISTOBE_REMOVE: | |
650 | continue; | |
651 | case PKG_ISTOBE_DECONFIGURE: | |
652 | if (dep->type == dep_breaks) | |
653 | continue; /* Already deconfiguring. */ | |
654 | /* Fall through. */ | |
655 | case PKG_ISTOBE_NORMAL: | |
656 | case PKG_ISTOBE_PREINSTALL: | |
657 | switch (provider->up->up->status) { | |
658 | case PKG_STAT_NOTINSTALLED: | |
659 | case PKG_STAT_CONFIGFILES: | |
660 | continue; | |
661 | case PKG_STAT_HALFINSTALLED: | |
662 | case PKG_STAT_UNPACKED: | |
663 | case PKG_STAT_HALFCONFIGURED: | |
664 | if (dep->type == dep_breaks) | |
665 | break; /* No problem. */ | |
666 | /* Fall through. */ | |
667 | case PKG_STAT_INSTALLED: | |
668 | case PKG_STAT_TRIGGERSPENDING: | |
669 | case PKG_STAT_TRIGGERSAWAITED: | |
670 | sprintf(linebuf, | |
671 | _(" %.250s provides %.250s and is present and %s.\n"), | |
672 | pkg_name(provider->up->up, pnaw_nonambig), possi->ed->name, | |
673 | gettext(statusstrings[provider->up->up->status])); | |
674 | varbuf_add_str(whynot, linebuf); | |
675 | if (!canfixbyremove) | |
676 | return false; | |
677 | nconflicts++; | |
678 | *canfixbyremove= provider->up->up; | |
679 | break; | |
680 | } | |
681 | break; | |
682 | default: | |
683 | internerr("unknown istobe conflict provider '%d'", | |
684 | provider->up->up->clientdata->istobe); | |
685 | } | |
686 | } | |
687 | ||
688 | if (!nconflicts) | |
689 | return true; | |
690 | if (nconflicts > 1) | |
691 | *canfixbyremove = NULL; | |
692 | return false; | |
693 | ||
694 | } /* if (dependency) {...} else {...} */ | |
695 | } |