1:255.16-alt1
[systemd_ALT.git] / src / analyze / analyze-compare-versions.c
blob94cff1853e28d652bf32a026ff83558bd4825fe1
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <stdio.h>
5 #include "analyze-compare-versions.h"
6 #include "compare-operator.h"
7 #include "macro.h"
8 #include "string-util.h"
9 #include "strv.h"
11 int verb_compare_versions(int argc, char *argv[], void *userdata) {
12 const char *v1 = ASSERT_PTR(argv[1]), *v2 = ASSERT_PTR(argv[argc-1]);
13 int r;
15 assert(IN_SET(argc, 3, 4));
16 assert(argv);
18 /* We only output a warning on invalid version strings (instead of failing), since the comparison
19 * functions try to handle invalid strings gracefully and it's still interesting to see what the
20 * comparison result will be. */
21 if (!version_is_valid_versionspec(v1))
22 log_warning("Version string 1 contains disallowed characters, they will be treated as separators: %s", v1);
23 if (!version_is_valid_versionspec(v2))
24 log_warning("Version string 2 contains disallowed characters, they will be treated as separators: %s", v2);
26 if (argc == 3) {
27 r = strverscmp_improved(v1, v2);
28 printf("%s %s %s\n",
29 isempty(v1) ? "''" : v1,
30 comparison_operator(r),
31 isempty(v2) ? "''" : v2);
33 /* This matches the exit convention used by rpmdev-vercmp.
34 * We don't use named values because 11 and 12 don't have names. */
35 return r < 0 ? 12 : r > 0 ? 11 : 0;
37 } else {
38 const char *op = ASSERT_PTR(argv[2]);
39 CompareOperator operator;
40 assert(argc == 4);
42 operator = parse_compare_operator(&op, COMPARE_ALLOW_TEXTUAL);
43 if (operator < 0 || !isempty(op))
44 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown operator \"%s\".", op);
46 r = version_or_fnmatch_compare(operator, v1, v2);
47 if (r < 0)
48 return log_error_errno(r, "Failed to compare versions: %m");
50 return r ? EXIT_SUCCESS : EXIT_FAILURE;