aboutsummaryrefslogtreecommitdiffstats
path: root/src/assuan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/assuan.c')
-rw-r--r--src/assuan.c95
1 files changed, 93 insertions, 2 deletions
diff --git a/src/assuan.c b/src/assuan.c
index b9d3143..5cbb86c 100644
--- a/src/assuan.c
+++ b/src/assuan.c
@@ -1,5 +1,6 @@
/* assuan.c - Global interface (not specific to context).
Copyright (C) 2009 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2012, 2013 g10 Code GmbH
This file is part of Assuan.
@@ -26,7 +27,11 @@
#include "assuan-defs.h"
#include "debug.h"
-
+
+
+#define digitp(a) ((a) >= '0' && (a) <= '9')
+
+
/* Global default state. */
@@ -154,7 +159,7 @@ assuan_new (assuan_context_t *r_ctx)
{
return assuan_new_ext (r_ctx, _assuan_default_err_source,
&_assuan_default_malloc_hooks,
- _assuan_default_log_cb,
+ _assuan_default_log_cb,
_assuan_default_log_cb_data);
}
@@ -187,3 +192,89 @@ assuan_release (assuan_context_t ctx)
deallocation. */
_assuan_free (ctx, ctx);
}
+
+
+
+/*
+ Version number stuff.
+ */
+
+static const char*
+parse_version_number (const char *s, int *number)
+{
+ int val = 0;
+
+ if (*s == '0' && digitp (s[1]))
+ return NULL; /* Leading zeros are not allowed. */
+ for (; digitp (*s); s++)
+ {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0 ? NULL : s;
+}
+
+
+static const char *
+parse_version_string (const char *s, int *major, int *minor, int *micro)
+{
+ s = parse_version_number (s, major);
+ if (!s || *s != '.')
+ return NULL;
+ s++;
+ s = parse_version_number (s, minor);
+ if (!s || *s != '.')
+ return NULL;
+ s++;
+ s = parse_version_number (s, micro);
+ if (!s)
+ return NULL;
+ return s; /* Patchlevel. */
+}
+
+
+static const char *
+compare_versions (const char *my_version, const char *req_version)
+{
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if (!req_version)
+ return my_version;
+ if (!my_version)
+ return NULL;
+
+ my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+ if (!my_plvl)
+ return NULL; /* Very strange: our own version is bogus. */
+ rq_plvl = parse_version_string(req_version,
+ &rq_major, &rq_minor, &rq_micro);
+ if (!rq_plvl)
+ return NULL; /* Requested version string is invalid. */
+
+ if (my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro))
+ {
+ return my_version;
+ }
+ return NULL;
+}
+
+
+/*
+ * Check that the the version of the library is at minimum REQ_VERSION
+ * and return the actual version string; return NULL if the condition
+ * is not met. If NULL is passed to this function, no check is done
+ * and the version string is simply returned.
+ */
+const char *
+assuan_check_version (const char *req_version)
+{
+ return compare_versions (PACKAGE_VERSION, req_version);
+}