From c81e115bb2ef60d3cae457e90df0200f5378dda9 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 28 Mar 2017 15:09:27 +0200 Subject: [PATCH] OCI: Add flatpak_archive_read_open_fd_with_checksum This will let us do the layer sha256 checksum during layer apply, which means we don't read it multiple times, and that its not modified inbetween. --- common/flatpak-oci-registry.c | 80 +++++++++++++++++++++++++++++++++++ common/flatpak-oci-registry.h | 5 +++ 2 files changed, 85 insertions(+) diff --git a/common/flatpak-oci-registry.c b/common/flatpak-oci-registry.c index 520b3b8f..978f55f1 100644 --- a/common/flatpak-oci-registry.c +++ b/common/flatpak-oci-registry.c @@ -1217,3 +1217,83 @@ flatpak_oci_layer_writer_get_archive (FlatpakOciLayerWriter *self) { return self->archive; } + +typedef struct { + int fd; + GChecksum *checksum; + char buffer[16*1024]; +} FlatpakArchiveReadWithChecksum; + +static int +checksum_open_cb (struct archive *a, void *user_data) +{ + return ARCHIVE_OK; +} + + +static ssize_t +checksum_read_cb (struct archive *a, void *user_data, const void **buff) +{ + FlatpakArchiveReadWithChecksum *data = user_data; + ssize_t bytes_read; + + *buff = &data->buffer; + do + bytes_read = read (data->fd, &data->buffer, sizeof (data->buffer)); + while (G_UNLIKELY (bytes_read == -1 && errno == EINTR)); + + if (bytes_read < 0) + { + archive_set_error (a, errno, "Read error on fd %d", data->fd); + return -1; + } + + g_checksum_update (data->checksum, (guchar *)data->buffer, bytes_read); + + return bytes_read; +} + +static int64_t +checksum_skip_cb (struct archive *a, void *user_data, int64_t request) +{ + FlatpakArchiveReadWithChecksum *data = user_data; + int64_t old_offset, new_offset; + + if (((old_offset = lseek (data->fd, 0, SEEK_CUR)) >= 0) && + ((new_offset = lseek (data->fd, request, SEEK_CUR)) >= 0)) + return new_offset - old_offset; + + archive_set_error (a, errno, "Error seeking"); + return -1; +} + +static int +checksum_close_cb (struct archive *a, void *user_data) +{ + FlatpakArchiveReadWithChecksum *data = user_data; + + g_free (data); + + return ARCHIVE_OK; +} + +gboolean +flatpak_archive_read_open_fd_with_checksum (struct archive *a, + int fd, + GChecksum *checksum, + GError **error) +{ + FlatpakArchiveReadWithChecksum *data = g_new0 (FlatpakArchiveReadWithChecksum, 1); + + data->fd = fd; + data->checksum = checksum; + + if (archive_read_open2 (a, data, + checksum_open_cb, + checksum_read_cb, + checksum_skip_cb, + checksum_close_cb) != ARCHIVE_OK) + return propagate_libarchive_error (error, a); + + return TRUE; +} diff --git a/common/flatpak-oci-registry.h b/common/flatpak-oci-registry.h index c00b0332..a721f4f9 100644 --- a/common/flatpak-oci-registry.h +++ b/common/flatpak-oci-registry.h @@ -110,4 +110,9 @@ gboolean flatpak_oci_layer_writer_close (FlatpakOciLayerWriter *se GCancellable *cancellable, GError **error); +gboolean flatpak_archive_read_open_fd_with_checksum (struct archive *a, + int fd, + GChecksum *checksum, + GError **error); + #endif /* __FLATPAK_OCI_REGISTRY_H__ */