diff options
author | Werner Koch <[email protected]> | 2013-02-22 18:34:25 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2013-02-22 18:34:25 +0000 |
commit | ab2e01598446120dac09e49c63a5c8fc27a1bc32 (patch) | |
tree | 8f4754f75299d38a2b2f7b2cfc4d85c20b5205b6 | |
parent | w32: Fix header inclusion order for newer toolchain. (diff) | |
download | libassuan-ab2e01598446120dac09e49c63a5c8fc27a1bc32.tar.gz libassuan-ab2e01598446120dac09e49c63a5c8fc27a1bc32.zip |
Add assuan_check_version and ASSUAN_VERSION_NUMBER.
* src/assuan.c (assuan_check_version): New.
(digitp, parse_version_number, parse_version_string)
(compare_versions): New. Taken from libksba.
* configure.ac (VERSION_NUMBER): New ac_subst.
* src/Makefile.am (assuan.h): Pass VERSION and VERSION_NUMBER to
mkheader.
* src/assuan.h.in (ASSUAN_VERSION, ASSUAN_VERSION_NUMBER): New macros.
(assuan_check_version): New prototype.
* src/libassuan.def, src/libassuan.vers: Add assuan_check_version.
* src/mkheader.c (write_special, main): Support version and
version_number.
* tests/version.c: New.
* tests/Makefile.am (TESTS): Add version.
--
All our other libs have a version number check, thus we should have
one in Libassuan as well.
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/assuan.c | 95 | ||||
-rw-r--r-- | src/assuan.h.in | 14 | ||||
-rw-r--r-- | src/libassuan.def | 9 | ||||
-rw-r--r-- | src/libassuan.vers | 1 | ||||
-rw-r--r-- | src/mkheader.c | 42 | ||||
-rw-r--r-- | tests/Makefile.am | 10 | ||||
-rw-r--r-- | tests/version.c | 90 |
9 files changed, 247 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac index 28b2c35..ef5f921 100644 --- a/configure.ac +++ b/configure.ac @@ -27,12 +27,16 @@ min_automake_version="1.10" # bump the version number immediately after the release and do another # commit and push so that the git magic is able to work. See below # for the LT versions. -m4_define([mym4_version], [2.1.0]) +m4_define(mym4_version_major, [2]) +m4_define(mym4_version_minor, [1]) +m4_define(mym4_version_micro, [0]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag # indicating a development version (mym4_isgit). Note that the m4 # processing is done by autoconf and not during the configure run. +m4_define(mym4_version, + [mym4_version_major.mym4_version_minor.mym4_version_micro]) m4_define([mym4_revision], m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([mym4_revision_dec], @@ -82,6 +86,9 @@ AC_SUBST(VERSION) AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) AC_DEFINE_UNQUOTED(PACKAGE_BUGREPORT, "$PACKAGE_BUGREPORT",[Bug report address]) +VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_version_major \ + mym4_version_minor mym4_version_micro) +AC_SUBST(VERSION_NUMBER) # Don't default to build static libs. diff --git a/src/Makefile.am b/src/Makefile.am index 95730b3..8ec2b31 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,7 +47,7 @@ parts_of_assuan_h = \ posix-fd-t.inc.h w32-fd-t.inc.h w32ce-fd-t.inc.h \ posix-sock-nonce.inc.h w32-sock-nonce.inc.h \ posix-sys-pth-impl.h w32-sys-pth-impl.h \ - w32ce-add.h + w32ce-add.h common_sources = \ assuan.h.in $(parts_of_assuan_h) \ @@ -142,6 +142,7 @@ mkheader: mkheader.c Makefile $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c assuan.h: assuan.h.in mkheader $(parts_of_assuan_h) - ./mkheader $(host_os) $(srcdir)/assuan.h.in >$@ + ./mkheader $(host_os) $(srcdir)/assuan.h.in \ + @VERSION@ @VERSION_NUMBER@ >$@ 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); +} diff --git a/src/assuan.h.in b/src/assuan.h.in index 69a6a9c..089415c 100644 --- a/src/assuan.h.in +++ b/src/assuan.h.in @@ -1,6 +1,6 @@ /* assuan.h - Definitions for the Assuan IPC library -*- c -*- Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, - 2011 Free Software Foundation, Inc. + 2011, 2013 Free Software Foundation, Inc. This file is part of Assuan. @@ -51,6 +51,15 @@ extern "C" #endif #endif +/* The version of this header should match the one of the library. Do + not use this symbol in your application; use assuan_check_version + instead. */ +#define ASSUAN_VERSION @version@ + +/* The version number of this header. It may be used to handle minor + API incompatibilities. */ +#define ASSUAN_VERSION_NUMBER @version-number@ + /* Check for compiler features. */ #if __GNUC__ @@ -102,6 +111,9 @@ typedef struct assuan_malloc_hooks *assuan_malloc_hooks_t; typedef int (*assuan_log_cb_t) (assuan_context_t ctx, void *hook, unsigned int cat, const char *msg); +/* Return or check the version number. */ +const char *assuan_check_version (const char *req_version); + /* Set the default gpg error source. */ void assuan_set_gpg_err_source (gpg_err_source_t errsource); diff --git a/src/libassuan.def b/src/libassuan.def index b634b1c..5636bfc 100644 --- a/src/libassuan.def +++ b/src/libassuan.def @@ -30,17 +30,17 @@ EXPORTS assuan_get_assuan_log_prefix @9 assuan_get_command_name @10 assuan_get_data_fp @11 - assuan_get_flag @12 + assuan_get_flag @12 assuan_get_gpg_err_source @13 - assuan_get_input_fd @14 + assuan_get_input_fd @14 assuan_get_log_cb @15 assuan_get_malloc_hooks @16 - assuan_get_output_fd @17 + assuan_get_output_fd @17 assuan_get_peercred @18 assuan_get_pid @19 assuan_get_pointer @20 assuan_init_pipe_server @21 - assuan_init_socket_server @22 + assuan_init_socket_server @22 assuan_inquire @23 assuan_inquire_ext @24 assuan_new @25 @@ -110,6 +110,7 @@ EXPORTS __assuan_recvmsg @89 __assuan_sendmsg @90 __assuan_waitpid @91 + assuan_check_version @92 ; END diff --git a/src/libassuan.vers b/src/libassuan.vers index 8f3419f..700c68c 100644 --- a/src/libassuan.vers +++ b/src/libassuan.vers @@ -100,6 +100,7 @@ LIBASSUAN_1.0 { assuan_write_status; assuan_free; assuan_socket_connect_fd; + assuan_check_version; __assuan_close; __assuan_pipe; diff --git a/src/mkheader.c b/src/mkheader.c index d44f6b4..44eb78e 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -4,7 +4,7 @@ * This file is free software; as a special exception the author gives * unlimited permission to copy and/or distribute it, with or without * modifications, as long as this notice is preserved. - * + * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -22,7 +22,8 @@ static const char *host_os; static char *srcdir; - +static const char *hdr_version; +static const char *hdr_version_number; /* Include the file NAME form the source directory. The included file is not further expanded. It may have comments indicated by a @@ -46,7 +47,7 @@ include_file (const char *fname, int lnr, const char *name) fp = fopen (incfname, "r"); if (!fp) { - fprintf (stderr, "%s:%d: error including `%s': %s\n", + fprintf (stderr, "%s:%d: error including `%s': %s\n", fname, lnr, incfname, strerror (errno)); exit (1); } @@ -63,7 +64,7 @@ include_file (const char *fname, int lnr, const char *name) } if (ferror (fp)) { - fprintf (stderr, "%s:%d: error reading `%s': %s\n", + fprintf (stderr, "%s:%d: error reading `%s': %s\n", fname, lnr, incfname, strerror (errno)); exit (1); } @@ -135,6 +136,18 @@ write_special (const char *fname, int lnr, const char *tag) if (!strcmp (host_os, "mingw32ce")) include_file (fname, lnr, "w32ce-add.h"); } + else if (!strcmp (tag, "version")) + { + putchar ('\"'); + fputs (hdr_version, stdout); + putchar ('\"'); + putchar ('\n'); + } + else if (!strcmp (tag, "version-number")) + { + fputs (hdr_version_number, stdout); + putchar ('\n'); + } else return 0; /* Unknown tag. */ @@ -142,7 +155,7 @@ write_special (const char *fname, int lnr, const char *tag) } -int +int main (int argc, char **argv) { FILE *fp; @@ -155,14 +168,17 @@ main (int argc, char **argv) { argc--; argv++; } - - if (argc != 2) + + if (argc != 4) { - fputs ("usage: " PGM " host_os template.h\n", stderr); + fputs ("usage: " PGM " host_os template.h version version_number\n", + stderr); return 1; } host_os = argv[0]; fname = argv[1]; + hdr_version = argv[2]; + hdr_version_number = argv[3]; srcdir = malloc (strlen (fname) + 2 + 1); if (!srcdir) @@ -184,7 +200,7 @@ main (int argc, char **argv) fname, lnr, strerror (errno)); return 1; } - + while (fgets (line, LINESIZE, fp)) { size_t n = strlen (line); @@ -198,7 +214,7 @@ main (int argc, char **argv) break; } line[--n] = 0; - + p1 = strchr (line, '@'); p2 = p1? strchr (p1+1, '@') : NULL; if (!p1 || !p2 || p2-p1 == 1) @@ -213,7 +229,7 @@ main (int argc, char **argv) if (!strcmp (p1, "configure_input")) { s = strrchr (fname, '/'); - printf ("Do not edit. Generated from %s by %s for %s.", + printf ("Do not edit. Generated from %s by %s for %s.", s? s+1 : fname, PGM, host_os); fputs (p2, stdout); putchar ('\n'); @@ -230,7 +246,7 @@ main (int argc, char **argv) if (ferror (fp)) { - fprintf (stderr, "%s:%d: error reading file: %s\n", + fprintf (stderr, "%s:%d: error reading file: %s\n", fname, lnr, strerror (errno)); return 1; } @@ -246,7 +262,7 @@ main (int argc, char **argv) fprintf (stderr, PGM ": error writing stdout: %s\n", strerror (errno)); return 1; } - + fclose (fp); return 0; diff --git a/tests/Makefile.am b/tests/Makefile.am index d82e18b..024ffe2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,17 +18,17 @@ ## Process this file with automake to produce Makefile.in -TESTS_ENVIRONMENT = +TESTS_ENVIRONMENT = EXTRA_DIST = motd ce-createpipe.c -BUILT_SOURCES = -CLEANFILES = +BUILT_SOURCES = +CLEANFILES = -TESTS = pipeconnect +TESTS = version pipeconnect if HAVE_W32CE_SYSTEM -w32cetools = ce-createpipe ce-server +w32cetools = ce-createpipe ce-server endif if USE_DESCRIPTOR_PASSING diff --git a/tests/version.c b/tests/version.c new file mode 100644 index 0000000..96e43c0 --- /dev/null +++ b/tests/version.c @@ -0,0 +1,90 @@ +/* version.c - Check the version info fucntions + Copyright (C) 2013 g10 Code GmbH + + This file is part of Assuan. + + Assuan is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + Assuan is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../src/assuan.h" +#include "common.h" + + +/* + + M A I N + +*/ +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { + log_set_prefix (*argv); + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--help")) + { + puts ( +"usage: ./version [options]\n" +"\n" +"Options:\n" +" --verbose Show what is going on\n" +); + exit (0); + } + if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + } + + assuan_set_assuan_log_prefix (log_prefix); + + if (!assuan_check_version (ASSUAN_VERSION)) + log_error ("assuan_check_version returned an error\n"); + if (!assuan_check_version ("2.0.99")) + log_error ("assuan_check_version returned an error for an old version\n"); + if (assuan_check_version ("15")) + log_error ("assuan_check_version did not returned an error" + " for a newer version\n"); + if (verbose || errorcount) + { + log_info ("Version from header: %s (0x%06x)\n", + ASSUAN_VERSION, ASSUAN_VERSION_NUMBER); + log_info ("Version from binary: %s \n", assuan_check_version (NULL)); + } + + return errorcount ? 1 : 0; +} |