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 
30 bool
versionsatisfied(struct pkgbin * it,struct deppossi * against)31 versionsatisfied(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  */
54 bool
deparchsatisfied(struct pkgbin * it,const struct dpkg_arch * it_arch,struct deppossi * against)55 deparchsatisfied(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 
81 bool
archsatisfied(struct pkgbin * it,struct deppossi * against)82 archsatisfied(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  */
110 bool
pkg_virtual_deppossi_satisfied(struct deppossi * dependee,struct deppossi * provider)111 pkg_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 }
126