dpkg (1.18.25) stretch; urgency=medium
[dpkg] / lib / dpkg / depcon.c
CommitLineData
1479465f
GJ
1/*
2 * libdpkg - Debian packaging suite library routines
3 * depcon.c - dependency and conflict checking
4 *
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
7 * Copyright © 2009 Canonical Ltd.
8 *
9 * This is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include <config.h>
24#include <compat.h>
25
26#include <dpkg/dpkg.h>
27#include <dpkg/dpkg-db.h>
28#include <dpkg/arch.h>
29
30bool
31versionsatisfied(struct pkgbin *it, struct deppossi *against)
32{
33 return dpkg_version_relate(&it->version,
34 against->verrel,
35 &against->version);
36}
37
38/**
39 * Check if the architecture qualifier in the dependency is satisfied.
40 *
41 * The rules are supposed to be:
42 * - unqualified Depends/Pre-Depends/Recommends/Suggests are only
43 * satisfied by a package of a different architecture if the target
44 * package is Multi-Arch: foreign.
45 * - Depends/Pre-Depends/Recommends/Suggests on pkg:any are satisfied by
46 * a package of a different architecture if the target package is
47 * Multi-Arch: allowed.
48 * - all other Depends/Pre-Depends/Recommends/Suggests are only
49 * satisfied by packages of the same architecture.
50 * - Architecture: all packages are treated the same as packages of the
51 * native architecture.
52 * - Conflicts/Replaces/Breaks are assumed to apply to packages of any arch.
53 */
54bool
55deparchsatisfied(struct pkgbin *it, const struct dpkg_arch *it_arch,
56 struct deppossi *against)
57{
58 const struct dpkg_arch *dep_arch, *pkg_arch;
59
60 if (against->arch_is_implicit &&
61 it->multiarch == PKG_MULTIARCH_FOREIGN)
62 return true;
63
64 dep_arch = against->arch;
65 if (dep_arch->type == DPKG_ARCH_WILDCARD &&
66 (it->multiarch == PKG_MULTIARCH_ALLOWED ||
67 against->up->type == dep_conflicts ||
68 against->up->type == dep_replaces ||
69 against->up->type == dep_breaks))
70 return true;
71
72 pkg_arch = it_arch;
73 if (dep_arch->type == DPKG_ARCH_NONE || dep_arch->type == DPKG_ARCH_ALL)
74 dep_arch = dpkg_arch_get(DPKG_ARCH_NATIVE);
75 if (pkg_arch->type == DPKG_ARCH_NONE || pkg_arch->type == DPKG_ARCH_ALL)
76 pkg_arch = dpkg_arch_get(DPKG_ARCH_NATIVE);
77
78 return (dep_arch == pkg_arch);
79}
80
81bool
82archsatisfied(struct pkgbin *it, struct deppossi *against)
83{
84 return deparchsatisfied(it, it->arch, against);
85}
86
87/**
88 * Check if the dependency is satisfied by a virtual package.
89 *
90 * For versioned depends, we only check providers with #DPKG_RELATION_EQ. It
91 * does not make sense to check ones without a version since we have nothing
92 * to verify against. Also, it is way too complex to allow anything but an
93 * equal in a provided version. A few examples below to deter you from trying:
94 *
95 * - pkg1 depends on virt (>= 0.6), pkg2 provides virt (<= 1.0).
96 * Should pass (easy enough).
97 *
98 * - pkg1 depends on virt (>= 0.7) and (<= 1.1), pkg2 provides virt (>= 1.2).
99 * Should fail (little harder).
100 *
101 * - pkg1 depends on virt (>= 0.4), pkg2 provides virt (<= 1.0) and (>= 0.5),
102 * IOW, inclusive of only those versions. This would require backchecking
103 * the other provided versions in the possi, which would make things sickly
104 * complex and overly time consuming. Should fail (very hard to implement).
105 *
106 * This could be handled by switching to a SAT solver, but that would imply
107 * lots of work for very little gain. Packages can easily get around most of
108 * these by providing multiple #DPKG_RELATION_EQ versions.
109 */
110bool
111pkg_virtual_deppossi_satisfied(struct deppossi *dependee,
112 struct deppossi *provider)
113{
114 if (provider->verrel != DPKG_RELATION_NONE &&
115 provider->verrel != DPKG_RELATION_EQ)
116 return false;
117
118 if (provider->verrel == DPKG_RELATION_NONE &&
119 dependee->verrel != DPKG_RELATION_NONE)
120 return false;
121
122 return dpkg_version_relate(&provider->version,
123 dependee->verrel,
124 &dependee->version);
125}