Coverage Report

Created: 2026-03-12 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/shared/install-printf.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include "alloc-util.h"
4
#include "install.h"
5
#include "install-printf.h"
6
#include "specifier.h"
7
#include "string-util.h"
8
#include "unit-name.h"
9
10
0
static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
11
0
        const InstallInfo *i = ASSERT_PTR(userdata);
12
0
        _cleanup_free_ char *prefix = NULL;
13
0
        int r;
14
15
0
        r = unit_name_to_prefix_and_instance(i->name, &prefix);
16
0
        if (r < 0)
17
0
                return r;
18
19
0
        if (endswith(prefix, "@") && i->default_instance) {
20
0
                char *ans;
21
22
0
                ans = strjoin(prefix, i->default_instance);
23
0
                if (!ans)
24
0
                        return -ENOMEM;
25
0
                *ret = ans;
26
0
        } else
27
0
                *ret = TAKE_PTR(prefix);
28
29
0
        return 0;
30
0
}
31
32
0
static int specifier_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
33
0
        const InstallInfo *i = ASSERT_PTR(userdata);
34
35
0
        if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
36
0
                return unit_name_replace_instance(i->name, i->default_instance, ret);
37
38
0
        return strdup_to(ret, i->name);
39
0
}
40
41
0
static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
42
0
        const InstallInfo *i = ASSERT_PTR(userdata);
43
44
0
        return unit_name_to_prefix(i->name, ret);
45
0
}
46
47
0
static int specifier_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
48
0
        const InstallInfo *i = ASSERT_PTR(userdata);
49
0
        char *instance;
50
0
        int r;
51
52
0
        r = unit_name_to_instance(i->name, &instance);
53
0
        if (r < 0)
54
0
                return r;
55
56
0
        if (isempty(instance)) {
57
0
                r = free_and_strdup(&instance, strempty(i->default_instance));
58
0
                if (r < 0)
59
0
                        return r;
60
0
        }
61
62
0
        *ret = instance;
63
0
        return 0;
64
0
}
65
66
0
static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
67
0
        _cleanup_free_ char *prefix = NULL;
68
0
        char *dash;
69
0
        int r;
70
71
0
        assert(ret);
72
73
0
        r = specifier_prefix(specifier, data, root, userdata, &prefix);
74
0
        if (r < 0)
75
0
                return r;
76
77
0
        dash = strrchr(prefix, '-');
78
0
        if (dash)
79
0
                return strdup_to(ret, dash + 1);
80
81
0
        *ret = TAKE_PTR(prefix);
82
0
        return 0;
83
0
}
84
85
int install_name_printf(
86
                RuntimeScope scope,
87
                const InstallInfo *info,
88
                const char *format,
89
0
                char **ret) {
90
        /* This is similar to unit_name_printf() */
91
92
0
        const Specifier table[] = {
93
0
                { 'i', specifier_instance,            NULL },
94
0
                { 'j', specifier_last_component,      NULL },
95
0
                { 'n', specifier_name,                NULL },
96
0
                { 'N', specifier_prefix_and_instance, NULL },
97
0
                { 'p', specifier_prefix,              NULL },
98
99
0
                COMMON_SYSTEM_SPECIFIERS,
100
101
0
                COMMON_CREDS_SPECIFIERS(scope),
102
0
                {}
103
0
        };
104
105
0
        assert(info);
106
0
        assert(format);
107
0
        assert(ret);
108
109
0
        return specifier_printf(format, UNIT_NAME_MAX, table, info->root, info, ret);
110
0
}