]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/specifier.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / shared / specifier.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
9e2f7c11
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
9e2f7c11
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
9e2f7c11 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
9e2f7c11
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <string.h>
6aaa8c2f 23#include <sys/utsname.h>
9e2f7c11 24
07630cea 25#include "hostname-util.h"
9e2f7c11 26#include "macro.h"
07630cea 27#include "string-util.h"
9e2f7c11
LP
28#include "util.h"
29#include "specifier.h"
30
31/*
32 * Generic infrastructure for replacing %x style specifiers in
33 * strings. Will call a callback for each replacement.
34 *
35 */
36
19f6d710
LP
37int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
38 char *ret, *t;
9e2f7c11
LP
39 const char *f;
40 bool percent = false;
41 size_t l;
19f6d710 42 int r;
9e2f7c11
LP
43
44 assert(text);
45 assert(table);
46
47 l = strlen(text);
19f6d710
LP
48 ret = new(char, l+1);
49 if (!ret)
50 return -ENOMEM;
9e2f7c11 51
19f6d710 52 t = ret;
9e2f7c11
LP
53
54 for (f = text; *f; f++, l--) {
55
56 if (percent) {
57 if (*f == '%')
58 *(t++) = '%';
59 else {
60 const Specifier *i;
61
62 for (i = table; i->specifier; i++)
63 if (i->specifier == *f)
64 break;
65
66 if (i->lookup) {
19f6d710
LP
67 _cleanup_free_ char *w = NULL;
68 char *n;
9e2f7c11
LP
69 size_t k, j;
70
19f6d710
LP
71 r = i->lookup(i->specifier, i->data, userdata, &w);
72 if (r < 0) {
73 free(ret);
74 return r;
9e2f7c11
LP
75 }
76
19f6d710 77 j = t - ret;
9e2f7c11
LP
78 k = strlen(w);
79
7ae03f36
LP
80 n = new(char, j + k + l + 1);
81 if (!n) {
19f6d710
LP
82 free(ret);
83 return -ENOMEM;
9e2f7c11
LP
84 }
85
19f6d710 86 memcpy(n, ret, j);
9e2f7c11
LP
87 memcpy(n + j, w, k);
88
19f6d710 89 free(ret);
9e2f7c11 90
19f6d710 91 ret = n;
9e2f7c11
LP
92 t = n + j + k;
93 } else {
94 *(t++) = '%';
95 *(t++) = *f;
96 }
97 }
98
99 percent = false;
100 } else if (*f == '%')
101 percent = true;
102 else
103 *(t++) = *f;
104 }
105
106 *t = 0;
19f6d710
LP
107 *_ret = ret;
108 return 0;
9e2f7c11
LP
109}
110
111/* Generic handler for simple string replacements */
112
19f6d710
LP
113int specifier_string(char specifier, void *data, void *userdata, char **ret) {
114 char *n;
115
116 n = strdup(strempty(data));
117 if (!n)
118 return -ENOMEM;
119
120 *ret = n;
121 return 0;
9e2f7c11 122}
d848b9cb 123
19f6d710 124int specifier_machine_id(char specifier, void *data, void *userdata, char **ret) {
d848b9cb 125 sd_id128_t id;
19f6d710 126 char *n;
d848b9cb
ZJS
127 int r;
128
129 r = sd_id128_get_machine(&id);
130 if (r < 0)
19f6d710 131 return r;
d848b9cb 132
19f6d710
LP
133 n = new(char, 33);
134 if (!n)
135 return -ENOMEM;
d848b9cb 136
19f6d710
LP
137 *ret = sd_id128_to_string(id, n);
138 return 0;
d848b9cb
ZJS
139}
140
19f6d710 141int specifier_boot_id(char specifier, void *data, void *userdata, char **ret) {
d848b9cb 142 sd_id128_t id;
19f6d710 143 char *n;
d848b9cb
ZJS
144 int r;
145
146 r = sd_id128_get_boot(&id);
147 if (r < 0)
19f6d710 148 return r;
d848b9cb 149
19f6d710
LP
150 n = new(char, 33);
151 if (!n)
152 return -ENOMEM;
d848b9cb 153
19f6d710
LP
154 *ret = sd_id128_to_string(id, n);
155 return 0;
d848b9cb
ZJS
156}
157
19f6d710
LP
158int specifier_host_name(char specifier, void *data, void *userdata, char **ret) {
159 char *n;
160
161 n = gethostname_malloc();
162 if (!n)
163 return -ENOMEM;
164
165 *ret = n;
166 return 0;
d848b9cb 167}
6aaa8c2f 168
19f6d710 169int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret) {
6aaa8c2f 170 struct utsname uts;
19f6d710 171 char *n;
6aaa8c2f
ZJS
172 int r;
173
174 r = uname(&uts);
175 if (r < 0)
19f6d710
LP
176 return -errno;
177
178 n = strdup(uts.release);
179 if (!n)
180 return -ENOMEM;
6aaa8c2f 181
19f6d710
LP
182 *ret = n;
183 return 0;
6aaa8c2f 184}