aboutsummaryrefslogtreecommitdiffstats
path: root/sm/base64.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2007-03-19 15:44:59 +0000
committerWerner Koch <[email protected]>2007-03-19 15:44:59 +0000
commit9e95c2dff6374fea6007711635063d8c1ab4fb2b (patch)
tree257f186fed764c911913911ff35037a28ff11532 /sm/base64.c
parentChanges to let the key listing use estream to help systems without (diff)
downloadgnupg-9e95c2dff6374fea6007711635063d8c1ab4fb2b.tar.gz
gnupg-9e95c2dff6374fea6007711635063d8c1ab4fb2b.zip
Allow export to work on systems without funopen/fopencookie.
Diffstat (limited to 'sm/base64.c')
-rw-r--r--sm/base64.c130
1 files changed, 96 insertions, 34 deletions
diff --git a/sm/base64.c b/sm/base64.c
index 0c3ebd150..cc94d4b88 100644
--- a/sm/base64.c
+++ b/sm/base64.c
@@ -30,6 +30,7 @@
#include "gpgsm.h"
+
#include <ksba.h>
#include "i18n.h"
@@ -43,6 +44,7 @@
/* data used by the reader callbacks */
struct reader_cb_parm_s {
FILE *fp;
+
unsigned char line[1024];
int linelen;
int readpos;
@@ -71,7 +73,9 @@ struct reader_cb_parm_s {
/* data used by the writer callbacks */
struct writer_cb_parm_s {
- FILE *fp;
+ FILE *fp; /* FP is only used if STREAM is NULL. */
+ estream_t stream; /* Alternative output if not NULL. */
+
const char *pem_name;
int wrote_begin;
@@ -400,6 +404,27 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
+/* Call either es_putc or the plain putc. */
+static void
+do_putc (int value, FILE *fp, estream_t stream)
+{
+ if (stream)
+ es_putc (value, stream);
+ else
+ putc (value, fp);
+}
+
+/* Call either es_fputs or the plain fputs. */
+static void
+do_fputs (const char *string, FILE *fp, estream_t stream)
+{
+ if (stream)
+ es_fputs (string, stream);
+ else
+ fputs (string, fp);
+}
+
+
static int
base64_writer_cb (void *cb_value, const void *buffer, size_t count)
{
@@ -408,6 +433,7 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
int i, c, idx, quad_count;
const unsigned char *p;
FILE *fp = parm->fp;
+ estream_t stream = parm->stream;
if (!count)
return 0;
@@ -416,9 +442,9 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
{
if (parm->pem_name)
{
- fputs ("-----BEGIN ", fp);
- fputs (parm->pem_name, fp);
- fputs ("-----\n", fp);
+ do_fputs ("-----BEGIN ", fp, stream);
+ do_fputs (parm->pem_name, fp, stream);
+ do_fputs ("-----\n", fp, stream);
}
parm->wrote_begin = 1;
parm->base64.idx = 0;
@@ -437,16 +463,16 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
{
idx = 0;
c = bintoasc[(*radbuf >> 2) & 077];
- putc (c, fp);
+ do_putc (c, fp, stream);
c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
- putc (c, fp);
+ do_putc (c, fp, stream);
c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
- putc (c, fp);
+ do_putc (c, fp, stream);
c = bintoasc[radbuf[2]&077];
- putc (c, fp);
+ do_putc (c, fp, stream);
if (++quad_count >= (64/4))
{
- fputs (LF, fp);
+ do_fputs (LF, fp, stream);
quad_count = 0;
}
}
@@ -456,7 +482,31 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count)
parm->base64.idx = idx;
parm->base64.quad_count = quad_count;
- return ferror (fp) ? gpg_error_from_syserror () : 0;
+ return ((stream? es_ferror (stream) : ferror (fp))
+ ? gpg_error_from_syserror ()
+ : 0);
+}
+
+/* This callback is only used in stream mode. Hiowever, we don't
+ restrict it to this. */
+static int
+plain_writer_cb (void *cb_value, const void *buffer, size_t count)
+{
+ struct writer_cb_parm_s *parm = cb_value;
+ FILE *fp = parm->fp;
+ estream_t stream = parm->stream;
+
+ if (!count)
+ return 0;
+
+ if (stream)
+ es_write (stream, buffer, count, NULL);
+ else
+ fwrite (buffer, count, 1, fp);
+
+ return ((stream? es_ferror (stream) : ferror (fp))
+ ? gpg_error_from_syserror ()
+ : 0);
}
static int
@@ -465,9 +515,10 @@ base64_finish_write (struct writer_cb_parm_s *parm)
unsigned char radbuf[4];
int i, c, idx, quad_count;
FILE *fp = parm->fp;
+ estream_t stream = parm->stream;
if (!parm->wrote_begin)
- return 0; /* nothing written */
+ return 0; /* Nothing written or we are not called in base-64 mode. */
/* flush the base64 encoding */
idx = parm->base64.idx;
@@ -478,40 +529,43 @@ base64_finish_write (struct writer_cb_parm_s *parm)
if (idx)
{
c = bintoasc[(*radbuf>>2)&077];
- putc (c, fp);
+ do_putc (c, fp, stream);
if (idx == 1)
{
c = bintoasc[((*radbuf << 4) & 060) & 077];
- putc (c, fp);
- putc ('=', fp);
- putc ('=', fp);
+ do_putc (c, fp, stream);
+ do_putc ('=', fp, stream);
+ do_putc ('=', fp, stream);
}
else
{
c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
- putc (c, fp);
+ do_putc (c, fp, stream);
c = bintoasc[((radbuf[1] << 2) & 074) & 077];
- putc (c, fp);
- putc ('=', fp);
+ do_putc (c, fp, stream);
+ do_putc ('=', fp, stream);
}
if (++quad_count >= (64/4))
{
- fputs (LF, fp);
+ do_fputs (LF, fp, stream);
quad_count = 0;
}
}
if (quad_count)
- fputs (LF, fp);
+ do_fputs (LF, fp, stream);
if (parm->pem_name)
{
- fputs ("-----END ", fp);
- fputs (parm->pem_name, fp);
- fputs ("-----\n", fp);
+ do_fputs ("-----END ", fp, stream);
+ do_fputs (parm->pem_name, fp, stream);
+ do_fputs ("-----\n", fp, stream);
}
- return ferror (fp)? gpg_error (gpg_err_code_from_errno (errno)) : 0;
+
+ return ((stream? es_ferror (stream) : ferror (fp))
+ ? gpg_error_from_syserror ()
+ : 0);
}
@@ -597,15 +651,16 @@ gpgsm_destroy_reader (Base64Context ctx)
-/* Create a writer for the given stream. Depending on the control
- information an output encoding is automagically choosen. The
- function returns a Base64Context object which must be passed to the
- gpgme_destroy_writer function. The created KsbaWriter object is
- also returned, but the caller must not call the ksba_reader_release
- function on. */
+/* Create a writer for the given stream FP or STREAM. Depending on
+ the control information an output encoding is automagically
+ choosen. The function returns a Base64Context object which must be
+ passed to the gpgme_destroy_writer function. The created
+ KsbaWriter object is also returned, but the caller must not call
+ the ksba_reader_release function on. */
int
gpgsm_create_writer (Base64Context *ctx,
- ctrl_t ctrl, FILE *fp, ksba_writer_t *r_writer)
+ ctrl_t ctrl, FILE *fp, estream_t stream,
+ ksba_writer_t *r_writer)
{
int rc;
ksba_writer_t w;
@@ -625,11 +680,18 @@ gpgsm_create_writer (Base64Context *ctx,
if (ctrl->create_pem || ctrl->create_base64)
{
(*ctx)->u.wparm.fp = fp;
+ (*ctx)->u.wparm.stream = stream;
if (ctrl->create_pem)
(*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name
: "CMS OBJECT";
rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm);
}
+ else if (stream)
+ {
+ (*ctx)->u.wparm.fp = fp;
+ (*ctx)->u.wparm.stream = stream;
+ rc = ksba_writer_set_cb (w, plain_writer_cb, &(*ctx)->u.wparm);
+ }
else
rc = ksba_writer_set_file (w, fp);
@@ -655,10 +717,10 @@ gpgsm_finish_writer (Base64Context ctx)
return gpg_error (GPG_ERR_INV_VALUE);
parm = &ctx->u.wparm;
if (parm->did_finish)
- return 0; /* already done */
+ return 0; /* Already done. */
parm->did_finish = 1;
- if (!parm->fp)
- return 0; /* callback was not used */
+ if (!parm->fp && !parm->stream)
+ return 0; /* Callback was not used. */
return base64_finish_write (parm);
}