Line data Source code
1 : /* version.c - Version checking
2 : * Copyright (C) 2001, 2002, 2012, 2013, 2014 g10 Code GmbH
3 : *
4 : * This file is part of libgpg-error.
5 : *
6 : * libgpg-error is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public License
8 : * as published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * libgpg-error is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : #if HAVE_CONFIG_H
21 : #include <config.h>
22 : #endif
23 :
24 : #include <stdlib.h>
25 : #include <stdio.h>
26 : #include <string.h>
27 :
28 : #include <gpg-error.h>
29 :
30 :
31 : #define digitp(a) ((a) >= '0' && (a) <= '9')
32 :
33 :
34 : /* This is actually a dummy function to make sure that is module is
35 : not empty. Some compilers barf on empty modules. */
36 : static const char *
37 : cright_blurb (void)
38 : {
39 : static const char blurb[] =
40 : "\n\n"
41 : "This is Libgpg-error " PACKAGE_VERSION " - An error code library\n"
42 : "Copyright 2003-2004, 2010, 2013-2017 g10 Code GmbH\n"
43 : "\n"
44 : "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
45 : "\n\n";
46 : return blurb;
47 : }
48 :
49 :
50 : static const char*
51 : parse_version_number (const char *s, int *number)
52 : {
53 : int val = 0;
54 :
55 23 : if (*s == '0' && digitp (s[1]))
56 : return NULL; /* Leading zeros are not allowed. */
57 35 : for (; digitp (*s); s++)
58 : {
59 35 : val *= 10;
60 35 : val += *s - '0';
61 : }
62 23 : *number = val;
63 23 : return val < 0 ? NULL : s;
64 : }
65 :
66 :
67 : static const char *
68 12 : parse_version_string (const char *s, int *major, int *minor)
69 : {
70 : s = parse_version_number (s, major);
71 12 : if (!s || *s != '.')
72 : return NULL;
73 11 : s++;
74 : s = parse_version_number (s, minor);
75 11 : if (!s)
76 : return NULL;
77 11 : return s; /* Patchlevel. */
78 : }
79 :
80 :
81 : static const char *
82 6 : compare_versions (const char *my_version, const char *req_version)
83 : {
84 : int my_major, my_minor;
85 : int rq_major, rq_minor;
86 : const char *my_plvl, *rq_plvl;
87 :
88 6 : if (!req_version)
89 : return my_version;
90 6 : if (!my_version)
91 : return NULL;
92 :
93 6 : my_plvl = parse_version_string (my_version, &my_major, &my_minor);
94 6 : if (!my_plvl)
95 : return NULL; /* Very strange: our own version is bogus. */
96 6 : rq_plvl = parse_version_string(req_version, &rq_major, &rq_minor);
97 6 : if (!rq_plvl)
98 : return NULL; /* Requested version string is invalid. */
99 :
100 5 : if (my_major > rq_major
101 5 : || (my_major == rq_major && my_minor >= rq_minor))
102 : {
103 : return my_version;
104 : }
105 0 : return NULL;
106 : }
107 :
108 :
109 : /*
110 : * Check that the the version of the library is at minimum REQ_VERSION
111 : * and return the actual version string; return NULL if the condition
112 : * is not met. If NULL is passed to this function, no check is done
113 : * and the version string is simply returned.
114 : */
115 : const char *
116 6 : _gpg_error_check_version (const char *req_version)
117 : {
118 6 : if (req_version && req_version[0] == 1 && req_version[1] == 1)
119 : return cright_blurb ();
120 6 : return compare_versions (PACKAGE_VERSION, req_version);
121 : }
|