Beispiel #1
0
static gpg_error_t
armor_data (char **r_string, const void *data, size_t datalen)
{
  gpg_error_t err;
  struct b64state b64state;
  estream_t fp;
  long length;
  char *buffer;
  size_t nread;

  *r_string = NULL;

  fp = es_fopenmem (0, "rw");
  if (!fp)
    return gpg_error_from_syserror ();

  if ((err=b64enc_start_es (&b64state, fp, "PGP PUBLIC KEY BLOCK"))
      || (err=b64enc_write (&b64state, data, datalen))
      || (err = b64enc_finish (&b64state)))
    {
      es_fclose (fp);
      return err;
    }

  /* FIXME: To avoid the extra buffer allocation estream should
     provide a function to snatch the internal allocated memory from
     such a memory stream.  */
  length = es_ftell (fp);
  if (length < 0)
    {
      err = gpg_error_from_syserror ();
      es_fclose (fp);
      return err;
    }

  buffer = xtrymalloc (length+1);
  if (!buffer)
    {
      err = gpg_error_from_syserror ();
      es_fclose (fp);
      return err;
    }

  es_rewind (fp);
  if (es_read (fp, buffer, length, &nread))
    {
      err = gpg_error_from_syserror ();
      es_fclose (fp);
      return err;
    }
  buffer[nread] = 0;
  es_fclose (fp);

  *r_string = buffer;
  return 0;
}
Beispiel #2
0
/* Copy all data from IN to OUT.  */
static gpg_error_t
copy_stream (estream_t in, estream_t out)
{
  char buffer[512];
  size_t nread;

  while (!es_read (in, buffer, sizeof buffer, &nread))
    {
      if (!nread)
        return 0; /* EOF */
      if (es_write (out, buffer, nread, NULL))
        break;

    }
  return gpg_error_from_syserror ();
}
Beispiel #3
0
/* The thread started by start_writer.  */
static void *
writer_thread_main (void *arg)
{
  gpg_error_t err = 0;
  struct writer_thread_parms *parm = arg;
  char _buffer[4096];
  char *buffer;
  size_t length;

  if (parm->stream)
    {
      buffer = _buffer;
      err = es_read (parm->stream, buffer, sizeof _buffer, &length);
      if (err)
        {
          log_error ("reading stream failed: %s\n", gpg_strerror (err));
          goto leave;
        }
    }
  else
    {
      buffer = (char *) parm->data;
      length = parm->datalen;
    }

  while (length)
    {
      ssize_t nwritten;

      nwritten = npth_write (parm->fd, buffer, length < 4096? length:4096);
      if (nwritten < 0)
        {
          if (errno == EINTR)
            continue;
          err = my_error_from_syserror ();
          break; /* Write error.  */
        }
      length -= nwritten;

      if (parm->stream)
        {
          if (length == 0)
            {
              err = es_read (parm->stream, buffer, sizeof _buffer, &length);
              if (err)
                {
                  log_error ("reading stream failed: %s\n",
                             gpg_strerror (err));
                  break;
                }
              if (length == 0)
                /* We're done.  */
                break;
            }
        }
      else
        buffer += nwritten;
    }

 leave:
  *parm->err_addr = err;
  if (close (parm->fd))
    log_error ("closing writer fd %d failed: %s\n", parm->fd, strerror (errno));
  xfree (parm);
  return NULL;
}
Beispiel #4
0
/* The thread started by start_feede3.  */
static void *
feeder_thread (void *arg)
{
  struct feeder_thread_parms *parm = arg;
  char buffer[4096];
  int rc;

  if (parm->direction)
    {
      size_t nread = 0;
      DWORD nwritten;

      log_debug ("feeder_thread estream->pipe: stream=%p pipe=%p\n",
                 parm->stream, parm->hd);
      while (parm->stream_valid
             && !es_read (parm->stream, buffer, sizeof buffer, &nread))
        {
          do
            {
              pth_enter ();
              rc = WriteFile (parm->hd, buffer, nread, &nwritten, NULL);
              pth_leave ();
              if (!rc)
                {
                  log_debug ("feeder(%p): WriteFile error: rc=%d\n",
                             parm->hd, (int)GetLastError ());
                  goto leave;
                }
              nread -= nwritten;
            }
          while (nread);
        }
      if (!parm->stream_valid)
        log_debug ("feeder(%p): closed by other thread\n", parm->hd);
      else if (nread)
        log_debug ("feeder(%p): es_read error: %s\n",
                   parm->hd, strerror (errno));
    }
  else
    {
      DWORD nread = 0;
      size_t nwritten;

      log_debug ("feeder_thread pipe->estream: stream=%p pipe=%p\n",
                 parm->stream, parm->hd);
      while ( (pth_enter (),
               (rc = ReadFile (parm->hd, buffer, sizeof buffer, &nread, NULL)),
               pth_leave (),
               rc) && nread)
        {
          log_debug ("feeder_thread pipe->estream: read %d bytes\n",
                     (int)nread);
          do
            {
              if (parm->stream_valid
                  && es_write (parm->stream, buffer, nread, &nwritten))
                {
                  log_debug ("feeder(%p): es_write error: %s\n",
                             parm->hd, strerror (errno));
                  goto leave;
                }
              log_debug ("feeder_thread pipe->estream: es_wrote %d bytes\n",
                         (int)nwritten);
              nread -= nwritten;
            }
          while (nread && parm->stream_valid);
        }
      if (!parm->stream_valid)
        log_debug ("feeder(%p): closed by other thread\n", parm->hd);
      else if (nread)
        log_debug ("feeder(%p): ReadFile error: rc=%d\n",
                   parm->hd, (int)GetLastError ());
      else
        log_debug ("feeder(%p): eof\n", parm->hd);
    }

leave:
  log_debug ("feeder(%p): waiting for es_fclose\n", parm->hd);
  while (parm->stream_valid)
    pth_yield (NULL);
  log_debug ("feeder(%p): about to close the pipe handle\n", parm->hd);
  CloseHandle (parm->hd);
  log_debug ("feeder(%p): pipe handle closed\n", parm->hd);
  xfree (parm);
  return NULL;
}