Example #1
0
gpgme_error_t
_gpgme_data_inbound_handler (void *opaque, int fd)
{
  struct io_cb_data *data = (struct io_cb_data *) opaque;
  gpgme_data_t dh = (gpgme_data_t) data->handler_value;
  char buffer[BUFFER_SIZE];
  char *bufp = buffer;
  gpgme_ssize_t buflen;
  TRACE_BEG1 (DEBUG_CTX, "_gpgme_data_inbound_handler", dh,
	      "fd=0x%x", fd);

  buflen = _gpgme_io_read (fd, buffer, BUFFER_SIZE);
  if (buflen < 0)
    return gpg_error_from_syserror ();
  if (buflen == 0)
    {
      _gpgme_io_close (fd);
      return TRACE_ERR (0);
    }

  do
    {
      gpgme_ssize_t amt = gpgme_data_write (dh, bufp, buflen);
      if (amt == 0 || (amt < 0 && errno != EINTR))
	return TRACE_ERR (gpg_error_from_syserror ());
      bufp += amt;
      buflen -= amt;
    }
  while (buflen > 0);
  return TRACE_ERR (0);
}
Example #2
0
gpgme_error_t
_gpgme_data_inbound_handler(void *opaque, int fd)
{
    gpgme_data_t dh = (gpgme_data_t) opaque;
    char buffer[BUFFER_SIZE];
    char *bufp = buffer;
    ssize_t buflen;

    buflen = _gpgme_io_read(fd, buffer, BUFFER_SIZE);
    if(buflen < 0)
        return gpg_error_from_errno(errno);
    if(buflen == 0)
    {
        _gpgme_io_close(fd);
        return 0;
    }

    do
    {
        ssize_t amt = gpgme_data_write(dh, bufp, buflen);
        if(amt == 0 || (amt < 0 && errno != EINTR))
            return gpg_error_from_errno(errno);
        bufp += amt;
        buflen -= amt;
    }
    while(buflen > 0);
    return 0;
}
Example #3
0
/* This function provides access to the internal read function; it is
   normally not used.  */
gpgme_ssize_t
gpgme_io_read (int fd, void *buffer, size_t count)
{
  int ret;
  TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
	      "buffer=%p, count=%u", buffer, count);

  ret = _gpgme_io_read (fd, buffer, count);

  return TRACE_SYSRES (ret);
}
Example #4
0
static gpgme_ssize_t
my_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
{
  return _gpgme_io_read ((int) fd, buffer, size);
}
Example #5
0
/* Read from gpgconf and pass line after line to the hook function.
   We put a limit of 64 k on the maximum size for a line.  This should
   allow for quite a long "group" line, which is usually the longest
   line (mine is currently ~3k).  */
static gpgme_error_t
gpgconf_read (void *engine, char *arg1, char *arg2,
	      gpgme_error_t (*cb) (void *hook, char *line),
	      void *hook)
{
  struct engine_gpgconf *gpgconf = engine;
  gpgme_error_t err = 0;
  char *linebuf;
  size_t linebufsize;
  int linelen;
  char *argv[4] = { NULL /* file_name */, NULL, NULL, NULL };
  int rp[2];
  struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */, -1, 0},
				   {-1, -1} };
  int status;
  int nread;
  char *mark = NULL;

  argv[1] = arg1;
  argv[2] = arg2;


  /* FIXME: Deal with engine->home_dir.  */

  /* _gpgme_engine_new guarantees that this is not NULL.  */
  argv[0] = gpgconf->file_name;

  if (_gpgme_io_pipe (rp, 1) < 0)
    return gpg_error_from_syserror ();

  cfd[0].fd = rp[1];

  status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
  if (status < 0)
    {
      _gpgme_io_close (rp[0]);
      _gpgme_io_close (rp[1]);
      return gpg_error_from_syserror ();
    }

  linebufsize = 1024; /* Usually enough for conf lines.  */
  linebuf = malloc (linebufsize);
  if (!linebuf)
    {
      err = gpg_error_from_syserror ();
      goto leave;
    }
  linelen = 0;

  while ((nread = _gpgme_io_read (rp[0], linebuf + linelen,
                                  linebufsize - linelen - 1)))
    {
      char *line;
      const char *lastmark = NULL;
      size_t nused;

      if (nread < 0)
        {
          err = gpg_error_from_syserror ();
          goto leave;
        }

      linelen += nread;
      linebuf[linelen] = '\0';

      for (line=linebuf; (mark = strchr (line, '\n')); line = mark+1 )
        {
          lastmark = mark;
          if (mark > line && mark[-1] == '\r')
            mark[-1] = '\0';
          else
            mark[0] = '\0';

          /* Got a full line.  Due to the CR removal code (which
             occurs only on Windows) we might be one-off and thus
             would see empty lines.  Don't pass them to the
             callback. */
          err = *line? (*cb) (hook, line) : 0;
          if (err)
            goto leave;
        }

      nused = lastmark? (lastmark + 1 - linebuf) : 0;
      memmove (linebuf, linebuf + nused, linelen - nused);
      linelen -= nused;

      if (!(linelen < linebufsize - 1))
        {
          char *newlinebuf;

          if (linelen <  8 * 1024 - 1)
            linebufsize = 8 * 1024;
          else if (linelen < 64 * 1024 - 1)
            linebufsize = 64 * 1024;
          else
            {
              /* We reached our limit - give up.  */
              err = gpg_error (GPG_ERR_LINE_TOO_LONG);
              goto leave;
            }

          newlinebuf = realloc (linebuf, linebufsize);
          if (!newlinebuf)
            {
              err = gpg_error_from_syserror ();
              goto leave;
            }
          linebuf = newlinebuf;
        }
    }

 leave:
  free (linebuf);
  _gpgme_io_close (rp[0]);
  return err;
}
static gpgme_error_t
gpgconf_read (void *engine, char *arg1, char *arg2,
	      gpgme_error_t (*cb) (void *hook, char *line),
	      void *hook)
{
  struct engine_gpgconf *gpgconf = engine;
  gpgme_error_t err = 0;
#define LINELENGTH 1024
  char linebuf[LINELENGTH] = "";
  int linelen = 0;
  char *argv[4] = { NULL /* file_name */, NULL, NULL, NULL };
  int rp[2];
  struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */, -1, 0},
				   {-1, -1} };
  int status;
  int nread;
  char *mark = NULL;

  argv[1] = arg1;
  argv[2] = arg2;


  /* FIXME: Deal with engine->home_dir.  */

  /* _gpgme_engine_new guarantees that this is not NULL.  */
  argv[0] = gpgconf->file_name;
  
  if (_gpgme_io_pipe (rp, 1) < 0)
    return gpg_error_from_syserror ();

  cfd[0].fd = rp[1];

  status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
  if (status < 0)
    {
      _gpgme_io_close (rp[0]);
      _gpgme_io_close (rp[1]);
      return gpg_error_from_syserror ();
    }

  do
    {
      nread = _gpgme_io_read (rp[0], 
                              linebuf + linelen, LINELENGTH - linelen - 1);
      if (nread > 0)
	{
          char *line;
          const char *lastmark = NULL;
          size_t nused;

	  linelen += nread;
	  linebuf[linelen] = '\0';

	  for (line=linebuf; (mark = strchr (line, '\n')); line = mark+1 )
	    {
              lastmark = mark;
	      if (mark > line && mark[-1] == '\r')
		mark[-1] = '\0';
              else
                mark[0] = '\0';

	      /* Got a full line.  Due to the CR removal code (which
                 occurs only on Windows) we might be one-off and thus
                 would see empty lines.  Don't pass them to the
                 callback. */
	      err = *line? (*cb) (hook, line) : 0;
	      if (err)
		goto leave;
	    }

          nused = lastmark? (lastmark + 1 - linebuf) : 0;
          memmove (linebuf, linebuf + nused, linelen - nused);
          linelen -= nused;
	}
    }
  while (nread > 0 && linelen < LINELENGTH - 1);
  
  if (!err && nread < 0)
    err = gpg_error_from_syserror ();
  if (!err && nread > 0)
    err = gpg_error (GPG_ERR_LINE_TOO_LONG);

 leave:
  _gpgme_io_close (rp[0]);

  return err;
}