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 #include "mount-api-utils.h"
23
24 static const char *lib_version = LIBMOUNT_VERSION;
25 static const char *lib_features[] = {
26 #ifdef HAVE_LIBSELINUX
27 "selinux",
28 #endif
29 #ifdef HAVE_SMACK
30 "smack",
31 #endif
32 #ifdef HAVE_BTRFS_SUPPORT
33 "btrfs",
34 #endif
35 #ifdef HAVE_CRYPTSETUP
36 "verity",
37 #endif
38 #ifdef USE_LIBMOUNT_SUPPORT_NAMESPACES
39 "namespaces",
40 #endif
41 #ifdef HAVE_MOUNTFD_API
42 "idmapping",
43 #endif
44 #ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
45 "fd-based-mount",
46 #endif
47 #if !defined(NDEBUG)
48 "assert", /* libc assert.h stuff */
49 #endif
50 "debug", /* always enabled */
51 NULL
52 };
53
54 /**
55 * mnt_parse_version_string:
56 * @ver_string: version string (e.g "2.18.0")
57 *
58 * Returns: release version code.
59 */
60 int mnt_parse_version_string(const char *ver_string)
61 {
62 const char *cp;
63 int version = 0;
64
65 assert(ver_string);
66
67 for (cp = ver_string; *cp; cp++) {
68 if (*cp == '.')
69 continue;
70 if (!isdigit(*cp))
71 break;
72 version = (version * 10) + (*cp - '0');
73 }
74 return version;
75 }
76
77 /**
78 * mnt_get_library_version:
79 * @ver_string: return pointer to the static library version string if not NULL
80 *
81 * Returns: release version number.
82 */
83 int mnt_get_library_version(const char **ver_string)
84 {
85 if (ver_string)
86 *ver_string = lib_version;
87
88 return mnt_parse_version_string(lib_version);
89 }
90
91 /**
92 * mnt_get_library_features:
93 * @features: returns a pointer to the static array of strings, the array is
94 * terminated by NULL.
95 *
96 * Returns: number of items in the features array not including the last NULL,
97 * or less than zero in case of error
98 *
99 * Example:
100 * <informalexample>
101 * <programlisting>
102 * const char **features;
103 *
104 * mnt_get_library_features(&features);
105 * while (features && *features)
106 * printf("%s\n", *features++);
107 * </programlisting>
108 * </informalexample>
109 *
110 */
111 int mnt_get_library_features(const char ***features)
112 {
113 if (!features)
114 return -EINVAL;
115
116 *features = lib_features;
117 return ARRAY_SIZE(lib_features) - 1;
118 }
119
120 #ifdef TEST_PROGRAM
121 static int test_version(struct libmnt_test *ts, int argc, char *argv[])
122 {
123 const char *ver;
124 const char **features;
125
126 if (argc == 2)
127 printf("Your version: %d\n",
128 mnt_parse_version_string(argv[1]));
129
130 mnt_get_library_version(&ver);
131
132 printf("Library version: %s\n", ver);
133 printf("Library API version: " LIBMOUNT_VERSION "\n");
134 printf("Library features:");
135
136 mnt_get_library_features(&features);
137 while (features && *features)
138 printf(" %s", *features++);
139
140 printf("\n");
141
142 if (mnt_get_library_version(NULL) ==
143 mnt_parse_version_string(LIBMOUNT_VERSION))
144 return 0;
145
146 return -1;
147 }
148
149 int main(int argc, char *argv[])
150 {
151 struct libmnt_test ts[] = {
152 { "--print", test_version, "print versions" },
153 { NULL }
154 };
155
156 return mnt_run_test(ts, argc, argv);
157 }
158 #endif