]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/import-util.c
Merge pull request #1648 from evverx/clarify-journalctl-quiet-option
[thirdparty/systemd.git] / src / shared / import-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2015 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 "btrfs-util.h"
23 #include "util.h"
24 #include "import-util.h"
25
26 int import_url_last_component(const char *url, char **ret) {
27 const char *e, *p;
28 char *s;
29
30 e = strchrnul(url, '?');
31
32 while (e > url && e[-1] == '/')
33 e--;
34
35 p = e;
36 while (p > url && p[-1] != '/')
37 p--;
38
39 if (e <= p)
40 return -EINVAL;
41
42 s = strndup(p, e - p);
43 if (!s)
44 return -ENOMEM;
45
46 *ret = s;
47 return 0;
48 }
49
50
51 int import_url_change_last_component(const char *url, const char *suffix, char **ret) {
52 const char *e;
53 char *s;
54
55 assert(url);
56 assert(ret);
57
58 e = strchrnul(url, '?');
59
60 while (e > url && e[-1] == '/')
61 e--;
62
63 while (e > url && e[-1] != '/')
64 e--;
65
66 if (e <= url)
67 return -EINVAL;
68
69 s = new(char, (e - url) + strlen(suffix) + 1);
70 if (!s)
71 return -ENOMEM;
72
73 strcpy(mempcpy(s, url, e - url), suffix);
74 *ret = s;
75 return 0;
76 }
77
78 static const char* const import_verify_table[_IMPORT_VERIFY_MAX] = {
79 [IMPORT_VERIFY_NO] = "no",
80 [IMPORT_VERIFY_CHECKSUM] = "checksum",
81 [IMPORT_VERIFY_SIGNATURE] = "signature",
82 };
83
84 DEFINE_STRING_TABLE_LOOKUP(import_verify, ImportVerify);
85
86 int tar_strip_suffixes(const char *name, char **ret) {
87 const char *e;
88 char *s;
89
90 e = endswith(name, ".tar");
91 if (!e)
92 e = endswith(name, ".tar.xz");
93 if (!e)
94 e = endswith(name, ".tar.gz");
95 if (!e)
96 e = endswith(name, ".tar.bz2");
97 if (!e)
98 e = endswith(name, ".tgz");
99 if (!e)
100 e = strchr(name, 0);
101
102 if (e <= name)
103 return -EINVAL;
104
105 s = strndup(name, e - name);
106 if (!s)
107 return -ENOMEM;
108
109 *ret = s;
110 return 0;
111 }
112
113 int raw_strip_suffixes(const char *p, char **ret) {
114
115 static const char suffixes[] =
116 ".xz\0"
117 ".gz\0"
118 ".bz2\0"
119 ".raw\0"
120 ".qcow2\0"
121 ".img\0"
122 ".bin\0";
123
124 _cleanup_free_ char *q = NULL;
125
126 q = strdup(p);
127 if (!q)
128 return -ENOMEM;
129
130 for (;;) {
131 const char *sfx;
132 bool changed = false;
133
134 NULSTR_FOREACH(sfx, suffixes) {
135 char *e;
136
137 e = endswith(q, sfx);
138 if (e) {
139 *e = 0;
140 changed = true;
141 }
142 }
143
144 if (!changed)
145 break;
146 }
147
148 *ret = q;
149 q = NULL;
150
151 return 0;
152 }
153
154 bool dkr_digest_is_valid(const char *digest) {
155 /* 7 chars for prefix, 64 chars for the digest itself */
156 if (strlen(digest) != 71)
157 return false;
158
159 return startswith(digest, "sha256:") && in_charset(digest + 7, "0123456789abcdef");
160 }
161
162 bool dkr_ref_is_valid(const char *ref) {
163 const char *colon;
164
165 if (isempty(ref))
166 return false;
167
168 colon = strchr(ref, ':');
169 if (!colon)
170 return filename_is_valid(ref);
171
172 return dkr_digest_is_valid(ref);
173 }
174
175 bool dkr_name_is_valid(const char *name) {
176 const char *slash, *p;
177
178 if (isempty(name))
179 return false;
180
181 slash = strchr(name, '/');
182 if (!slash)
183 return false;
184
185 if (!filename_is_valid(slash + 1))
186 return false;
187
188 p = strndupa(name, slash - name);
189 if (!filename_is_valid(p))
190 return false;
191
192 return true;
193 }
194
195 bool dkr_id_is_valid(const char *id) {
196
197 if (!filename_is_valid(id))
198 return false;
199
200 if (!in_charset(id, "0123456789abcdef"))
201 return false;
202
203 return true;
204 }
205
206 int import_assign_pool_quota_and_warn(const char *path) {
207 int r;
208
209 r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
210 if (r == -ENOTTY) {
211 log_debug_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, as directory is not on btrfs or not a subvolume. Ignoring.");
212 return 0;
213 }
214 if (r < 0)
215 return log_error_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines: %m");
216 if (r > 0)
217 log_info("Set up default quota hierarchy for /var/lib/machines.");
218
219 r = btrfs_subvol_auto_qgroup(path, 0, true);
220 if (r == -ENOTTY) {
221 log_debug_errno(r, "Failed to set up quota hierarchy for %s, as directory is not on btrfs or not a subvolume. Ignoring.", path);
222 return 0;
223 }
224 if (r < 0)
225 return log_error_errno(r, "Failed to set up default quota hierarchy for %s: %m", path);
226 if (r > 0)
227 log_info("Set up default quota hierarchy for %s.", path);
228
229 return 0;
230 }