]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/specifier.c
man: document ARM root partition types
[thirdparty/systemd.git] / src / shared / specifier.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <string.h>
23 #include <sys/utsname.h>
24
25 #include "macro.h"
26 #include "util.h"
27 #include "specifier.h"
28
29 /*
30 * Generic infrastructure for replacing %x style specifiers in
31 * strings. Will call a callback for each replacement.
32 *
33 */
34
35 int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
36 char *ret, *t;
37 const char *f;
38 bool percent = false;
39 size_t l;
40 int r;
41
42 assert(text);
43 assert(table);
44
45 l = strlen(text);
46 ret = new(char, l+1);
47 if (!ret)
48 return -ENOMEM;
49
50 t = ret;
51
52 for (f = text; *f; f++, l--) {
53
54 if (percent) {
55 if (*f == '%')
56 *(t++) = '%';
57 else {
58 const Specifier *i;
59
60 for (i = table; i->specifier; i++)
61 if (i->specifier == *f)
62 break;
63
64 if (i->lookup) {
65 _cleanup_free_ char *w = NULL;
66 char *n;
67 size_t k, j;
68
69 r = i->lookup(i->specifier, i->data, userdata, &w);
70 if (r < 0) {
71 free(ret);
72 return r;
73 }
74
75 j = t - ret;
76 k = strlen(w);
77
78 n = new(char, j + k + l + 1);
79 if (!n) {
80 free(ret);
81 return -ENOMEM;
82 }
83
84 memcpy(n, ret, j);
85 memcpy(n + j, w, k);
86
87 free(ret);
88
89 ret = n;
90 t = n + j + k;
91 } else {
92 *(t++) = '%';
93 *(t++) = *f;
94 }
95 }
96
97 percent = false;
98 } else if (*f == '%')
99 percent = true;
100 else
101 *(t++) = *f;
102 }
103
104 *t = 0;
105 *_ret = ret;
106 return 0;
107 }
108
109 /* Generic handler for simple string replacements */
110
111 int specifier_string(char specifier, void *data, void *userdata, char **ret) {
112 char *n;
113
114 n = strdup(strempty(data));
115 if (!n)
116 return -ENOMEM;
117
118 *ret = n;
119 return 0;
120 }
121
122 int specifier_machine_id(char specifier, void *data, void *userdata, char **ret) {
123 sd_id128_t id;
124 char *n;
125 int r;
126
127 r = sd_id128_get_machine(&id);
128 if (r < 0)
129 return r;
130
131 n = new(char, 33);
132 if (!n)
133 return -ENOMEM;
134
135 *ret = sd_id128_to_string(id, n);
136 return 0;
137 }
138
139 int specifier_boot_id(char specifier, void *data, void *userdata, char **ret) {
140 sd_id128_t id;
141 char *n;
142 int r;
143
144 r = sd_id128_get_boot(&id);
145 if (r < 0)
146 return r;
147
148 n = new(char, 33);
149 if (!n)
150 return -ENOMEM;
151
152 *ret = sd_id128_to_string(id, n);
153 return 0;
154 }
155
156 int specifier_host_name(char specifier, void *data, void *userdata, char **ret) {
157 char *n;
158
159 n = gethostname_malloc();
160 if (!n)
161 return -ENOMEM;
162
163 *ret = n;
164 return 0;
165 }
166
167 int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret) {
168 struct utsname uts;
169 char *n;
170 int r;
171
172 r = uname(&uts);
173 if (r < 0)
174 return -errno;
175
176 n = strdup(uts.release);
177 if (!n)
178 return -ENOMEM;
179
180 *ret = n;
181 return 0;
182 }