From f42cd70f18d53df47cc2d027bade736377d39b71 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 19 Jul 2018 09:50:30 +0200 Subject: [PATCH] core: New interface gpgme_data_new_from_estream. * src/gpgme.h.in (gpgme_data_new_from_estream): New. * src/data-estream.c: New. * src/data.h (gpgme_data): New union member e_stream. -- The estream functions (gpgrt_fopen et al.) are any waypart of the required libgpg-error library and thus it makes sense to provide this convenience interface. Signed-off-by: Werner Koch --- NEWS | 5 ++- doc/gpgme.texi | 19 +++++++++ src/Makefile.am | 1 + src/data-estream.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ src/data.h | 3 ++ src/gpgme.h.in | 2 + 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/data-estream.c diff --git a/NEWS b/NEWS index ae80642f..20a80e8d 100644 --- a/NEWS +++ b/NEWS @@ -7,13 +7,16 @@ Noteworthy changes in version 1.11.2 (unreleased) * Added context flag "auto-key-locate" to control the behavior of GPGME_KEYLIST_MODE_LOCATE. + * New data function to create a data object from an estream. + * Interface changes relative to the 1.11.1 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_data_new_from_estream NEW. gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc. gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'. GPGME_AUDITLOG_DEFAULT NEW. GPGME_AUDITLOG_DIAG NEW. - gpgme_set_ctx_flag EXTENDED: New flag 'auto-key-locate'. + gpgme_set_ctx_flag EXTENDED: New flag 'auto-key-locate'. cpp: DecryptionResult::sessionKey NEW. cpp: DecryptionResult::symkeyAlgo NEW. cpp: DecryptionResult::isLegacyCipherNoMDC New. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 38d34809..aff72405 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1909,6 +1909,25 @@ data object was successfully created, and @code{GPG_ERR_ENOMEM} if not enough memory is available. @end deftypefun +@deftypefun gpgme_error_t gpgme_data_new_from_estream (@w{gpgme_data_t *@var{dh}}, @w{gpgrt_stream_t @var{stream}}) +The function @code{gpgme_data_new_from_estream} creates a new +@code{gpgme_data_t} object and uses the gpgrt stream @var{stream} to read +from (if used as an input data object) and write to (if used as an +output data object). + +When using the data object as an input buffer, the function might read +a bit more from the stream than is actually needed by the crypto +engine in the desired operation because of internal buffering. + +Note that GPGME assumes that the stream is in blocking mode. Errors +during I/O operations, except for EINTR, are usually fatal for crypto +operations. + +The function returns the error code @code{GPG_ERR_NO_ERROR} if the +data object was successfully created, and @code{GPG_ERR_ENOMEM} if not +enough memory is available. +@end deftypefun + @node Callback Based Data Buffers @subsection Callback Based Data Buffers diff --git a/src/Makefile.am b/src/Makefile.am index 0a196e0c..1394c028 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,6 +70,7 @@ main_sources = \ parsetlv.c parsetlv.h \ mbox-util.c mbox-util.h \ data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \ + data-estream.c \ data-compat.c data-identify.c \ signers.c sig-notation.c \ wait.c wait-global.c wait-private.c wait-user.c wait.h \ diff --git a/src/data-estream.c b/src/data-estream.c new file mode 100644 index 00000000..34f88a7f --- /dev/null +++ b/src/data-estream.c @@ -0,0 +1,99 @@ +/* data-stream.c - A stream based data object. + * Copyright (C) 2002, 2004, 2018 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include "debug.h" +#include "data.h" + + +static gpgme_ssize_t +stream_es_read (gpgme_data_t dh, void *buffer, size_t size) +{ + size_t amt = gpgrt_fread (buffer, 1, size, dh->data.e_stream); + if (amt > 0) + return amt; + return gpgrt_ferror (dh->data.e_stream) ? -1 : 0; +} + + +static gpgme_ssize_t +stream_es_write (gpgme_data_t dh, const void *buffer, size_t size) +{ + size_t amt = gpgrt_fwrite (buffer, 1, size, dh->data.e_stream); + if (amt > 0) + return amt; + return gpgrt_ferror (dh->data.e_stream) ? -1 : 0; +} + + +static gpgme_off_t +stream_es_seek (gpgme_data_t dh, gpgme_off_t offset, int whence) +{ + int err; + + err = gpgrt_fseeko (dh->data.e_stream, offset, whence); + if (err) + return -1; + + return gpgrt_ftello (dh->data.e_stream); +} + + +static int +stream_es_get_fd (gpgme_data_t dh) +{ + gpgrt_fflush (dh->data.e_stream); + return gpgrt_fileno (dh->data.e_stream); +} + + +static struct _gpgme_data_cbs stream_es_cbs = + { + stream_es_read, + stream_es_write, + stream_es_seek, + NULL, + stream_es_get_fd + }; + + + +gpgme_error_t +gpgme_data_new_from_estream (gpgme_data_t *r_dh, gpgrt_stream_t stream) +{ + gpgme_error_t err; + TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_estream", r_dh, "estream=%p", + stream); + + err = _gpgme_data_new (r_dh, &stream_es_cbs); + if (err) + return TRACE_ERR (err); + + (*r_dh)->data.e_stream = stream; + return TRACE_SUC1 ("dh=%p", *r_dh); +} diff --git a/src/data.h b/src/data.h index 0a15b613..f12508b9 100644 --- a/src/data.h +++ b/src/data.h @@ -100,6 +100,9 @@ struct gpgme_data /* For gpgme_data_new_from_stream. */ FILE *stream; + /* For gpgme_data_new_from_estream. */ + gpgrt_stream_t e_stream; + /* For gpgme_data_new_from_cbs. */ struct { diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 421199a9..35968017 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1180,6 +1180,8 @@ gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *dh, gpgme_error_t gpgme_data_new_from_fd (gpgme_data_t *dh, int fd); gpgme_error_t gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream); +gpgme_error_t gpgme_data_new_from_estream (gpgme_data_t *r_dh, + gpgrt_stream_t stream); /* Return the encoding attribute of the data buffer DH */ gpgme_data_encoding_t gpgme_data_get_encoding (gpgme_data_t dh);