1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
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.
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.
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/>.
25 #include "btrfs-util.h"
26 #include "import-util.h"
28 #define FILENAME_ESCAPE "/.#\"\'"
30 bool http_etag_is_valid(const char *etag) {
31 if (!endswith(etag, "\""))
34 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
40 int import_find_old_etags(const char *url, const char *image_root, int dt, const char *prefix, const char *suffix, char ***etags) {
41 _cleanup_free_ char *escaped_url = NULL;
42 _cleanup_closedir_ DIR *d = NULL;
43 _cleanup_strv_free_ char **l = NULL;
51 image_root = "/var/lib/machines";
53 escaped_url = xescape(url, FILENAME_ESCAPE);
57 d = opendir(image_root);
59 if (errno == ENOENT) {
67 FOREACH_DIRENT_ALL(de, d, return -errno) {
71 if (de->d_type != DT_UNKNOWN &&
76 a = startswith(de->d_name, prefix);
82 a = startswith(a, escaped_url);
86 a = startswith(a, ".");
91 b = endswith(de->d_name, suffix);
95 b = strchr(de->d_name, 0);
100 u = cunescape_length(a, b - a);
104 if (!http_etag_is_valid(u)) {
109 r = strv_consume(&l, u);
120 int import_make_local_copy(const char *final, const char *image_root, const char *local, bool force_local) {
128 image_root = "/var/lib/machines";
130 p = strappenda(image_root, "/", local);
133 (void) btrfs_subvol_remove(p);
134 (void) rm_rf_dangerous(p, false, true, false);
137 r = btrfs_subvol_snapshot(final, p, false, false);
139 r = copy_tree(final, p, false);
141 return log_error_errno(r, "Failed to copy image: %m");
143 return log_error_errno(r, "Failed to create local image: %m");
145 log_info("Created new local image '%s'.", local);
150 int import_make_read_only(const char *path) {
153 r = btrfs_subvol_set_read_only(path, true);
159 return log_error_errno(errno, "Failed to stat temporary image: %m");
161 if (chmod(path, st.st_mode & 0755) < 0)
162 return log_error_errno(errno, "Failed to chmod() final image: %m");
167 return log_error_errno(r, "Failed to mark final image read-only: %m");
172 int import_make_path(const char *url, const char *etag, const char *image_root, const char *prefix, const char *suffix, char **ret) {
173 _cleanup_free_ char *escaped_url = NULL;
180 image_root = "/var/lib/machines";
182 escaped_url = xescape(url, FILENAME_ESCAPE);
187 _cleanup_free_ char *escaped_etag = NULL;
189 escaped_etag = xescape(etag, FILENAME_ESCAPE);
193 path = strjoin(image_root, "/", strempty(prefix), escaped_url, ".", escaped_etag, strempty(suffix), NULL);
195 path = strjoin(image_root, "/", strempty(prefix), escaped_url, strempty(suffix), NULL);