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 <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle 2021-04-26 19:16:19 +01:00
parent 9996328abd
commit 794cf3ac59
No known key found for this signature in database
GPG Key ID: 5A8F39C31C3217CA
2 changed files with 55 additions and 2 deletions

View File

@ -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)

View File

@ -17,6 +17,7 @@
#define AUC_VERSION "unknown"
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <dlfcn.h>
@ -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 <iwj10@cus.cam.ac.uk>
*/
/* 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;