common: Support different digest algorithms for ssh fingerprints.
[gnupg.git] / common / membuf.c
index c3480df..18a971d 100644 (file)
@@ -1,5 +1,6 @@
 /* membuf.c - A simple implementation of a dynamic buffer.
  * Copyright (C) 2001, 2003, 2009, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
  *
  * This file is part of GnuPG.
  *
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <stdlib.h>
 #include <errno.h>
-
-#include "membuf.h"
+#include <stdarg.h>
 
 #include "util.h"
+#include "membuf.h"
 
 
 /* A simple implementation of a dynamic buffer.  Use init_membuf() to
@@ -66,7 +67,7 @@ init_membuf_secure (membuf_t *mb, int initiallen)
 }
 
 
-/* Shift the the content of the membuf MB by AMOUNT bytes.  The next
+/* Shift the content of the membuf MB by AMOUNT bytes.  The next
    operation will then behave as if AMOUNT bytes had not been put into
    the buffer.  If AMOUNT is greater than the actual accumulated
    bytes, the membuf is basically reset to its initial state.  */
@@ -115,6 +116,20 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
 }
 
 
+/* A variant of put_membuf accepting a void * and returning a
+   gpg_error_t (which will always return 0) to be used as a generic
+   callback handler.  This function also allows buffer to be NULL.  */
+gpg_error_t
+put_membuf_cb (void *opaque, const void *buf, size_t len)
+{
+  membuf_t *data = opaque;
+
+  if (buf)
+    put_membuf (data, buf, len);
+  return 0;
+}
+
+
 void
 put_membuf_str (membuf_t *mb, const char *string)
 {
@@ -122,6 +137,26 @@ put_membuf_str (membuf_t *mb, const char *string)
 }
 
 
+void
+put_membuf_printf (membuf_t *mb, const char *format, ...)
+{
+  int rc;
+  va_list arg_ptr;
+  char *buf;
+
+  va_start (arg_ptr, format);
+  rc = gpgrt_vasprintf (&buf, format, arg_ptr);
+  if (rc < 0)
+    mb->out_of_core = errno ? errno : ENOMEM;
+  va_end (arg_ptr);
+  if (rc >= 0)
+    {
+      put_membuf (mb, buf, strlen (buf));
+      xfree (buf);
+    }
+}
+
+
 void *
 get_membuf (membuf_t *mb, size_t *len)
 {
@@ -148,6 +183,31 @@ get_membuf (membuf_t *mb, size_t *len)
 }
 
 
+/* Same as get_membuf but shrinks the reallocated space to the
+   required size.  */
+void *
+get_membuf_shrink (membuf_t *mb, size_t *len)
+{
+  void *p, *pp;
+  size_t dummylen;
+
+  if (!len)
+    len = &dummylen;
+
+  p = get_membuf (mb, len);
+  if (!p)
+    return NULL;
+  if (*len)
+    {
+      pp = xtryrealloc (p, *len);
+      if (pp)
+        p = pp;
+    }
+
+  return p;
+}
+
+
 /* Peek at the membuf MB.  On success a pointer to the buffer is
    returned which is valid until the next operation on MB.  If LEN is
    not NULL the current LEN of the buffer is stored there.  On error