From 794cf3ac59deb28b30f63aeb26f58726595cd885 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 26 Apr 2021 19:16:19 +0100 Subject: [PATCH] auc: compare versions using dpkg/opkg's verrevcmp Using strcmp() to compare a version string doesn't work well. Use verrevcmp() function from opkg instead. Signed-off-by: Daniel Golle --- utils/auc/src/CMakeLists.txt | 2 +- utils/auc/src/auc.c | 55 +++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/utils/auc/src/CMakeLists.txt b/utils/auc/src/CMakeLists.txt index de6cee833..14cc199ce 100644 --- a/utils/auc/src/CMakeLists.txt +++ b/utils/auc/src/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.6...3.12) PROJECT(auc C) ADD_DEFINITIONS(-Os -ggdb -Wall --std=gnu99 -Wmissing-declarations) diff --git a/utils/auc/src/auc.c b/utils/auc/src/auc.c index d3162066a..5836875a3 100644 --- a/utils/auc/src/auc.c +++ b/utils/auc/src/auc.c @@ -17,6 +17,7 @@ #define AUC_VERSION "unknown" #endif +#include #include #include #include @@ -359,6 +360,58 @@ static int load_config() { return 0; } +/* + * libdpkg - Debian packaging suite library routines + * vercmp.c - comparison of version numbers + * + * Copyright (C) 1995 Ian Jackson + */ + +/* assume ascii; warning: evaluates x multiple times! */ +#define order(x) ((x) == '~' ? -1 \ + : isdigit((x)) ? 0 \ + : !(x) ? 0 \ + : isalpha((x)) ? (x) \ + : (x) + 256) + +static int verrevcmp(const char *val, const char *ref) +{ + if (!val) + val = ""; + if (!ref) + ref = ""; + + while (*val || *ref) { + int first_diff = 0; + + while ((*val && !isdigit(*val)) || (*ref && !isdigit(*ref))) { + int vc = order(*val), rc = order(*ref); + if (vc != rc) + return vc - rc; + val++; + ref++; + } + + while (*val == '0') + val++; + while (*ref == '0') + ref++; + while (isdigit(*val) && isdigit(*ref)) { + if (!first_diff) + first_diff = *val - *ref; + val++; + ref++; + } + if (isdigit(*val)) + return 1; + if (isdigit(*ref)) + return -1; + if (first_diff) + return first_diff; + } + return 0; +} + /** * UBUS response callbacks @@ -409,7 +462,7 @@ static void pkglist_check_cb(struct ubus_request *req, int type, struct blob_att continue; } - cmpres = strcmp(blobmsg_get_string(cur), pkg->version); + cmpres = verrevcmp(blobmsg_get_string(cur), pkg->version); if (cmpres < 0) *status |= PKG_UPGRADE;