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