From f87a4724c29363fe3d4cea96bd4fc995e6e5b19a Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Mon, 24 Sep 2007 21:08:03 -0400 Subject: [PATCH] Added the COMPRESS and DECOMPRESS status messages. Both output the number of bytes processed so far along with the total number of bytes to be processed. The frequency of the output is determined by the new zlib_bufsize configuration parameter which sets the input and output buffer chunk size. Note that COMPRESS shows the number of uncompressed bytes in the document while DECOMPRESS shows the number of processed compressed bytes. --- configure.ac | 3 ++ src/commands.c | 115 +++++++++++++++++++++++++++++++++++++++++++-------------- src/common.h | 9 +++-- src/pwmd.c | 7 ++++ 4 files changed, 102 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index dab95c3e..461d9f77 100644 --- a/configure.ac +++ b/configure.ac @@ -124,6 +124,9 @@ AC_ARG_ENABLE(mem_debug, AC_HELP_STRING([--enable-mem-debug], [Enable memory deb AC_DEFINE([DEFAULT_RECURSION_DEPTH], 20, \ [Default number of target recursions before returning an error.]) +AC_DEFINE([DEFAULT_ZLIB_BUFSIZE], 4096, \ + [Default input and output buffer chunk sizes. Affects status messages.]) + AM_CONDITIONAL(MEM_DEBUG, test x"${ac_cv_sys_mem_debug}" != xno) AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile po/Makefile.in]) AC_OUTPUT diff --git a/src/commands.c b/src/commands.c index 42b106ff..d90751b8 100644 --- a/src/commands.c +++ b/src/commands.c @@ -48,8 +48,6 @@ #include "commands.h" #ifdef HAVE_ZLIB_H -#define Z_BUFSIZE 2048 - static void *z_alloc(void *data, unsigned items, unsigned size) { #ifndef MEM_DEBUG @@ -187,18 +185,27 @@ static gchar *print_fmt(const char *fmt, ...) } #ifdef HAVE_ZLIB_H +/* + * FIXME + * + * insize is the new size after realloc() to the required gcrypt blocksize + * which isn't the actual length of the data so the final status message + * totals will be wrong. Better to store the length of the data in the gzip + * header and use that instead. + */ gboolean do_decompress(assuan_context_t ctx, gpointer in, gint insize, gpointer *out, glong *outsize, gint *error) { z_stream z; gint ret; gpointer pout; + gint cmd = Z_NO_FLUSH; z.zalloc = z_alloc; z.zfree = z_free; z.next_in = in; - z.avail_in = insize; - z.next_out = pout = g_malloc(Z_BUFSIZE); + z.avail_in = zlib_bufsize; + z.next_out = pout = g_malloc(zlib_bufsize); if (!pout) { log_write("%s(%i): %s", __FUNCTION__, __LINE__, strerror(ENOMEM)); @@ -206,7 +213,7 @@ gboolean do_decompress(assuan_context_t ctx, gpointer in, gint insize, return FALSE; } - z.avail_out = Z_BUFSIZE; + z.avail_out = zlib_bufsize; ret = inflateInit(&z); if (ret != Z_OK) { @@ -219,22 +226,40 @@ gboolean do_decompress(assuan_context_t ctx, gpointer in, gint insize, do { gpointer p; - ret = inflate(&z, Z_FINISH); + ret = inflate(&z, cmd); switch (ret) { case Z_OK: break; case Z_BUF_ERROR: - p = g_realloc(pout, z.total_out + Z_BUFSIZE); + if (!z.avail_out) { + p = g_realloc(pout, z.total_out + zlib_bufsize); + + if (!p) { + ret = Z_MEM_ERROR; + goto fail; + } + + pout = p; + z.next_out = pout + z.total_out; + z.avail_out = zlib_bufsize; + } + + if (!z.avail_in && z.total_in < insize) { + if (z.total_in + zlib_bufsize > insize) + z.avail_in = insize - z.total_in; + else + z.avail_in = zlib_bufsize; + + z.next_in = in + z.total_in; - if (!p) { - ret = Z_MEM_ERROR; - goto fail; + if (ctx) + assuan_write_status(ctx, "DECOMPRESS", + print_fmt("%i %i", z.total_in, insize)); } + else if (!z.avail_in) + cmd = Z_FINISH; - pout = p; - z.next_out = pout + z.total_out; - z.avail_out = Z_BUFSIZE; break; case Z_STREAM_END: break; @@ -244,6 +269,10 @@ gboolean do_decompress(assuan_context_t ctx, gpointer in, gint insize, } } while (ret != Z_STREAM_END); + if (ctx) + assuan_write_status(ctx, "DECOMPRESS", + print_fmt("%i %i", z.total_in, insize)); + *out = pout; *outsize = z.total_out; inflateEnd(&z); @@ -450,14 +479,16 @@ gboolean do_compress(assuan_context_t ctx, gint level, gpointer data, gint size, gpointer *out, glong *outsize, gint *error) { z_stream z; - gpointer pout; + gpointer pout, pin; gint ret; + gint total = 0; + gint cmd = Z_NO_FLUSH; z.zalloc = z_alloc; z.zfree = z_free; - z.next_in = data; - z.avail_in = size; - z.next_out = pout = g_malloc(Z_BUFSIZE); + z.next_in = pin = data; + z.avail_in = zlib_bufsize; + z.next_out = pout = g_malloc(zlib_bufsize); if (!pout) { log_write("%s(%i): %s", __FUNCTION__, __LINE__, strerror(ENOMEM)); @@ -465,7 +496,7 @@ gboolean do_compress(assuan_context_t ctx, gint level, gpointer data, return FALSE; } - z.avail_out = Z_BUFSIZE; + z.avail_out = zlib_bufsize; ret = deflateInit(&z, level); if (ret != Z_OK) { @@ -479,20 +510,48 @@ gboolean do_compress(assuan_context_t ctx, gint level, gpointer data, do { gpointer p; - ret = deflate(&z, Z_FINISH); + ret = deflate(&z, cmd); switch (ret) { case Z_OK: - p = g_realloc(pout, z.total_out + Z_BUFSIZE); + break; + case Z_BUF_ERROR: + if (!z.avail_out) { + p = g_realloc(pout, z.total_out + zlib_bufsize); - if (!p) { - ret = Z_MEM_ERROR; - goto fail; + if (!p) { + ret = Z_MEM_ERROR; + goto fail; + } + + pout = p; + z.next_out = pout + z.total_out; + z.avail_out = zlib_bufsize; + } + + if (!z.avail_in) { + if (total >= size) { + cmd = Z_FINISH; + break; + } + + if (total + zlib_bufsize > size) { + z.avail_in = size - total; + total += size - total; + } + else { + total += zlib_bufsize; + z.avail_in = zlib_bufsize; + } + + pin += zlib_bufsize; + z.next_in = pin; + + if (ctx) + assuan_write_status(ctx, "COMPRESS", + print_fmt("%i %i", total, size)); } - pout = p; - z.next_out = pout + z.total_out; - z.avail_out = Z_BUFSIZE; break; case Z_STREAM_END: break; @@ -516,7 +575,7 @@ fail: #endif gpg_error_t do_xml_encrypt(struct client_s *client, gcry_cipher_hd_t gh, - const gchar *filename, gpointer data, size_t insize, + const gchar *filename, gpointer data, size_t insize, const guchar *shakey, guint iter) { gsize len = insize; @@ -2274,7 +2333,7 @@ gpg_error_t try_xml_decrypt(assuan_context_t ctx, gint fd, struct stat st, gcry_free(iv); #ifdef HAVE_ZLIB_H - if (do_decompress(NULL, inbuf, insize, &outbuf, &outsize, &zerror) == FALSE) { + if (do_decompress(ctx, inbuf, insize, &outbuf, &outsize, &zerror) == FALSE) { /* * Z_DATA_ERROR may be returned if this file hasn't been compressed yet. */ diff --git a/src/common.h b/src/common.h index 7d8a5b01..e4794a6e 100644 --- a/src/common.h +++ b/src/common.h @@ -50,7 +50,10 @@ struct client_s { gcry_error_t gcryerrno; gsize gcrykeysize, gcryblocksize; GKeyFile *keyfileh; -int max_recursion_depth; +gint max_recursion_depth; +#ifdef HAVE_ZLIB_H +gint zlib_bufsize; +#endif void log_write(const gchar *fmt, ...); gpg_error_t send_error(assuan_context_t ctx, gpg_error_t pwmd_errno); @@ -59,7 +62,7 @@ gboolean decrypt_xml(gcry_cipher_hd_t gh, void *outbuf, gsize outsize, void *inbuf, gsize insize); gint open_file(const gchar *filename, struct stat *st); gpg_error_t do_xml_encrypt(struct client_s *client, gcry_cipher_hd_t gh, - const gchar *filename, gpointer data, size_t insize, + const gchar *filename, gpointer data, size_t insize, const guchar *shakey, guint iter); gint get_key_file_integer(const gchar *section, const gchar *what); gboolean get_key_file_boolean(const gchar *section, const gchar *what); @@ -70,8 +73,6 @@ gboolean valid_filename(const gchar *filename); #ifdef HAVE_ZLIB_H gboolean do_compress(assuan_context_t ctx, gint level, gpointer data, gint size, gpointer *out, glong *outsize, gint *error); -gboolean do_decompress(assuan_context_t ctx, gpointer in, gint insize, - gpointer *out, glong *outsize, gint *error); #endif #endif diff --git a/src/pwmd.c b/src/pwmd.c index a9f7f852..fb10fa63 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -368,6 +368,13 @@ static void set_rcfile_defaults(GKeyFile *kf) if (g_key_file_has_key(kf, "default", "recursion_depth", NULL) == FALSE) g_key_file_set_integer(kf, "default", "recursion_depth", DEFAULT_RECURSION_DEPTH); +#ifdef HAVE_ZLIB_H + if (g_key_file_has_key(kf, "default", "zlib_bufsize", NULL) == FALSE) + g_key_file_set_integer(kf, "default", "zlib_bufsize", DEFAULT_ZLIB_BUFSIZE); + + zlib_bufsize = g_key_file_get_integer(kf, "default", "zlib_bufsize", NULL); +#endif + max_recursion_depth = g_key_file_get_integer(kf, "default", "recursion_depth", NULL); disable_list_and_dump = g_key_file_get_boolean(kf, "default", "disable_list_and_dump", NULL); -- 2.11.4.GIT