Branch data Line data Source code
1 : : /*
2 : : * dpkg - main program for package management
3 : : * packages.c - common to actions that process packages
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 <string.h>
31 : : #include <fcntl.h>
32 : : #include <dirent.h>
33 : : #include <unistd.h>
34 : : #include <stdlib.h>
35 : : #include <stdio.h>
36 : :
37 : : #include <dpkg/i18n.h>
38 : : #include <dpkg/dpkg.h>
39 : : #include <dpkg/dpkg-db.h>
40 : : #include <dpkg/pkg-list.h>
41 : : #include <dpkg/pkg-queue.h>
42 : : #include <dpkg/string.h>
43 : : #include <dpkg/options.h>
44 : : #include <dpkg/db-ctrl.h>
45 : : #include <dpkg/db-fsys.h>
46 : :
47 : : #include "main.h"
48 : :
49 : : static struct pkginfo *progress_bytrigproc;
50 : : static struct pkg_queue queue = PKG_QUEUE_INIT;
51 : :
52 : : enum dependtry dependtry = DEPEND_TRY_NORMAL;
53 : : int sincenothing = 0;
54 : :
55 : : void
56 : 0 : enqueue_package(struct pkginfo *pkg)
57 : : {
58 : 0 : ensure_package_clientdata(pkg);
59 [ # # ]: 0 : if (pkg->clientdata->enqueued)
60 : 0 : return;
61 : 0 : pkg->clientdata->enqueued = true;
62 : 0 : pkg_queue_push(&queue, pkg);
63 : : }
64 : :
65 : : void
66 : 0 : enqueue_package_mark_seen(struct pkginfo *pkg)
67 : : {
68 : 0 : enqueue_package(pkg);
69 : 0 : pkg->clientdata->cmdline_seen++;
70 : 0 : }
71 : :
72 : : static void
73 : 0 : enqueue_pending(void)
74 : : {
75 : : struct pkg_hash_iter *iter;
76 : : struct pkginfo *pkg;
77 : :
78 : 0 : iter = pkg_hash_iter_new();
79 [ # # ]: 0 : while ((pkg = pkg_hash_iter_next_pkg(iter)) != NULL) {
80 [ # # # # ]: 0 : switch (cipaction->arg_int) {
81 : 0 : case act_configure:
82 [ # # ]: 0 : if (!(pkg->status == PKG_STAT_UNPACKED ||
83 [ # # ]: 0 : pkg->status == PKG_STAT_HALFCONFIGURED ||
84 [ # # ]: 0 : pkg->trigpend_head))
85 : 0 : continue;
86 [ # # ]: 0 : if (pkg->want != PKG_WANT_INSTALL &&
87 [ # # ]: 0 : pkg->want != PKG_WANT_HOLD)
88 : 0 : continue;
89 : 0 : break;
90 : 0 : case act_triggers:
91 [ # # ]: 0 : if (!pkg->trigpend_head)
92 : 0 : continue;
93 [ # # ]: 0 : if (pkg->want != PKG_WANT_INSTALL &&
94 [ # # ]: 0 : pkg->want != PKG_WANT_HOLD)
95 : 0 : continue;
96 : 0 : break;
97 : 0 : case act_remove:
98 : : case act_purge:
99 [ # # ]: 0 : if (pkg->want != PKG_WANT_PURGE) {
100 [ # # ]: 0 : if (pkg->want != PKG_WANT_DEINSTALL)
101 : 0 : continue;
102 [ # # ]: 0 : if (pkg->status == PKG_STAT_CONFIGFILES)
103 : 0 : continue;
104 : : }
105 [ # # ]: 0 : if (pkg->status == PKG_STAT_NOTINSTALLED)
106 : 0 : continue;
107 : 0 : break;
108 : 0 : default:
109 : 0 : internerr("unknown action '%d'", cipaction->arg_int);
110 : : }
111 : 0 : enqueue_package(pkg);
112 : : }
113 : 0 : pkg_hash_iter_free(iter);
114 : 0 : }
115 : :
116 : : static void
117 : 0 : enqueue_specified(const char *const *argv)
118 : : {
119 : : const char *thisarg;
120 : :
121 [ # # ]: 0 : while ((thisarg = *argv++) != NULL) {
122 : : struct pkginfo *pkg;
123 : :
124 : 0 : pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
125 [ # # # # ]: 0 : if (pkg->status == PKG_STAT_NOTINSTALLED &&
126 : 0 : str_match_end(pkg->set->name, DEBEXT)) {
127 : 0 : badusage(_("you must specify packages by their own names, "
128 : : "not by quoting the names of the files they come in"));
129 : : }
130 : 0 : enqueue_package_mark_seen(pkg);
131 : : }
132 : :
133 [ # # ]: 0 : if (cipaction->arg_int == act_configure)
134 : 0 : trigproc_populate_deferred();
135 : 0 : }
136 : :
137 : : int
138 : 0 : packages(const char *const *argv)
139 : : {
140 : 0 : trigproc_install_hooks();
141 : :
142 [ # # # # ]: 0 : modstatdb_open(f_noact ? msdbrw_readonly :
143 : 0 : in_force(FORCE_NON_ROOT) ? msdbrw_write :
144 : : msdbrw_needsuperuser);
145 : 0 : checkpath();
146 : 0 : pkg_infodb_upgrade();
147 : :
148 : 0 : log_message("startup packages %s", cipaction->olong);
149 : :
150 [ # # ]: 0 : if (f_pending) {
151 [ # # ]: 0 : if (*argv)
152 : 0 : badusage(_("--%s --pending does not take any non-option arguments"),cipaction->olong);
153 : :
154 : 0 : enqueue_pending();
155 : : } else {
156 [ # # ]: 0 : if (!*argv)
157 : 0 : badusage(_("--%s needs at least one package name argument"), cipaction->olong);
158 : :
159 : 0 : enqueue_specified(argv);
160 : : }
161 : :
162 : 0 : ensure_diversions();
163 : :
164 : 0 : process_queue();
165 : 0 : trigproc_run_deferred();
166 : :
167 : 0 : modstatdb_shutdown();
168 : :
169 : 0 : return 0;
170 : : }
171 : :
172 : 0 : void process_queue(void) {
173 : : struct pkg_list *rundown;
174 : : struct pkginfo *volatile pkg;
175 : : volatile enum action action_todo;
176 : : jmp_buf ejbuf;
177 : 0 : enum pkg_istobe istobe = PKG_ISTOBE_NORMAL;
178 : :
179 [ # # ]: 0 : if (abort_processing)
180 : 0 : return;
181 : :
182 : 0 : clear_istobes();
183 : :
184 [ # # # ]: 0 : switch (cipaction->arg_int) {
185 : 0 : case act_triggers:
186 : : case act_configure:
187 : : case act_install:
188 : 0 : istobe = PKG_ISTOBE_INSTALLNEW;
189 : 0 : break;
190 : 0 : case act_remove:
191 : : case act_purge:
192 : 0 : istobe = PKG_ISTOBE_REMOVE;
193 : 0 : break;
194 : 0 : default:
195 : 0 : internerr("unknown action '%d'", cipaction->arg_int);
196 : : }
197 [ # # ]: 0 : for (rundown = queue.head; rundown; rundown = rundown->next) {
198 : 0 : ensure_package_clientdata(rundown->pkg);
199 : :
200 : : /* We have processed this package more than once. There are no duplicates
201 : : * as we make sure of that when enqueuing them. */
202 [ # # ]: 0 : if (rundown->pkg->clientdata->cmdline_seen > 1) {
203 [ # # # ]: 0 : switch (cipaction->arg_int) {
204 : 0 : case act_triggers:
205 : : case act_configure: case act_remove: case act_purge:
206 : 0 : printf(_("Package %s listed more than once, only processing once.\n"),
207 : : pkg_name(rundown->pkg, pnaw_nonambig));
208 : 0 : break;
209 : 0 : case act_install:
210 : 0 : printf(_("More than one copy of package %s has been unpacked\n"
211 : : " in this run ! Only configuring it once.\n"),
212 : : pkg_name(rundown->pkg, pnaw_nonambig));
213 : 0 : break;
214 : 0 : default:
215 : 0 : internerr("unknown action '%d'", cipaction->arg_int);
216 : : }
217 : : }
218 : 0 : rundown->pkg->clientdata->istobe = istobe;
219 : : }
220 : :
221 [ # # ]: 0 : while (!pkg_queue_is_empty(&queue)) {
222 : 0 : pkg = pkg_queue_pop(&queue);
223 [ # # ]: 0 : if (!pkg)
224 : 0 : continue; /* Duplicate, which we removed earlier. */
225 : :
226 : 0 : ensure_package_clientdata(pkg);
227 : 0 : pkg->clientdata->enqueued = false;
228 : :
229 : 0 : action_todo = cipaction->arg_int;
230 : :
231 [ # # ]: 0 : if (sincenothing++ > queue.length * 3 + 2) {
232 : : /* Make sure that even if we have exceeded the queue since not having
233 : : * made any progress, we are not getting stuck trying to progress by
234 : : * trigger processing, w/o jumping into the next dependtry. */
235 : 0 : dependtry++;
236 : 0 : sincenothing = 0;
237 [ # # ]: 0 : if (dependtry >= DEPEND_TRY_LAST)
238 : 0 : internerr("exceeded dependtry %d (sincenothing=%d; queue.length=%d)",
239 : : dependtry, sincenothing, queue.length);
240 [ # # ]: 0 : } else if (sincenothing > queue.length * 2 + 2) {
241 [ # # # # ]: 0 : if (dependtry >= DEPEND_TRY_TRIGGERS &&
242 [ # # ]: 0 : progress_bytrigproc && progress_bytrigproc->trigpend_head) {
243 : 0 : enqueue_package(pkg);
244 : 0 : pkg = progress_bytrigproc;
245 : 0 : progress_bytrigproc = NULL;
246 : 0 : action_todo = act_configure;
247 : : } else {
248 : 0 : dependtry++;
249 : 0 : sincenothing = 0;
250 [ # # ]: 0 : if (dependtry >= DEPEND_TRY_LAST)
251 : 0 : internerr("exceeded dependtry %d (sincenothing=%d, queue.length=%d)",
252 : : dependtry, sincenothing, queue.length);
253 : : }
254 : : }
255 : :
256 : 0 : debug(dbg_general, "process queue pkg %s queue.len %d progress %d, try %d",
257 : : pkg_name(pkg, pnaw_always), queue.length, sincenothing, dependtry);
258 : :
259 [ # # ]: 0 : if (pkg->status > PKG_STAT_INSTALLED)
260 : 0 : internerr("package %s status %d is out-of-bounds",
261 : : pkg_name(pkg, pnaw_always), pkg->status);
262 : :
263 [ # # ]: 0 : if (setjmp(ejbuf)) {
264 : : /* Give up on it from the point of view of other packages, i.e. reset
265 : : * istobe. */
266 : 0 : pkg->clientdata->istobe = PKG_ISTOBE_NORMAL;
267 : :
268 : 0 : pop_error_context(ehflag_bombout);
269 [ # # ]: 0 : if (abort_processing)
270 : 0 : return;
271 : 0 : continue;
272 : : }
273 : 0 : push_error_context_jump(&ejbuf, print_error_perpackage,
274 : 0 : pkg_name(pkg, pnaw_nonambig));
275 : :
276 [ # # # # : 0 : switch (action_todo) {
# ]
277 : 0 : case act_triggers:
278 [ # # ]: 0 : if (!pkg->trigpend_head)
279 : 0 : ohshit(_("package %.250s is not ready for trigger processing\n"
280 : : " (current status '%.250s' with no pending triggers)"),
281 : : pkg_name(pkg, pnaw_nonambig), pkg_status_name(pkg));
282 : : /* Fall through. */
283 : : case act_install:
284 : : /* Don't try to configure pkgs that we've just disappeared. */
285 [ # # ]: 0 : if (pkg->status == PKG_STAT_NOTINSTALLED)
286 : 0 : break;
287 : : /* Fall through. */
288 : : case act_configure:
289 : : /* Do whatever is most needed. */
290 [ # # ]: 0 : if (pkg->trigpend_head)
291 : 0 : trigproc(pkg, TRIGPROC_TRY_QUEUED);
292 : : else
293 : 0 : deferred_configure(pkg);
294 : 0 : break;
295 : 0 : case act_remove: case act_purge:
296 : 0 : deferred_remove(pkg);
297 : 0 : break;
298 : 0 : default:
299 : 0 : internerr("unknown action '%d'", cipaction->arg_int);
300 : : }
301 : 0 : m_output(stdout, _("<standard output>"));
302 : 0 : m_output(stderr, _("<standard error>"));
303 : :
304 : 0 : pop_error_context(ehflag_normaltidy);
305 : : }
306 : :
307 [ # # ]: 0 : if (queue.length)
308 : 0 : internerr("finished package processing with non-empty queue length %d",
309 : : queue.length);
310 : : }
311 : :
312 : : /*** Dependency processing - common to --configure and --remove. ***/
313 : :
314 : : /*
315 : : * The algorithm for deciding what to configure or remove first is as
316 : : * follows:
317 : : *
318 : : * Loop through all packages doing a ‘try 1’ until we've been round and
319 : : * nothing has been done, then do ‘try 2’ and ‘try 3’ likewise.
320 : : *
321 : : * When configuring, in each try we check to see whether all
322 : : * dependencies of this package are done. If so we do it. If some of
323 : : * the dependencies aren't done yet but will be later we defer the
324 : : * package, otherwise it is an error.
325 : : *
326 : : * When removing, in each try we check to see whether there are any
327 : : * packages that would have dependencies missing if we removed this
328 : : * one. If not we remove it now. If some of these packages are
329 : : * themselves scheduled for removal we defer the package until they
330 : : * have been done.
331 : : *
332 : : * The criteria for satisfying a dependency vary with the various
333 : : * tries. In try 1 we treat the dependencies as absolute. In try 2 we
334 : : * check break any cycles in the dependency graph involving the package
335 : : * we are trying to process before trying to process the package
336 : : * normally. In try 3 (which should only be reached if
337 : : * --force-depends-version is set) we ignore version number clauses in
338 : : * Depends lines. In try 4 (only reached if --force-depends is set) we
339 : : * say "ok" regardless.
340 : : *
341 : : * If we are configuring and one of the packages we depend on is
342 : : * awaiting configuration but wasn't specified in the argument list we
343 : : * will add it to the argument list if --configure-any is specified.
344 : : * In this case we note this as having "done something" so that we
345 : : * don't needlessly escalate to higher levels of dependency checking
346 : : * and breaking.
347 : : */
348 : :
349 : : enum found_status {
350 : : FOUND_NONE = 0,
351 : : FOUND_DEFER = 1,
352 : : FOUND_FORCED = 2,
353 : : FOUND_OK = 3,
354 : : };
355 : :
356 : : static enum found_status
357 : 0 : found_forced_on(enum dependtry dependtry_forced)
358 : : {
359 [ # # ]: 0 : if (dependtry >= dependtry_forced)
360 : 0 : return FOUND_FORCED;
361 : : else
362 : 0 : return FOUND_DEFER;
363 : : }
364 : :
365 : : /*
366 : : * Return values:
367 : : * 0: cannot be satisfied.
368 : : * 1: defer: may be satisfied later, when other packages are better or
369 : : * at higher dependtry due to --force
370 : : * will set *fixbytrig to package whose trigger processing would help
371 : : * if applicable (and leave it alone otherwise).
372 : : * 2: not satisfied but forcing
373 : : * (*interestingwarnings >= 0 on exit? caller is to print oemsgs).
374 : : * 3: satisfied now.
375 : : */
376 : : static enum found_status
377 : 0 : deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby,
378 : : struct pkginfo *removing, struct deppossi *provider,
379 : : struct pkginfo **fixbytrig,
380 : : bool *matched, struct deppossi *checkversion,
381 : : int *interestingwarnings, struct varbuf *oemsgs)
382 : : {
383 : : enum found_status thisf;
384 : :
385 [ # # ]: 0 : if (ignore_depends(possdependee)) {
386 : 0 : debug(dbg_depcondetail," ignoring depended package so ok and found");
387 : 0 : return FOUND_OK;
388 : : }
389 : 0 : thisf = FOUND_NONE;
390 [ # # ]: 0 : if (possdependee == removing) {
391 [ # # ]: 0 : if (provider) {
392 : 0 : varbuf_printf(oemsgs,
393 : 0 : _(" Package %s which provides %s is to be removed.\n"),
394 : : pkg_name(possdependee, pnaw_nonambig),
395 : 0 : provider->ed->name);
396 : : } else {
397 : 0 : varbuf_printf(oemsgs, _(" Package %s is to be removed.\n"),
398 : : pkg_name(possdependee, pnaw_nonambig));
399 : : }
400 : :
401 : 0 : *matched = true;
402 : 0 : debug(dbg_depcondetail," removing possdependee, returning %d",thisf);
403 : 0 : return thisf;
404 : : }
405 [ # # ]: 0 : switch (possdependee->status) {
406 : 0 : case PKG_STAT_UNPACKED:
407 : : case PKG_STAT_HALFCONFIGURED:
408 : : case PKG_STAT_TRIGGERSAWAITED:
409 : : case PKG_STAT_TRIGGERSPENDING:
410 : : case PKG_STAT_INSTALLED:
411 [ # # ]: 0 : if (checkversion) {
412 [ # # ]: 0 : if (provider) {
413 : 0 : debug(dbg_depcondetail, " checking package %s provided by pkg %s",
414 : 0 : checkversion->ed->name, pkg_name(possdependee, pnaw_always));
415 [ # # ]: 0 : if (!pkg_virtual_deppossi_satisfied(checkversion, provider)) {
416 : 0 : varbuf_printf(oemsgs,
417 : 0 : _(" Version of %s on system, provided by %s, is %s.\n"),
418 : 0 : checkversion->ed->name,
419 : : pkg_name(possdependee, pnaw_always),
420 : 0 : versiondescribe(&provider->version, vdew_nonambig));
421 [ # # ]: 0 : if (in_force(FORCE_DEPENDS_VERSION))
422 : 0 : thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION);
423 : 0 : debug(dbg_depcondetail, " bad version");
424 : 0 : goto unsuitable;
425 : : }
426 : : } else {
427 : 0 : debug(dbg_depcondetail, " checking non-provided pkg %s",
428 : : pkg_name(possdependee, pnaw_always));
429 [ # # ]: 0 : if (!versionsatisfied(&possdependee->installed, checkversion)) {
430 : 0 : varbuf_printf(oemsgs, _(" Version of %s on system is %s.\n"),
431 : : pkg_name(possdependee, pnaw_nonambig),
432 : 0 : versiondescribe(&possdependee->installed.version,
433 : : vdew_nonambig));
434 [ # # ]: 0 : if (in_force(FORCE_DEPENDS_VERSION))
435 : 0 : thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION);
436 : 0 : debug(dbg_depcondetail, " bad version");
437 : 0 : goto unsuitable;
438 : : }
439 : : }
440 : : }
441 [ # # ]: 0 : if (possdependee->status == PKG_STAT_INSTALLED ||
442 [ # # ]: 0 : possdependee->status == PKG_STAT_TRIGGERSPENDING) {
443 : 0 : debug(dbg_depcondetail," is installed, ok and found");
444 : 0 : return FOUND_OK;
445 : : }
446 [ # # ]: 0 : if (possdependee->status == PKG_STAT_TRIGGERSAWAITED) {
447 [ # # ]: 0 : if (possdependee->trigaw.head == NULL)
448 : 0 : internerr("package %s in state %s, has no awaited triggers",
449 : : pkg_name(possdependee, pnaw_always),
450 : : pkg_status_name(possdependee));
451 : :
452 [ # # ]: 0 : if (removing ||
453 [ # # ]: 0 : !(f_triggers ||
454 [ # # ]: 0 : (possdependee->clientdata &&
455 [ # # ]: 0 : possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW))) {
456 [ # # ]: 0 : if (provider) {
457 : 0 : varbuf_printf(oemsgs,
458 : 0 : _(" Package %s which provides %s awaits trigger processing.\n"),
459 : : pkg_name(possdependee, pnaw_nonambig),
460 : 0 : provider->ed->name);
461 : : } else {
462 : 0 : varbuf_printf(oemsgs,
463 : 0 : _(" Package %s awaits trigger processing.\n"),
464 : : pkg_name(possdependee, pnaw_nonambig));
465 : : }
466 : 0 : debug(dbg_depcondetail, " triggers-awaited, no fixbytrig");
467 : 0 : goto unsuitable;
468 : : }
469 : : /* We don't check the status of trigaw.head->pend here, just in case
470 : : * we get into the pathological situation where Triggers-Awaited but
471 : : * the named package doesn't actually have any pending triggers. In
472 : : * that case we queue the non-pending package for trigger processing
473 : : * anyway, and that trigger processing will be a noop except for
474 : : * sorting out all of the packages which name it in Triggers-Awaited.
475 : : *
476 : : * (This situation can only arise if modstatdb_note success in
477 : : * clearing the triggers-pending status of the pending package
478 : : * but then fails to go on to update the awaiters.) */
479 : 0 : *fixbytrig = possdependee->trigaw.head->pend;
480 : 0 : debug(dbg_depcondetail,
481 : : " triggers-awaited, fixbytrig '%s', defer",
482 : : pkg_name(*fixbytrig, pnaw_always));
483 : 0 : return FOUND_DEFER;
484 : : }
485 [ # # ]: 0 : if (possdependee->clientdata &&
486 [ # # ]: 0 : possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) {
487 : 0 : debug(dbg_depcondetail," unpacked/halfconfigured, defer");
488 : 0 : return FOUND_DEFER;
489 [ # # # # ]: 0 : } else if (!removing && in_force(FORCE_CONFIGURE_ANY) &&
490 [ # # ]: 0 : !skip_due_to_hold(possdependee) &&
491 [ # # ]: 0 : !(possdependee->status == PKG_STAT_HALFCONFIGURED)) {
492 : 0 : notice(_("also configuring '%s' (required by '%s')"),
493 : : pkg_name(possdependee, pnaw_nonambig),
494 : : pkg_name(requiredby, pnaw_nonambig));
495 : 0 : enqueue_package(possdependee);
496 : 0 : sincenothing = 0;
497 : 0 : return FOUND_DEFER;
498 : : } else {
499 [ # # ]: 0 : if (provider) {
500 : 0 : varbuf_printf(oemsgs,
501 : 0 : _(" Package %s which provides %s is not configured yet.\n"),
502 : : pkg_name(possdependee, pnaw_nonambig),
503 : 0 : provider->ed->name);
504 : : } else {
505 : 0 : varbuf_printf(oemsgs, _(" Package %s is not configured yet.\n"),
506 : : pkg_name(possdependee, pnaw_nonambig));
507 : : }
508 : :
509 : 0 : debug(dbg_depcondetail, " not configured/able");
510 : 0 : goto unsuitable;
511 : : }
512 : :
513 : 0 : default:
514 [ # # ]: 0 : if (provider) {
515 : 0 : varbuf_printf(oemsgs,
516 : 0 : _(" Package %s which provides %s is not installed.\n"),
517 : : pkg_name(possdependee, pnaw_nonambig),
518 : 0 : provider->ed->name);
519 : : } else {
520 : 0 : varbuf_printf(oemsgs, _(" Package %s is not installed.\n"),
521 : : pkg_name(possdependee, pnaw_nonambig));
522 : : }
523 : :
524 : 0 : debug(dbg_depcondetail, " not installed");
525 : 0 : goto unsuitable;
526 : : }
527 : :
528 : 0 : unsuitable:
529 : 0 : debug(dbg_depcondetail, " returning %d", thisf);
530 : 0 : (*interestingwarnings)++;
531 : :
532 : 0 : return thisf;
533 : : }
534 : :
535 : : static void
536 : 0 : breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok,
537 : : struct deppossi *breaks, struct pkginfo *broken,
538 : : struct pkginfo *breaker, struct deppossi *virtbroken)
539 : : {
540 : 0 : struct varbuf depmsg = VARBUF_INIT;
541 : :
542 [ # # ]: 0 : debug(dbg_depcondetail, " checking breaker %s virtbroken %s",
543 : : pkg_name(breaker, pnaw_always),
544 : 0 : virtbroken ? virtbroken->ed->name : "<none>");
545 : :
546 [ # # ]: 0 : if (breaker->status == PKG_STAT_NOTINSTALLED ||
547 [ # # ]: 0 : breaker->status == PKG_STAT_CONFIGFILES)
548 : 0 : return;
549 [ # # ]: 0 : if (broken == breaker) return;
550 [ # # ]: 0 : if (!versionsatisfied(&broken->installed, breaks)) return;
551 : : /* The test below can only trigger if dep_breaks start having
552 : : * arch qualifiers different from “any”. */
553 [ # # ]: 0 : if (!archsatisfied(&broken->installed, breaks))
554 : 0 : return;
555 [ # # ]: 0 : if (ignore_depends(breaker)) return;
556 [ # # # # ]: 0 : if (virtbroken && ignore_depends(&virtbroken->ed->pkg))
557 : 0 : return;
558 [ # # # # ]: 0 : if (virtbroken && !pkg_virtual_deppossi_satisfied(breaks, virtbroken))
559 : 0 : return;
560 : :
561 : 0 : varbufdependency(&depmsg, breaks->up);
562 : 0 : varbuf_end_str(&depmsg);
563 : 0 : varbuf_printf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"),
564 : : pkg_name(breaker, pnaw_nonambig),
565 : 0 : versiondescribe(&breaker->installed.version, vdew_nonambig),
566 : 0 : depmsg.buf, gettext(statusstrings[breaker->status]));
567 : 0 : varbuf_destroy(&depmsg);
568 : :
569 [ # # ]: 0 : if (virtbroken) {
570 : 0 : varbuf_printf(aemsgs, _(" %s (%s) provides %s.\n"),
571 : : pkg_name(broken, pnaw_nonambig),
572 : 0 : versiondescribe(&broken->installed.version, vdew_nonambig),
573 : 0 : virtbroken->ed->name);
574 [ # # ]: 0 : } else if (breaks->verrel != DPKG_RELATION_NONE) {
575 : 0 : varbuf_printf(aemsgs, _(" Version of %s to be configured is %s.\n"),
576 : : pkg_name(broken, pnaw_nonambig),
577 : 0 : versiondescribe(&broken->installed.version, vdew_nonambig));
578 [ # # ]: 0 : if (in_force(FORCE_DEPENDS_VERSION))
579 : 0 : return;
580 : : }
581 [ # # ]: 0 : if (force_breaks(breaks)) return;
582 : 0 : *ok = DEP_CHECK_HALT;
583 : : }
584 : :
585 : : static void
586 : 0 : breaks_check_target(struct varbuf *aemsgs, enum dep_check *ok,
587 : : struct pkginfo *broken, struct pkgset *target,
588 : : struct deppossi *virtbroken)
589 : : {
590 : : struct deppossi *possi;
591 : :
592 [ # # ]: 0 : for (possi = target->depended.installed; possi; possi = possi->rev_next) {
593 [ # # ]: 0 : if (possi->up->type != dep_breaks) continue;
594 : 0 : breaks_check_one(aemsgs, ok, possi, broken, possi->up->up, virtbroken);
595 : : }
596 : 0 : }
597 : :
598 : : enum dep_check
599 : 0 : breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs)
600 : : {
601 : : struct dependency *dep;
602 : : struct deppossi *virtbroken;
603 : 0 : enum dep_check ok = DEP_CHECK_OK;
604 : :
605 : 0 : debug(dbg_depcon, " checking Breaks");
606 : :
607 : 0 : breaks_check_target(aemsgs, &ok, pkg, pkg->set, NULL);
608 : :
609 [ # # ]: 0 : for (dep= pkg->installed.depends; dep; dep= dep->next) {
610 [ # # ]: 0 : if (dep->type != dep_provides) continue;
611 : 0 : virtbroken = dep->list;
612 : 0 : debug(dbg_depcondetail, " checking virtbroken %s", virtbroken->ed->name);
613 : 0 : breaks_check_target(aemsgs, &ok, pkg, virtbroken->ed, virtbroken);
614 : : }
615 : 0 : return ok;
616 : : }
617 : :
618 : : /*
619 : : * Checks [Pre]-Depends only.
620 : : */
621 : : enum dep_check
622 : 0 : dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
623 : : struct varbuf *aemsgs)
624 : : {
625 : : /* Valid values: 2 = ok, 1 = defer, 0 = halt. */
626 : : enum dep_check ok;
627 : : /* Valid values: 0 = none, 1 = defer, 2 = withwarning, 3 = ok. */
628 : : enum found_status found, thisf;
629 : : int interestingwarnings;
630 : : bool matched, anycannotfixbytrig;
631 : 0 : struct varbuf oemsgs = VARBUF_INIT;
632 : : struct dependency *dep;
633 : : struct deppossi *possi, *provider;
634 : : struct pkginfo *possfixbytrig, *canfixbytrig;
635 : :
636 : 0 : ok = DEP_CHECK_OK;
637 [ # # ]: 0 : debug(dbg_depcon,"checking dependencies of %s (- %s)",
638 : : pkg_name(pkg, pnaw_always),
639 : 0 : removing ? pkg_name(removing, pnaw_always) : "<none>");
640 : :
641 : 0 : anycannotfixbytrig = false;
642 : 0 : canfixbytrig = NULL;
643 [ # # ]: 0 : for (dep= pkg->installed.depends; dep; dep= dep->next) {
644 [ # # # # ]: 0 : if (dep->type != dep_depends && dep->type != dep_predepends) continue;
645 : 0 : debug(dbg_depcondetail," checking group ...");
646 : 0 : matched = false;
647 : 0 : interestingwarnings = 0;
648 : 0 : varbuf_reset(&oemsgs);
649 : 0 : found = FOUND_NONE;
650 : 0 : possfixbytrig = NULL;
651 [ # # # # ]: 0 : for (possi = dep->list; found != FOUND_OK && possi; possi = possi->next) {
652 : : struct deppossi_pkg_iterator *possi_iter;
653 : : struct pkginfo *pkg_pos;
654 : :
655 : 0 : debug(dbg_depcondetail," checking possibility -> %s",possi->ed->name);
656 [ # # ]: 0 : if (possi->cyclebreak) {
657 : 0 : debug(dbg_depcondetail," break cycle so ok and found");
658 : 0 : found = FOUND_OK;
659 : 0 : break;
660 : : }
661 : :
662 : 0 : thisf = FOUND_NONE;
663 : 0 : possi_iter = deppossi_pkg_iter_new(possi, wpb_installed);
664 [ # # ]: 0 : while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) {
665 : 0 : thisf = deppossi_ok_found(pkg_pos, pkg, removing, NULL,
666 : : &possfixbytrig, &matched, possi,
667 : : &interestingwarnings, &oemsgs);
668 [ # # ]: 0 : if (thisf > found)
669 : 0 : found = thisf;
670 [ # # ]: 0 : if (found == FOUND_OK)
671 : 0 : break;
672 : : }
673 : 0 : deppossi_pkg_iter_free(possi_iter);
674 : :
675 [ # # ]: 0 : if (found != FOUND_OK) {
676 : 0 : for (provider = possi->ed->depended.installed;
677 [ # # # # ]: 0 : found != FOUND_OK && provider;
678 : 0 : provider = provider->rev_next) {
679 [ # # ]: 0 : if (provider->up->type != dep_provides)
680 : 0 : continue;
681 : 0 : debug(dbg_depcondetail, " checking provider %s",
682 : 0 : pkg_name(provider->up->up, pnaw_always));
683 [ # # ]: 0 : if (!deparchsatisfied(&provider->up->up->installed, provider->arch,
684 : : possi)) {
685 : 0 : debug(dbg_depcondetail, " provider does not satisfy arch");
686 : 0 : continue;
687 : : }
688 : 0 : thisf = deppossi_ok_found(provider->up->up, pkg, removing, provider,
689 : : &possfixbytrig, &matched, possi,
690 : : &interestingwarnings, &oemsgs);
691 [ # # # # : 0 : if (thisf == FOUND_DEFER && provider->up->up == pkg && !removing) {
# # ]
692 : : /* IOW, if the pkg satisfies its own dep (via a provide), then
693 : : * we let it pass, even if it isn't configured yet (as we're
694 : : * installing it). */
695 : 0 : thisf = FOUND_OK;
696 : : }
697 [ # # ]: 0 : if (thisf > found)
698 : 0 : found = thisf;
699 : : }
700 : : }
701 : 0 : debug(dbg_depcondetail," found %d",found);
702 [ # # ]: 0 : if (thisf > found) found= thisf;
703 : : }
704 [ # # ]: 0 : if (in_force(FORCE_DEPENDS)) {
705 : 0 : thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS);
706 [ # # ]: 0 : if (thisf > found) {
707 : 0 : found = thisf;
708 : 0 : debug(dbg_depcondetail, " rescued by force-depends, found %d", found);
709 : : }
710 : : }
711 : 0 : debug(dbg_depcondetail, " found %d matched %d possfixbytrig %s",
712 : : found, matched,
713 [ # # ]: 0 : possfixbytrig ? pkg_name(possfixbytrig, pnaw_always) : "-");
714 [ # # # # ]: 0 : if (removing && !matched) continue;
715 [ # # # # : 0 : switch (found) {
# ]
716 : 0 : case FOUND_NONE:
717 : 0 : anycannotfixbytrig = true;
718 : 0 : ok = DEP_CHECK_HALT;
719 : : /* Fall through. */
720 : 0 : case FOUND_FORCED:
721 : 0 : varbuf_add_str(aemsgs, " ");
722 : 0 : varbuf_add_pkgbin_name(aemsgs, pkg, &pkg->installed, pnaw_nonambig);
723 : 0 : varbuf_add_str(aemsgs, _(" depends on "));
724 : 0 : varbufdependency(aemsgs, dep);
725 [ # # ]: 0 : if (interestingwarnings) {
726 : : /* Don't print the line about the package to be removed if
727 : : * that's the only line. */
728 : 0 : varbuf_end_str(&oemsgs);
729 : 0 : varbuf_add_str(aemsgs, _("; however:\n"));
730 : 0 : varbuf_add_str(aemsgs, oemsgs.buf);
731 : : } else {
732 : 0 : varbuf_add_str(aemsgs, ".\n");
733 : : }
734 : 0 : break;
735 : 0 : case FOUND_DEFER:
736 [ # # ]: 0 : if (possfixbytrig)
737 : 0 : canfixbytrig = possfixbytrig;
738 : : else
739 : 0 : anycannotfixbytrig = true;
740 [ # # ]: 0 : if (ok > DEP_CHECK_DEFER)
741 : 0 : ok = DEP_CHECK_DEFER;
742 : 0 : break;
743 : 0 : case FOUND_OK:
744 : 0 : break;
745 : 0 : default:
746 : 0 : internerr("unknown value for found '%d'", found);
747 : : }
748 : : }
749 [ # # ]: 0 : if (ok == DEP_CHECK_HALT &&
750 [ # # # # ]: 0 : (pkg->clientdata && pkg->clientdata->istobe == PKG_ISTOBE_REMOVE))
751 : 0 : ok = DEP_CHECK_DEFER;
752 [ # # # # ]: 0 : if (!anycannotfixbytrig && canfixbytrig)
753 : 0 : progress_bytrigproc = canfixbytrig;
754 : :
755 : 0 : varbuf_destroy(&oemsgs);
756 : 0 : debug(dbg_depcon,"ok %d msgs >>%.*s<<", ok, (int)aemsgs->used, aemsgs->buf);
757 : 0 : return ok;
758 : : }
|