core: Make use of the "size-hint" in engine-gpg.

* src/engine-gpg.c: Include data.h.
(add_input_size_hint): New.
(gpg_decrypt, gpg_encrypt, gpg_encrypt_sign, gpg_sign)
(gpg_verify): Call new function,

* tests/run-encrypt.c (status_cb): Print to stderr.
(progress_cb): New.o
(main): Add option --progress.  Print full-status lines.  Provide a
size for the input data.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-08-12 15:24:46 +02:00
parent 293d173691
commit fe1e8e71aa
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 134 additions and 4 deletions

View File

@ -2177,6 +2177,30 @@ The function @code{gpgme_data_set_encoding} changes the encoding of
the data object with the handle @var{dh} to @var{enc}. the data object with the handle @var{dh} to @var{enc}.
@end deftypefun @end deftypefun
@deftypefun {gpgme_error_t} gpgme_data_set_flag @
(@w{gpgme_data_t @var{dh}}, @
@w{const char *@var{name}}, @
@w{const char *@var{value}})
Some minor properties of the data object can be controlled with flags
set by this function. The properties are identified by the following
values for @var{name}:
@table @code
@item size-hint
The value is a decimal number with the length gpgme shall assume for
this data object. This is useful if the data is provided by callbacks
or via file descriptors but the applications knows the total size of
the data. If this is set the OpenPGP engine may use this to decide on
buffer allocation strategies and to provide a total value for its
progress information.
@end table
This function returns @code{0} on success.
@end deftypefun
@node Data Buffer Convenience @node Data Buffer Convenience
@subsection Data Buffer Convenience Functions @subsection Data Buffer Convenience Functions
@cindex data buffer, convenience @cindex data buffer, convenience

View File

@ -42,6 +42,7 @@
#include "priv-io.h" #include "priv-io.h"
#include "sema.h" #include "sema.h"
#include "debug.h" #include "debug.h"
#include "data.h"
#include "engine-backend.h" #include "engine-backend.h"
@ -1483,6 +1484,35 @@ start (engine_gpg_t gpg)
} }
/* Add the --input-size-hint option if requested. */
static gpgme_error_t
add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
{
gpgme_error_t err;
gpgme_off_t value = _gpgme_data_get_size_hint (data);
char numbuf[50]; /* Large enough for even 2^128 in base-10. */
char *p;
if (!value || !have_gpg_version (gpg, "2.1.15"))
return 0;
err = add_arg (gpg, "--input-size-hint");
if (!err)
{
p = numbuf + sizeof numbuf;
*--p = 0;
do
{
*--p = '0' + (value % 10);
value /= 10;
}
while (value);
err = add_arg (gpg, p);
}
return err;
}
static gpgme_error_t static gpgme_error_t
gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
{ {
@ -1498,6 +1528,8 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
err = add_arg (gpg, "-"); err = add_arg (gpg, "-");
if (!err) if (!err)
err = add_data (gpg, plain, 1, 1); err = add_data (gpg, plain, 1, 1);
if (!err)
err = add_input_size_hint (gpg, ciph);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)
@ -1763,6 +1795,8 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err) if (!err)
err = add_arg (gpg, gpgme_data_get_file_name (plain)); err = add_arg (gpg, gpgme_data_get_file_name (plain));
} }
if (!err)
err = add_input_size_hint (gpg, plain);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)
@ -1836,6 +1870,8 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err) if (!err)
err = add_arg (gpg, gpgme_data_get_file_name (plain)); err = add_arg (gpg, gpgme_data_get_file_name (plain));
} }
if (!err)
err = add_input_size_hint (gpg, plain);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)
@ -2291,7 +2327,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
err = add_arg (gpg, "--with-colons"); err = add_arg (gpg, "--with-colons");
/* Since gpg 2.1.15 fingerprints are always printed, thus there is /* Since gpg 2.1.15 fingerprints are always printed, thus there is
* no more need to explictly reqeust them. */ * no more need to explictly request them. */
if (!have_gpg_version (gpg, "2.1.15")) if (!have_gpg_version (gpg, "2.1.15"))
{ {
if (!err) if (!err)
@ -2435,6 +2471,8 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
} }
/* Tell the gpg object about the data. */ /* Tell the gpg object about the data. */
if (!err)
err = add_input_size_hint (gpg, in);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)
@ -2481,10 +2519,11 @@ gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (plaintext) if (plaintext)
{ {
/* Normal or cleartext signature. */ /* Normal or cleartext signature. */
err = add_arg (gpg, "--output"); err = add_arg (gpg, "--output");
if (!err) if (!err)
err = add_arg (gpg, "-"); err = add_arg (gpg, "-");
if (!err)
err = add_input_size_hint (gpg, sig);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)
@ -2495,6 +2534,8 @@ gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
else else
{ {
err = add_arg (gpg, "--verify"); err = add_arg (gpg, "--verify");
if (!err)
err = add_input_size_hint (gpg, signed_text);
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)

View File

@ -36,15 +36,32 @@
static int verbose; static int verbose;
static gpg_error_t static gpg_error_t
status_cb (void *opaque, const char *keyword, const char *value) status_cb (void *opaque, const char *keyword, const char *value)
{ {
(void)opaque; (void)opaque;
printf ("status_cb: %s %s\n", keyword, value); fprintf (stderr, "status_cb: %s %s\n", nonnull(keyword), nonnull(value));
return 0; return 0;
} }
static void
progress_cb (void *opaque, const char *what, int type, int current, int total)
{
(void)opaque;
(void)type;
if (total)
fprintf (stderr, "progress for '%s' %u%% (%d of %d)\n",
nonnull (what),
(unsigned)(((double)current / total) * 100), current, total);
else
fprintf (stderr, "progress for '%s' %d\n", nonnull(what), current);
fflush (stderr);
}
static void static void
print_result (gpgme_encrypt_result_t result) print_result (gpgme_encrypt_result_t result)
{ {
@ -65,6 +82,7 @@ show_usage (int ex)
"Options:\n" "Options:\n"
" --verbose run in verbose mode\n" " --verbose run in verbose mode\n"
" --status print status lines from the backend\n" " --status print status lines from the backend\n"
" --progress print progress info\n"
" --openpgp use the OpenPGP protocol (default)\n" " --openpgp use the OpenPGP protocol (default)\n"
" --cms use the CMS protocol\n" " --cms use the CMS protocol\n"
" --uiserver use the UI server\n" " --uiserver use the UI server\n"
@ -87,12 +105,14 @@ main (int argc, char **argv)
gpgme_data_t in, out; gpgme_data_t in, out;
gpgme_encrypt_result_t result; gpgme_encrypt_result_t result;
int print_status = 0; int print_status = 0;
int print_progress = 0;
int use_loopback = 0; int use_loopback = 0;
char *keyargs[10]; char *keyargs[10];
gpgme_key_t keys[10+1]; gpgme_key_t keys[10+1];
int keycount = 0; int keycount = 0;
int i; int i;
gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
gpgme_off_t offset;
if (argc) if (argc)
{ argc--; argv++; } { argc--; argv++; }
@ -120,6 +140,11 @@ main (int argc, char **argv)
print_status = 1; print_status = 1;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--progress"))
{
print_progress = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--openpgp")) else if (!strcmp (*argv, "--openpgp"))
{ {
protocol = GPGME_PROTOCOL_OpenPGP; protocol = GPGME_PROTOCOL_OpenPGP;
@ -179,7 +204,12 @@ main (int argc, char **argv)
gpgme_set_protocol (ctx, protocol); gpgme_set_protocol (ctx, protocol);
gpgme_set_armor (ctx, 1); gpgme_set_armor (ctx, 1);
if (print_status) if (print_status)
gpgme_set_status_cb (ctx, status_cb, NULL); {
gpgme_set_status_cb (ctx, status_cb, NULL);
gpgme_set_ctx_flag (ctx, "full-status", "1");
}
if (print_progress)
gpgme_set_progress_cb (ctx, progress_cb, NULL);
if (use_loopback) if (use_loopback)
{ {
gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
@ -200,6 +230,41 @@ main (int argc, char **argv)
*argv, gpg_strerror (err)); *argv, gpg_strerror (err));
exit (1); exit (1);
} }
offset = gpgme_data_seek (in, 0, SEEK_END);
if (offset == (gpgme_off_t)(-1))
{
err = gpg_error_from_syserror ();
fprintf (stderr, PGM ": error seeking `%s': %s\n",
*argv, gpg_strerror (err));
exit (1);
}
if (gpgme_data_seek (in, 0, SEEK_SET) == (gpgme_off_t)(-1))
{
err = gpg_error_from_syserror ();
fprintf (stderr, PGM ": error seeking `%s': %s\n",
*argv, gpg_strerror (err));
exit (1);
}
{
char numbuf[50];
char *p;
p = numbuf + sizeof numbuf;
*--p = 0;
do
{
*--p = '0' + (offset % 10);
offset /= 10;
}
while (offset);
err = gpgme_data_set_flag (in, "size-hint", p);
if (err)
{
fprintf (stderr, PGM ": error setting size-hint for `%s': %s\n",
*argv, gpg_strerror (err));
exit (1);
}
}
err = gpgme_data_new (&out); err = gpgme_data_new (&out);
fail_if_err (err); fail_if_err (err);