tools: Allow retrieval of signed data from mime-maker.
authorWerner Koch <wk@gnupg.org>
Thu, 29 Sep 2016 15:38:06 +0000 (17:38 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 29 Sep 2016 15:56:37 +0000 (17:56 +0200)
* tools/mime-maker.c (find_part): New.
(mime_maker_get_part): New.

Signed-off-by: Werner Koch <wk@gnupg.org>
tools/mime-maker.c
tools/mime-maker.h

index 99185cf..a81bd69 100644 (file)
@@ -202,6 +202,22 @@ find_parent (part_t root, part_t needle)
   return NULL;
 }
 
+/* Find the part node from the PARTID.  */
+static part_t
+find_part (part_t root, unsigned int partid)
+{
+  part_t node, n;
+
+  for (node = root->child; node; node = node->next)
+    {
+      if (node->partid == partid)
+        return root;
+      if ((n = find_part (node, partid)))
+        return n;
+    }
+  return NULL;
+}
+
 
 /* Create a boundary string.  Outr codes is aware of the general
  * structure of that string (gebins with "=-=") so that
@@ -730,3 +746,54 @@ mime_maker_make (mime_maker_t ctx, estream_t fp)
   ctx->outfp = NULL;
   return err;
 }
+
+
+/* Create a stream object from the MIME part identified by PARTID and
+ * store it at R_STREAM.  If PARTID identifies a container the entire
+ * tree is returned. Using that function may read stream objects
+ * which have been added as MIME bodies.  The caller must close the
+ * stream object. */
+gpg_error_t
+mime_maker_get_part (mime_maker_t ctx, unsigned int partid, estream_t *r_stream)
+{
+  gpg_error_t err;
+  part_t part;
+  estream_t fp;
+
+  *r_stream = NULL;
+
+  /* When the entire tree is requested, we make sure that all missing
+   * headers are applied.  We don't do that if only a part is
+   * requested because the additional headers (like Date:) will only
+   * be added to part 0 headers anyway. */
+  if (!partid)
+    {
+       err = add_missing_headers (ctx);
+       if (err)
+         return err;
+       part = ctx->mail;
+    }
+  else
+    part = find_part (ctx->mail, partid);
+
+  /* For now we use a memory stream object; however it would also be
+   * possible to create an object created on the fly while the caller
+   * is reading the returned stream.  */
+  fp = es_fopenmem (0, "w+b");
+  if (!fp)
+    return gpg_error_from_syserror ();
+
+  ctx->outfp = fp;
+  err = write_tree (ctx, NULL, part);
+  ctx->outfp = NULL;
+
+  if (!err)
+    {
+      es_rewind (fp);
+      *r_stream = fp;
+    }
+  else
+    es_fclose (fp);
+
+  return err;
+}
index 2fac9c3..23047c3 100644 (file)
@@ -39,6 +39,8 @@ gpg_error_t mime_maker_end_container (mime_maker_t ctx);
 unsigned int mime_maker_get_partid (mime_maker_t ctx);
 
 gpg_error_t mime_maker_make (mime_maker_t ctx, estream_t fp);
+gpg_error_t mime_maker_get_part (mime_maker_t ctx, unsigned int partid,
+                                 estream_t *r_stream);