From 14d099181cc5006fab24982c450cbca1025796ad Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 May 2008 08:13:39 +0000 Subject: [PATCH] Allow for engine version lines with a suffix. --- gpgme/ChangeLog | 6 +++++ gpgme/version.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index e5b441b0..23b5c5d2 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,9 @@ +2008-05-06 Werner Koch + + * version.c (extract_version_string): New. + (_gpgme_get_program_version): Use it to allow for suffixes in the + version line. + 2008-04-28 Werner Koch * engine-gpgconf.c (gpgconf_read): Fixed segv. Avoid memmove for diff --git a/gpgme/version.c b/gpgme/version.c index f010249d..457945a6 100644 --- a/gpgme/version.c +++ b/gpgme/version.c @@ -1,6 +1,6 @@ /* version.c - Version check routines. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 g10 Code GmbH This file is part of GPGME. @@ -187,6 +187,55 @@ gpgme_check_version (const char *req_version) #define LINELENGTH 80 +/* Extract the version string of a program from STRING. The version + number is expected to be in GNU style format: + + foo 1.2.3 + foo (bar system) 1.2.3 + foo 1.2.3 cruft + foo (bar system) 1.2.3 cruft. + + Spaces and tabs are skipped and used as delimiters, a term in + (nested) parenthesis before the version string is skipped, the + version string may consist of any non-space and non-tab characters + but needs to bstart with a digit. +*/ +static const char * +extract_version_string (const char *string, size_t *r_len) +{ + const char *s; + int count, len; + + for (s=string; *s; s++) + if (*s == ' ' || *s == '\t') + break; + while (*s == ' ' || *s == '\t') + s++; + if (*s == '(') + { + for (count=1, s++; count && *s; s++) + if (*s == '(') + count++; + else if (*s == ')') + count--; + } + /* For robustness we look for a digit. */ + while ( *s && !(*s >= '0' && *s <= '9') ) + s++; + if (*s >= '0' && *s <= '9') + { + for (len=0; s[len]; len++) + if (s[len] == ' ' || s[len] == '\t') + break; + } + else + len = 0; + + *r_len = len; + return s; +} + + /* Retrieve the version number from the --version output of the program FILE_NAME. */ char * @@ -243,10 +292,18 @@ _gpgme_get_program_version (const char *const file_name) if (mark) { - mark = strrchr (line, ' '); + size_t len; + const char *s; + + s = extract_version_string (line, &len); + if (!len) + return NULL; + mark = malloc (len + 1); if (!mark) return NULL; - return strdup (mark + 1); + memcpy (mark, s, len); + mark[len] = 0; + return mark; } return NULL;