+static int gpt_import_file_make_final_path(GptImportFile *f) {
+ _cleanup_free_ char *escaped_url = NULL, *escaped_etag = NULL;
+
+ assert(f);
+
+ if (f->final_path)
+ return 0;
+
+ escaped_url = xescape(f->url, FILENAME_ESCAPE);
+ if (!escaped_url)
+ return -ENOMEM;
+
+ if (f->etag) {
+ escaped_etag = xescape(f->etag, FILENAME_ESCAPE);
+ if (!escaped_etag)
+ return -ENOMEM;
+
+ f->final_path = strjoin("/var/lib/container/.gpt-", escaped_url, ".", escaped_etag, ".gpt", NULL);
+ } else
+ f->final_path = strjoin("/var/lib/container/.gpt-", escaped_url, ".gpt", NULL);
+ if (!f->final_path)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void gpt_import_file_success(GptImportFile *f) {
+ int r;
+
+ assert(f);
+
+ f->done = true;
+
+ if (f->local) {
+ _cleanup_free_ char *tp = NULL;
+ _cleanup_close_ int dfd = -1;
+ const char *p;
+
+ if (f->disk_fd >= 0) {
+ if (lseek(f->disk_fd, SEEK_SET, 0) == (off_t) -1) {
+ r = log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
+ goto finish;
+ }
+ } else {
+ r = gpt_import_file_make_final_path(f);
+ if (r < 0) {
+ log_oom();
+ goto finish;
+ }
+
+ f->disk_fd = open(f->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+ if (f->disk_fd < 0) {
+ r = log_error_errno(errno, "Failed top open vendor image: %m");
+ goto finish;
+ }
+ }
+
+ p = strappenda("/var/lib/container/", f->local, ".gpt");
+ if (f->force_local)
+ (void) rm_rf_dangerous(p, false, true, false);
+
+ r = tempfn_random(p, &tp);
+ if (r < 0) {
+ log_oom();
+ goto finish;
+ }
+
+ dfd = open(tp, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
+ if (dfd < 0) {
+ r = log_error_errno(errno, "Failed to create writable copy of image: %m");
+ goto finish;
+ }
+
+ r = copy_bytes(f->disk_fd, dfd, (off_t) -1, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to make writable copy of image: %m");
+ unlink(tp);
+ goto finish;
+ }
+
+ (void) copy_times(f->disk_fd, dfd);
+ (void) copy_xattr(f->disk_fd, dfd);
+
+ dfd = safe_close(dfd);
+
+ r = rename(tp, p);
+ if (r < 0) {
+ r = log_error_errno(errno, "Failed to move writable image into place: %m");
+ unlink(tp);
+ goto finish;
+ }
+
+ log_info("Created new local image %s.", p);
+ }
+
+ f->disk_fd = safe_close(f->disk_fd);
+ r = 0;
+
+finish:
+ gpt_import_finish(f->import, r);
+}
+