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