Coverage Report

Created: 2019-06-19 13:33

/src/systemd/src/shared/install-printf.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1+ */
2
3
#include <errno.h>
4
#include <stdio.h>
5
#include <string.h>
6
#include <unistd.h>
7
8
#include "format-util.h"
9
#include "install-printf.h"
10
#include "install.h"
11
#include "macro.h"
12
#include "specifier.h"
13
#include "string-util.h"
14
#include "unit-name.h"
15
#include "user-util.h"
16
17
0
static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
18
0
        const UnitFileInstallInfo *i = userdata;
19
0
        _cleanup_free_ char *prefix = NULL;
20
0
        int r;
21
0
22
0
        assert(i);
23
0
24
0
        r = unit_name_to_prefix_and_instance(i->name, &prefix);
25
0
        if (r < 0)
26
0
                return r;
27
0
28
0
        if (endswith(prefix, "@") && i->default_instance) {
29
0
                char *ans;
30
0
31
0
                ans = strjoin(prefix, i->default_instance);
32
0
                if (!ans)
33
0
                        return -ENOMEM;
34
0
                *ret = ans;
35
0
        } else
36
0
                *ret = TAKE_PTR(prefix);
37
0
38
0
        return 0;
39
0
}
40
41
0
static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) {
42
0
        const UnitFileInstallInfo *i = userdata;
43
0
        char *ans;
44
0
45
0
        assert(i);
46
0
47
0
        if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
48
0
                return unit_name_replace_instance(i->name, i->default_instance, ret);
49
0
50
0
        ans = strdup(i->name);
51
0
        if (!ans)
52
0
                return -ENOMEM;
53
0
        *ret = ans;
54
0
        return 0;
55
0
}
56
57
0
static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
58
0
        const UnitFileInstallInfo *i = userdata;
59
0
60
0
        assert(i);
61
0
62
0
        return unit_name_to_prefix(i->name, ret);
63
0
}
64
65
0
static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) {
66
0
        const UnitFileInstallInfo *i = userdata;
67
0
        char *instance;
68
0
        int r;
69
0
70
0
        assert(i);
71
0
72
0
        r = unit_name_to_instance(i->name, &instance);
73
0
        if (r < 0)
74
0
                return r;
75
0
76
0
        if (isempty(instance)) {
77
0
                r = free_and_strdup(&instance, strempty(i->default_instance));
78
0
                if (r < 0)
79
0
                        return r;
80
0
        }
81
0
82
0
        *ret = instance;
83
0
        return 0;
84
0
}
85
86
0
static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
87
0
        _cleanup_free_ char *prefix = NULL;
88
0
        char *dash;
89
0
        int r;
90
0
91
0
        r = specifier_prefix(specifier, data, userdata, &prefix);
92
0
        if (r < 0)
93
0
                return r;
94
0
95
0
        dash = strrchr(prefix, '-');
96
0
        if (dash) {
97
0
                dash = strdup(dash + 1);
98
0
                if (!dash)
99
0
                        return -ENOMEM;
100
0
                *ret = dash;
101
0
        } else
102
0
                *ret = TAKE_PTR(prefix);
103
0
104
0
        return 0;
105
0
}
106
107
0
int install_full_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
108
0
        /* This is similar to unit_full_printf() but does not support
109
0
         * anything path-related.
110
0
         *
111
0
         * %n: the full id of the unit                 (foo@bar.waldo)
112
0
         * %N: the id of the unit without the suffix   (foo@bar)
113
0
         * %p: the prefix                              (foo)
114
0
         * %i: the instance                            (bar)
115
0
116
0
         * %U the UID of the running user
117
0
         * %u the username of running user
118
0
         * %m the machine ID of the running system
119
0
         * %H the host name of the running system
120
0
         * %b the boot ID of the running system
121
0
         * %v `uname -r` of the running system
122
0
         */
123
0
124
0
        const Specifier table[] = {
125
0
                { 'n', specifier_name,                NULL },
126
0
                { 'N', specifier_prefix_and_instance, NULL },
127
0
                { 'p', specifier_prefix,              NULL },
128
0
                { 'i', specifier_instance,            NULL },
129
0
                { 'j', specifier_last_component,      NULL },
130
0
131
0
                { 'g', specifier_group_name,          NULL },
132
0
                { 'G', specifier_group_id,            NULL },
133
0
                { 'U', specifier_user_id,             NULL },
134
0
                { 'u', specifier_user_name,           NULL },
135
0
136
0
                { 'm', specifier_machine_id,          NULL },
137
0
                { 'H', specifier_host_name,           NULL },
138
0
                { 'b', specifier_boot_id,             NULL },
139
0
                { 'v', specifier_kernel_release,      NULL },
140
0
                {}
141
0
        };
142
0
143
0
        assert(i);
144
0
        assert(format);
145
0
        assert(ret);
146
0
147
0
        return specifier_printf(format, table, i, ret);
148
0
}