1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3 * This file is part of libmount from util-linux project.
4 *
5 * Copyright (C) 2008-2018 Karel Zak <kzak@redhat.com>
6 *
7 * libmount is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 */
12
13 /**
14 * SECTION: version-utils
15 * @title: Version functions
16 * @short_description: functions to get the library version.
17 */
18
19 #include <ctype.h>
20
21 #include "mountP.h"
22
23 static const char *lib_version = LIBMOUNT_VERSION;
24 static const char *lib_features[] = {
25 #ifdef HAVE_LIBSELINUX
26 "selinux",
27 #endif
28 #ifdef HAVE_SMACK
29 "smack",
30 #endif
31 #ifdef HAVE_BTRFS_SUPPORT
32 "btrfs",
33 #endif
34 #ifdef HAVE_CRYPTSETUP
35 "verity",
36 #endif
37 #ifdef USE_LIBMOUNT_SUPPORT_MTAB
38 "mtab",
39 #endif
40 #ifdef USE_LIBMOUNT_SUPPORT_NAMESPACES
41 "namespaces",
42 #endif
43 #if !defined(NDEBUG)
44 "assert", /* libc assert.h stuff */
45 #endif
46 "debug", /* always enabled */
47 NULL
48 };
49
50 /**
51 * mnt_parse_version_string:
52 * @ver_string: version string (e.g "2.18.0")
53 *
54 * Returns: release version code.
55 */
mnt_parse_version_string(const char * ver_string)56 int mnt_parse_version_string(const char *ver_string)
57 {
58 const char *cp;
59 int version = 0;
60
61 assert(ver_string);
62
63 for (cp = ver_string; *cp; cp++) {
64 if (*cp == '.')
65 continue;
66 if (!isdigit(*cp))
67 break;
68 version = (version * 10) + (*cp - '0');
69 }
70 return version;
71 }
72
73 /**
74 * mnt_get_library_version:
75 * @ver_string: return pointer to the static library version string if not NULL
76 *
77 * Returns: release version number.
78 */
mnt_get_library_version(const char ** ver_string)79 int mnt_get_library_version(const char **ver_string)
80 {
81 if (ver_string)
82 *ver_string = lib_version;
83
84 return mnt_parse_version_string(lib_version);
85 }
86
87 /**
88 * mnt_get_library_features:
89 * @features: returns a pointer to the static array of strings, the array is
90 * terminated by NULL.
91 *
92 * Returns: number of items in the features array not including the last NULL,
93 * or less than zero in case of error
94 *
95 * Example:
96 * <informalexample>
97 * <programlisting>
98 * const char **features;
99 *
100 * mnt_get_library_features(&features);
101 * while (features && *features)
102 * printf("%s\n", *features++);
103 * </programlisting>
104 * </informalexample>
105 *
106 */
mnt_get_library_features(const char *** features)107 int mnt_get_library_features(const char ***features)
108 {
109 if (!features)
110 return -EINVAL;
111
112 *features = lib_features;
113 return ARRAY_SIZE(lib_features) - 1;
114 }
115
116 #ifdef TEST_PROGRAM
test_version(struct libmnt_test * ts,int argc,char * argv[])117 static int test_version(struct libmnt_test *ts, int argc, char *argv[])
118 {
119 const char *ver;
120 const char **features;
121
122 if (argc == 2)
123 printf("Your version: %d\n",
124 mnt_parse_version_string(argv[1]));
125
126 mnt_get_library_version(&ver);
127
128 printf("Library version: %s\n", ver);
129 printf("Library API version: " LIBMOUNT_VERSION "\n");
130 printf("Library features:");
131
132 mnt_get_library_features(&features);
133 while (features && *features)
134 printf(" %s", *features++);
135
136 printf("\n");
137
138 if (mnt_get_library_version(NULL) ==
139 mnt_parse_version_string(LIBMOUNT_VERSION))
140 return 0;
141
142 return -1;
143 }
144
main(int argc,char * argv[])145 int main(int argc, char *argv[])
146 {
147 struct libmnt_test ts[] = {
148 { "--print", test_version, "print versions" },
149 { NULL }
150 };
151
152 return mnt_run_test(ts, argc, argv);
153 }
154 #endif
155