]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/import-util.c
9c9a9d7e301efd2e9b687ea0ea17010e0b08f462
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "btrfs-util.h"
5 #include "chattr-util.h"
6 #include "errno-util.h"
7 #include "import-util.h"
9 #include "nulstr-util.h"
10 #include "string-table.h"
11 #include "string-util.h"
13 static const char *skip_protocol_and_hostname(const char *url
) {
17 /* A very very lenient implementation of RFC3986 Section 3.2 */
19 /* Find colon separating protocol and hostname */
25 /* Skip slashes after colon */
28 /* Skip everything till next slash or end */
29 n
= strcspn(d
, "/?#");
36 int import_url_last_component(
40 const char *e
, *p
, *h
;
42 /* This extracts the last path component of the specified URI, i.e. the last non-empty substrings
43 * between two "/" characters. This ignores "Query" and "Fragment" suffixes (as per RFC3986). */
45 h
= skip_protocol_and_hostname(url
);
49 e
= h
+ strcspn(h
, "?#"); /* Cut off "Query" and "Fragment" */
51 while (e
> h
&& e
[-1] == '/') /* Eat trailing slashes */
55 while (p
> h
&& p
[-1] != '/') /* Find component before that */
58 if (e
<= p
) /* Empty component? */
59 return -EADDRNOTAVAIL
;
64 s
= strndup(p
, e
- p
);
74 int import_url_change_suffix(
76 size_t n_drop_components
,
86 /* This drops the specified number of path components of the specified URI, i.e. the specified number
87 * of non-empty substring between two "/" characters from the end of the string, and then append the
88 * specified suffix instead. Before doing all this it chops off the "Query" and "Fragment" suffixes
89 * (they are *not* re-added to the final URL). Note that n_drop_components may be 0 (in which case the
90 * component are simply added to the end). The suffix may be specified as NULL or empty string in
91 * which case nothing is appended, only the specified number of components chopped off. Note that the
92 * function may be called with n_drop_components == 0 and suffix == NULL, in which case the "Query"
93 * and "Fragment" is chopped off, and ensured the URL ends in a single "/", and that's it. */
95 h
= skip_protocol_and_hostname(url
);
99 e
= h
+ strcspn(h
, "?#"); /* Cut off "Query" and "Fragment" */
101 while (e
> h
&& e
[-1] == '/') /* Eat trailing slashes */
104 /* Drop the specified number of components from the end. Note that this is pretty lenient: if there
105 * are less component we silently drop those and then append the suffix to the top. */
106 while (n_drop_components
> 0) {
107 while (e
> h
&& e
[-1] != '/') /* Eat last word (we don't mind if empty) */
110 while (e
> h
&& e
[-1] == '/') /* Eat slashes before the last word */
116 s
= new(char, (e
- url
) + 1 + strlen_ptr(suffix
) + 1);
120 strcpy(stpcpy(mempcpy(s
, url
, e
- url
), "/"), strempty(suffix
));
125 static const char* const import_type_table
[_IMPORT_TYPE_MAX
] = {
126 [IMPORT_RAW
] = "raw",
127 [IMPORT_TAR
] = "tar",
130 DEFINE_STRING_TABLE_LOOKUP(import_type
, ImportType
);
132 static const char* const import_verify_table
[_IMPORT_VERIFY_MAX
] = {
133 [IMPORT_VERIFY_NO
] = "no",
134 [IMPORT_VERIFY_CHECKSUM
] = "checksum",
135 [IMPORT_VERIFY_SIGNATURE
] = "signature",
138 DEFINE_STRING_TABLE_LOOKUP(import_verify
, ImportVerify
);
140 int tar_strip_suffixes(const char *name
, char **ret
) {
144 e
= endswith(name
, ".tar");
146 e
= endswith(name
, ".tar.xz");
148 e
= endswith(name
, ".tar.gz");
150 e
= endswith(name
, ".tar.bz2");
152 e
= endswith(name
, ".tar.zst");
154 e
= endswith(name
, ".tgz");
161 s
= strndup(name
, e
- name
);
169 int raw_strip_suffixes(const char *p
, char **ret
) {
171 static const char suffixes
[] =
183 _cleanup_free_
char *q
= NULL
;
190 bool changed
= false;
192 NULSTR_FOREACH(sfx
, suffixes
) {
195 e
= endswith(q
, sfx
);
211 int import_assign_pool_quota_and_warn(const char *path
) {
216 r
= btrfs_subvol_auto_qgroup(path
, 0, true);
218 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 log_error_errno(r
, "Failed to set up default quota hierarchy for %s: %m", path
);
224 log_debug("Set up default quota hierarchy for %s.", path
);
229 int import_set_nocow_and_log(int fd
, const char *path
) {
232 r
= chattr_fd(fd
, FS_NOCOW_FL
, FS_NOCOW_FL
);
234 return log_full_errno(
235 ERRNO_IS_IOCTL_NOT_SUPPORTED(r
) ? LOG_DEBUG
: LOG_WARNING
,
236 r
, "Failed to set file attributes on %s: %m", path
);