/* * libdpkg - Debian packaging suite library routines * depcon.c - dependency and conflict checking * * Copyright © 1995 Ian Jackson * Copyright © 2008-2014 Guillem Jover * Copyright © 2009 Canonical Ltd. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include bool versionsatisfied(struct pkgbin *it, struct deppossi *against) { return dpkg_version_relate(&it->version, against->verrel, &against->version); } /** * Check if the architecture qualifier in the dependency is satisfied. * * The rules are supposed to be: * - unqualified Depends/Pre-Depends/Recommends/Suggests are only * satisfied by a package of a different architecture if the target * package is Multi-Arch: foreign. * - Depends/Pre-Depends/Recommends/Suggests on pkg:any are satisfied by * a package of a different architecture if the target package is * Multi-Arch: allowed. * - all other Depends/Pre-Depends/Recommends/Suggests are only * satisfied by packages of the same architecture. * - Architecture: all packages are treated the same as packages of the * native architecture. * - Conflicts/Replaces/Breaks are assumed to apply to packages of any arch. */ bool deparchsatisfied(struct pkgbin *it, const struct dpkg_arch *it_arch, struct deppossi *against) { const struct dpkg_arch *dep_arch, *pkg_arch; if (against->arch_is_implicit && it->multiarch == PKG_MULTIARCH_FOREIGN) return true; dep_arch = against->arch; if (dep_arch->type == DPKG_ARCH_WILDCARD && (it->multiarch == PKG_MULTIARCH_ALLOWED || against->up->type == dep_conflicts || against->up->type == dep_replaces || against->up->type == dep_breaks)) return true; pkg_arch = it_arch; if (dep_arch->type == DPKG_ARCH_NONE || dep_arch->type == DPKG_ARCH_ALL) dep_arch = dpkg_arch_get(DPKG_ARCH_NATIVE); if (pkg_arch->type == DPKG_ARCH_NONE || pkg_arch->type == DPKG_ARCH_ALL) pkg_arch = dpkg_arch_get(DPKG_ARCH_NATIVE); return (dep_arch == pkg_arch); } bool archsatisfied(struct pkgbin *it, struct deppossi *against) { return deparchsatisfied(it, it->arch, against); } /** * Check if the dependency is satisfied by a virtual package. * * For versioned depends, we only check providers with #DPKG_RELATION_EQ. It * does not make sense to check ones without a version since we have nothing * to verify against. Also, it is way too complex to allow anything but an * equal in a provided version. A few examples below to deter you from trying: * * - pkg1 depends on virt (>= 0.6), pkg2 provides virt (<= 1.0). * Should pass (easy enough). * * - pkg1 depends on virt (>= 0.7) and (<= 1.1), pkg2 provides virt (>= 1.2). * Should fail (little harder). * * - pkg1 depends on virt (>= 0.4), pkg2 provides virt (<= 1.0) and (>= 0.5), * IOW, inclusive of only those versions. This would require backchecking * the other provided versions in the possi, which would make things sickly * complex and overly time consuming. Should fail (very hard to implement). * * This could be handled by switching to a SAT solver, but that would imply * lots of work for very little gain. Packages can easily get around most of * these by providing multiple #DPKG_RELATION_EQ versions. */ bool pkg_virtual_deppossi_satisfied(struct deppossi *dependee, struct deppossi *provider) { if (provider->verrel != DPKG_RELATION_NONE && provider->verrel != DPKG_RELATION_EQ) return false; if (provider->verrel == DPKG_RELATION_NONE && dependee->verrel != DPKG_RELATION_NONE) return false; return dpkg_version_relate(&provider->version, dependee->verrel, &dependee->version); }