import-util.c revision 8f6950587ab7b4d6fe1b51241759cc3a4682b96d
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering/***
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering This file is part of systemd.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering Copyright 2015 Lennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering systemd is free software; you can redistribute it and/or modify it
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering under the terms of the GNU Lesser General Public License as published by
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering (at your option) any later version.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering systemd is distributed in the hope that it will be useful, but
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering Lesser General Public License for more details.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering You should have received a copy of the GNU Lesser General Public License
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering***/
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "util.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "strv.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "copy.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "btrfs-util.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include "import-util.h"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#define FILENAME_ESCAPE "/.#\"\'"
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringbool http_etag_is_valid(const char *etag) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!endswith(etag, "\""))
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return false;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return false;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return true;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_find_old_etags(const char *url, const char *image_root, int dt, const char *prefix, const char *suffix, char ***etags) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_free_ char *escaped_url = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_closedir_ DIR *d = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_strv_free_ char **l = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering struct dirent *de;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(url);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(etags);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!image_root)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering image_root = "/var/lib/machines";
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering escaped_url = xescape(url, FILENAME_ESCAPE);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering if (!escaped_url)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering d = opendir(image_root);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!d) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (errno == ENOENT) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *etags = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -errno;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering FOREACH_DIRENT_ALL(de, d, return -errno) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering const char *a, *b;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering char *u;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (de->d_type != DT_UNKNOWN &&
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering de->d_type != dt)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (prefix) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering a = startswith(de->d_name, prefix);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!a)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering } else
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering a = de->d_name;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering a = startswith(a, escaped_url);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!a)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering a = startswith(a, ".");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!a)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering if (suffix) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering b = endswith(de->d_name, suffix);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!b)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering } else
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering b = strchr(de->d_name, 0);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (a >= b)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering u = cunescape_length(a, b - a);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!u)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!http_etag_is_valid(u)) {
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering free(u);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering continue;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering r = strv_consume(&l, u);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return r;
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering }
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *etags = l;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering l = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_make_local_copy(const char *final, const char *image_root, const char *local, bool force_local) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering const char *p;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(final);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(local);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!image_root)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering image_root = "/var/lib/machines";
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p = strappenda(image_root, "/", local);
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (force_local) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering (void) btrfs_subvol_remove(p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering (void) rm_rf_dangerous(p, false, true, false);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering }
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = btrfs_subvol_snapshot(final, p, false, false);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r == -ENOTTY) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = copy_tree(final, p, false);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(r, "Failed to copy image: %m");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering } else if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(r, "Failed to create local image: %m");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering log_info("Created new local image '%s'.", local);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_make_read_only_fd(int fd) {
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering int r;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(fd >= 0);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* First, let's make this a read-only subvolume if it refers
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering * to a subvolume */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = btrfs_subvol_set_read_only_fd(fd, true);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r == -ENOTTY || r == -ENOTDIR || r == -EINVAL) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering struct stat st;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering /* This doesn't refer to a subvolume, or the file
b7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5dbLennart Poettering * system isn't even btrfs. In that, case fall back to
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering * chmod()ing */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering r = fstat(fd, &st);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(errno, "Failed to stat temporary image: %m");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering /* Drop "w" flag */
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (fchmod(fd, st.st_mode & 07555) < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(errno, "Failed to chmod() final image: %m");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering } else if (r < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(r, "Failed to make subvolume read-only: %m");
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_make_read_only(const char *path) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_close_ int fd = 1;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (fd < 0)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return log_error_errno(errno, "Failed to open %s: %m", path);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return import_make_read_only_fd(fd);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_make_path(const char *url, const char *etag, const char *image_root, const char *prefix, const char *suffix, char **ret) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_free_ char *escaped_url = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering char *path;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(url);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(ret);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!image_root)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering image_root = "/var/lib/machines";
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering escaped_url = xescape(url, FILENAME_ESCAPE);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!escaped_url)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (etag) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering _cleanup_free_ char *escaped_etag = NULL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering escaped_etag = xescape(etag, FILENAME_ESCAPE);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!escaped_etag)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering path = strjoin(image_root, "/", strempty(prefix), escaped_url, ".", escaped_etag, strempty(suffix), NULL);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering } else
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering path = strjoin(image_root, "/", strempty(prefix), escaped_url, strempty(suffix), NULL);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!path)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *ret = path;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_url_last_component(const char *url, char **ret) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering const char *e, *p;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering char *s;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e = strchrnul(url, '?');
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering while (e > url && e[-1] == '/')
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e--;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p = e;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering while (p > url && p[-1] != '/')
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering p--;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (e <= p)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -EINVAL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering s = strndup(p, e - p);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!s)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *ret = s;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringint import_url_change_last_component(const char *url, const char *suffix, char **ret) {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering const char *e;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering char *s;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(url);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering assert(ret);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e = strchrnul(url, '?');
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering while (e > url && e[-1] == '/')
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e--;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering while (e > url && e[-1] != '/')
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering e--;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (e <= url)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -EINVAL;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering s = new(char, (e - url) + strlen(suffix) + 1);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering if (!s)
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return -ENOMEM;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering strcpy(mempcpy(s, url, e - url), suffix);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering *ret = s;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering return 0;
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering}
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poetteringstatic const char* const import_verify_table[_IMPORT_VERIFY_MAX] = {
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering [IMPORT_VERIFY_NO] = "no",
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering [IMPORT_VERIFY_SUM] = "sum",
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering [IMPORT_VERIFY_SIGNATURE] = "signature",
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering};
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(import_verify, ImportVerify);
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering