Line data Source code
1 : /* version.c - Version checking
2 : * Copyright (C) 2001, 2002, 2012 g10 Code GmbH
3 : *
4 : * This file is part of KSBA.
5 : *
6 : * KSBA is free software; you can redistribute it and/or modify
7 : * it under the terms of either
8 : *
9 : * - the GNU Lesser General Public License as published by the Free
10 : * Software Foundation; either version 3 of the License, or (at
11 : * your option) any later version.
12 : *
13 : * or
14 : *
15 : * - the GNU General Public License as published by the Free
16 : * Software Foundation; either version 2 of the License, or (at
17 : * your option) any later version.
18 : *
19 : * or both in parallel, as here.
20 : *
21 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
22 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 : * License for more details.
25 : *
26 : * You should have received a copies of the GNU General Public License
27 : * and the GNU Lesser General Public License along with this program;
28 : * if not, see <http://www.gnu.org/licenses/>.
29 : */
30 :
31 : #include <config.h>
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 :
36 : #include "util.h"
37 :
38 : static const char*
39 0 : parse_version_number (const char *s, int *number)
40 : {
41 0 : int val = 0;
42 :
43 0 : if (*s == '0' && digitp (s+1))
44 0 : return NULL; /* Leading zeros are not allowed. */
45 0 : for (; digitp (s); s++)
46 : {
47 0 : val *= 10;
48 0 : val += *s - '0';
49 : }
50 0 : *number = val;
51 0 : return val < 0 ? NULL : s;
52 : }
53 :
54 : static const char *
55 0 : parse_version_string (const char *s, int *major, int *minor, int *micro)
56 : {
57 0 : s = parse_version_number (s, major);
58 0 : if (!s || *s != '.')
59 0 : return NULL;
60 0 : s++;
61 0 : s = parse_version_number (s, minor);
62 0 : if (!s || *s != '.')
63 0 : return NULL;
64 0 : s++;
65 0 : s = parse_version_number (s, micro);
66 0 : if (!s)
67 0 : return NULL;
68 0 : return s; /* Patchlevel. */
69 : }
70 :
71 : static const char *
72 0 : compare_versions (const char *my_version, const char *req_version)
73 : {
74 : int my_major, my_minor, my_micro;
75 : int rq_major, rq_minor, rq_micro;
76 : const char *my_plvl, *rq_plvl;
77 :
78 0 : if (!req_version)
79 0 : return my_version;
80 0 : if (!my_version)
81 0 : return NULL;
82 :
83 0 : my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
84 0 : if (!my_plvl)
85 0 : return NULL; /* Very strange: our own version is bogus. */
86 0 : rq_plvl = parse_version_string(req_version,
87 : &rq_major, &rq_minor, &rq_micro);
88 0 : if (!rq_plvl)
89 0 : return NULL; /* Requested version string is invalid. */
90 :
91 0 : if (my_major > rq_major
92 0 : || (my_major == rq_major && my_minor > rq_minor)
93 0 : || (my_major == rq_major && my_minor == rq_minor
94 0 : && my_micro > rq_micro)
95 0 : || (my_major == rq_major && my_minor == rq_minor
96 0 : && my_micro == rq_micro))
97 : {
98 0 : return my_version;
99 : }
100 0 : return NULL;
101 : }
102 :
103 : /**
104 : * ksba_check_version:
105 : * @req_version: A string with a version
106 : *
107 : * Check that the the version of the library is at minimum the requested one
108 : * and return the version string; return NULL if the condition is not
109 : * met. If a NULL is passed to this function, no check is done and
110 : * the version string is simply returned. It is a pretty good idea to
111 : * run this function as soon as possible, because it also intializes
112 : * some subsystems. In a multithreaded environment if should be called
113 : * before the first thread is created.
114 : *
115 : * Return value: The version string or NULL
116 : **/
117 : const char *
118 0 : ksba_check_version (const char *req_version)
119 : {
120 : /* fixme: if we need global initializations.
121 : Note that these the malloc hook might not have been run yet */
122 0 : return compare_versions (VERSION, req_version);
123 : }
|