+
+ if (unlikely(filedes_valid(&ctx->tmpfile_fd))) {
+ /* Just extracting to temporary file for now. */
+ ret = full_write(&ctx->tmpfile_fd, chunk, size);
+ if (ret) {
+ ERROR_WITH_ERRNO("Error writing data to "
+ "temporary file \"%"TS"\"",
+ ctx->tmpfile_name);
+ }
+ return ret;
+ }
+
+ return call_consume_chunk(chunk, size, ctx->saved_cbs);
+}
+
+/* Copy the blob's data from the temporary file to each of its targets.
+ *
+ * This is executed only in the very uncommon case that a blob is being
+ * extracted to more than MAX_OPEN_FILES targets! */
+static int
+extract_from_tmpfile(const tchar *tmpfile_name,
+ const struct blob_descriptor *orig_blob,
+ const struct read_blob_callbacks *cbs)
+{
+ struct blob_descriptor tmpfile_blob;
+ const struct blob_extraction_target *targets = blob_extraction_targets(orig_blob);
+ int ret;
+
+ memcpy(&tmpfile_blob, orig_blob, sizeof(struct blob_descriptor));
+ tmpfile_blob.blob_location = BLOB_IN_FILE_ON_DISK;
+ tmpfile_blob.file_on_disk = (tchar *)tmpfile_name;
+ tmpfile_blob.out_refcnt = 1;
+
+ for (u32 i = 0; i < orig_blob->out_refcnt; i++) {
+ tmpfile_blob.inline_blob_extraction_targets[0] = targets[i];
+ ret = read_blob_with_cbs(&tmpfile_blob, cbs);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int
+end_extract_blob_wrapper(struct blob_descriptor *blob, int status, void *_ctx)
+{
+ struct apply_ctx *ctx = _ctx;
+
+ if (unlikely(filedes_valid(&ctx->tmpfile_fd))) {
+ filedes_close(&ctx->tmpfile_fd);
+ if (!status)
+ status = extract_from_tmpfile(ctx->tmpfile_name, blob,
+ ctx->saved_cbs);
+ filedes_invalidate(&ctx->tmpfile_fd);
+ tunlink(ctx->tmpfile_name);
+ FREE(ctx->tmpfile_name);
+ return status;
+ }
+
+ return call_end_blob(blob, status, ctx->saved_cbs);