Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- The vercmp logic is relatively complicated, so shelling out to the official vercmp binary is much simpler, and will be available on any system with pacman installed. conf/config.proto | 1 + web/lib/pkgfuncs.inc.php | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/conf/config.proto b/conf/config.proto index c56141c..37c455e 100644 --- a/conf/config.proto +++ b/conf/config.proto @@ -31,6 +31,7 @@ log_uri = https://aur.archlinux.org/cgit/aur.git/log/?h=%s snapshot_uri = /cgit/aur.git/snapshot/%s.tar.gz enable-maintenance = 1 maintenance-exceptions = 127.0.0.1 +vercmp-cmd = /usr/bin/vercmp [notifications] notify-cmd = /srv/http/aurweb/scripts/notify.py diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 4b0fdba..a697e69 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -204,14 +204,14 @@ function pkg_groups($pkgid) { */ function pkg_providers($name) { $dbh = DB::connect(); - $q = "SELECT p.ID, p.Name FROM Packages p "; + $q = "SELECT p.ID, p.Name, p.Version FROM Packages p "; $q.= "LEFT JOIN PackageRelations pr ON pr.PackageID = p.ID "; $q.= "LEFT JOIN RelationTypes rt ON rt.ID = pr.RelTypeID "; $q.= "WHERE p.Name = " . $dbh->quote($name) . " "; $q.= "OR (rt.Name = 'provides' "; $q.= "AND pr.RelName = " . $dbh->quote($name) . ")"; $q.= "UNION "; - $q.= "SELECT 0, Name FROM OfficialProviders "; + $q.= "SELECT 0, Name, 0 FROM OfficialProviders "; $q.= "WHERE Provides = " . $dbh->quote($name); $result = $dbh->query($q); @@ -349,6 +349,33 @@ function pkg_provider_link($name, $official) { return $link; } +function cmp_provider_ver($version, $cond) { + if (!$cond) { + return True; + } + + $condition = preg_split("/^([<=>]{0,2})/", $cond, -1, PREG_SPLIT_DELIM_CAPTURE); + + $cmd = config_get('options', 'vercmp-cmd'); + $cmd .= ' ' . escapeshellarg($version) . ' ' . escapeshellarg($condition[2]); + $handle = popen($cmd, 'r'); + $result = fread($handle, 2); + pclose($handle); + + switch ($condition[1]) { + case ">=": + return $result >= 0; + case "<=": + return $result <= 0; + case ">": + return $result > 0; + case "<": + return $result < 0; + case "==": + return $result == 0; + } +} + /** * Get the HTML code to display a package dependency link * @@ -407,6 +434,11 @@ function pkg_depend_link($name, $type, $cond, $arch, $pkg_id) { if (count($providers) > 0) { $link .= '<span class="virtual-dep">('; foreach ($providers as $provider) { + $version = $provider[2]; + if (!cmp_provider_ver($version, $cond)) { + break; + } + $is_official = ($provider[0] == 0); $name = $provider[1]; $link .= pkg_provider_link($name, $is_official) . ', '; -- 2.10.0