Пример #1
0
static gpg_error_t
part_data (void *cookie, const void *data, size_t datalen)
{
  receive_ctx_t ctx = cookie;

  if (data)
    {
      if (opt.debug)
        log_debug ("part_data: '%.*s'\n", (int)datalen, (const char*)data);
      if (ctx->collect_key_data)
        {
          if (es_write (ctx->key_data, data, datalen, NULL)
              || es_fputs ("\n", ctx->key_data))
            return gpg_error_from_syserror ();
        }
      if (ctx->collect_wkd_data)
        {
          if (es_write (ctx->wkd_data, data, datalen, NULL)
              || es_fputs ("\n", ctx->wkd_data))
            return gpg_error_from_syserror ();
        }
    }
  else
    {
      if (opt.debug)
        log_debug ("part_data: finished\n");
      ctx->collect_key_data = 0;
      ctx->collect_wkd_data = 0;
    }
  return 0;
}
Пример #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 ();
}
Пример #3
0
/* The thread started by start_reader.  */
static void *
reader_thread_main (void *arg)
{
  gpg_error_t err = 0;
  struct reader_thread_parms *parm = arg;
  char buffer[4096];
  int nread;

  while ( (nread = npth_read (parm->fd, buffer, sizeof buffer)) )
    {
      if (nread < 0)
        {
          if (errno == EINTR)
            continue;
          err = my_error_from_syserror ();
          break;  /* Read error.  */
        }

      if (parm->stream)
        {
          const char *p = buffer;
          size_t nwritten;
          while (nread)
            {
              err = es_write (parm->stream, p, nread, &nwritten);
              if (err)
                {
                  log_error ("writing stream failed: %s\n",
                             gpg_strerror (err));
                  goto leave;
                }
              nread -= nwritten;
              p += nwritten;
            }
        }
      else
        put_membuf (parm->mb, buffer, nread);
    }

 leave:
  *parm->err_addr = err;
  if (close (parm->fd))
    log_error ("closing reader fd %d failed: %s\n", parm->fd, strerror (errno));
  xfree (parm);
  return NULL;
}
Пример #4
0
/* Data callback for the WKD_GET command. */
static gpg_error_t
wkd_get_data_cb (void *opaque, const void *data, size_t datalen)
{
  struct wkd_get_parm_s *parm = opaque;
  gpg_error_t err = 0;
  size_t nwritten;

  if (!data)
    return 0;  /* Ignore END commands.  */
  if (!parm->memfp)
    return 0;  /* Data is not required.  */

  if (es_write (parm->memfp, data, datalen, &nwritten))
    err = gpg_error_from_syserror ();

  return err;
}
Пример #5
0
/* Helper for ks_hkp_put.  */
static gpg_error_t
put_post_cb (void *opaque, http_t http)
{
  struct put_post_parm_s *parm = opaque;
  gpg_error_t err = 0;
  estream_t fp;
  size_t len;

  fp = http_get_write_ptr (http);
  len = strlen (parm->datastring);

  es_fprintf (fp,
              "Content-Type: application/x-www-form-urlencoded\r\n"
              "Content-Length: %zu\r\n", len+8 /* 8 is for "keytext" */);
  http_start_data (http);
  if (es_fputs ("keytext=", fp) || es_write (fp, parm->datastring, len, NULL))
    err = gpg_error_from_syserror ();
  return err;
}
Пример #6
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;
}
Пример #7
0
static void
test_poll (void)
{
  int ret;
  gpgrt_poll_t fds[3];
  char buffer[16];
  size_t used, nwritten;
  int c;

  memset (fds, 0, sizeof fds);
  fds[0].stream = test_stdin;
  fds[0].want_read = 1;
  fds[1].stream = test_stdout;
  fds[1].want_write = 1;
  /* FIXME: We don't use the next stream at all.  */
  fds[2].stream = test_stderr;
  fds[2].want_write = 1;
  fds[2].ignore = 1;


  used = 0;
  while (used || !fds[0].ignore)
    {
      ret = gpgrt_poll (fds, DIM(fds), -1);
      if (ret == -1)
        {
          fail ("gpgrt_poll failed: %s\n", strerror (errno));
          continue;
        }
      if (!ret)
        {
          fail ("gpgrt_poll unexpectedly timed out\n");
          continue;
        }
      show ("gpgrt_poll detected %d events\n", ret);
      if (fds[0].got_read)
        {
          /* Read from the producer.  */
          for (;;)
            {
              c = es_fgetc (fds[0].stream);
              if (c == EOF)
                {
                  if (es_feof (fds[0].stream))
                    {
                      show ("reading '%s': EOF\n", peer_stdin.name);
                      fds[0].ignore = 1; /* Not anymore needed.  */
                      peer_stdin.stop_me = 1; /* Tell the thread to stop.  */
                    }
                  else if (es_ferror (fds[0].stream))
                    {
                      fail ("error reading '%s': %s\n",
                            peer_stdin.name, strerror (errno));
                      fds[0].ignore = 1;    /* Disable.  */
                      peer_stdin.stop_me = 1; /* Tell the thread to stop.  */
                    }
                  else
                    show ("reading '%s': EAGAIN\n", peer_stdin.name);
                  break;
                }
              else
                {
                  if (used <= sizeof buffer -1)
                    buffer[used++] = c;
                  if (used == sizeof buffer)
                    {
                      show ("throttling reading from '%s'\n", peer_stdin.name);
                      fds[0].ignore = 1;
                      break;
                    }
                }
            }
          show ("read from '%s': %zu bytes\n", peer_stdin.name, used);
          if (used)
            fds[1].ignore = 0; /* Data to send.  */
        }
      if (fds[1].got_write)
        {
          if (used)
            {
              ret = es_write (fds[1].stream, buffer, used, &nwritten);
              show ("result for writing to '%s': ret=%d, n=%zu, nwritten=%zu\n",
                    peer_stdout.name, ret, used, nwritten);
              if (!ret)
                {
                  assert (nwritten <= used);
                  /* Move the remaining data to the front of buffer.  */
                  memmove (buffer, buffer + nwritten,
                           sizeof buffer - nwritten);
                  used -= nwritten;
                }
              ret = es_fflush (fds[1].stream);
              if (ret)
                fail ("Flushing for '%s' failed: %s\n",
                      peer_stdout.name, strerror (errno));
            }
          if (!used)
            fds[1].ignore = 1; /* No need to send data.  */
        }

      if (used < sizeof buffer / 2 && !peer_stdin.stop_me && fds[0].ignore)
        {
          show ("accelerate reading from '%s'\n", peer_stdin.name);
          fds[0].ignore = 0;
        }
    }
}
Пример #8
0
CURLcode
curl_easy_perform(CURL *curl)
{
  int rc;
  CURLcode err=CURLE_OK;
  const char *errstr=NULL;
  char *proxy=NULL;
  struct http_srv srv;

  memset(&srv,0,sizeof(srv));

  /* Emulate the libcurl proxy behavior.  If the calling program set a
     proxy, use it.  If it didn't set a proxy or set it to NULL, check
     for one in the environment.  If the calling program explicitly
     set a null-string proxy the http code doesn't use a proxy at
     all. */

  if(curl->proxy)
    proxy=curl->proxy;
  else
    proxy=getenv(HTTP_PROXY_ENV);

  if(curl->srvtag)
    srv.srvtag=curl->srvtag;

  if(curl->flags.verbose)
    {
      fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
      fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url);
      if(srv.srvtag)
	fprintf(curl->errors,
		"* SRV tag is \"%s\": host and port may be overridden\n",
		srv.srvtag);
      fprintf(curl->errors,"* HTTP auth is \"%s\"\n",
	      curl->auth?curl->auth:"null");
      fprintf(curl->errors,"* HTTP method is %s\n",
	      curl->flags.post?"POST":"GET");
    }

  if(curl->flags.post)
    {
      rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
                      0, proxy, NULL, &srv,
		      curl->headers?curl->headers->list:NULL);
      if (!rc)
	{
	  unsigned int post_len = strlen(curl->postfields);

	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  es_fprintf (http_get_write_ptr (curl->hd),
                      "Content-Type: application/x-www-form-urlencoded\r\n"
                      "Content-Length: %u\r\n", post_len);
	  http_start_data (curl->hd);
	  es_write (http_get_write_ptr (curl->hd),
                    curl->postfields, post_len, NULL);

	  rc = http_wait_response (curl->hd);
          curl->status = http_get_status_code (curl->hd);
	  if (!rc && curl->flags.failonerror && curl->status>=300)
	    err = CURLE_HTTP_RETURNED_ERROR;
          http_close (curl->hd, 0);
          curl->hd = NULL;
	}
    }
  else
    {
      rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
                      0, proxy, NULL, &srv,
		      curl->headers?curl->headers->list:NULL);
      if (!rc)
	{
	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  rc = http_wait_response (curl->hd);
          curl->status = http_get_status_code (curl->hd);
	  if (!rc)
	    {
	      if (curl->flags.failonerror && curl->status>=300)
		err = CURLE_HTTP_RETURNED_ERROR;
	      else
		{
		  size_t maxlen = 1024;
                  size_t buflen;
                  unsigned int len;
		  char *line = NULL;

		  while ((len = es_read_line (http_get_read_ptr (curl->hd),
                                              &line, &buflen, &maxlen)))
		    {
		      size_t ret;

		      maxlen=1024;

		      ret=(curl->writer)(line,len,1,curl->file);
		      if(ret!=len)
			{
			  err=CURLE_WRITE_ERROR;
			  break;
			}
		    }

		  es_free (line);
		  http_close(curl->hd, 0);
                  curl->hd = NULL;
		}
	    }
	  else
            {
              http_close (curl->hd, 0);
              curl->hd = NULL;
            }
	}
    }

  xfree(srv.used_server);

  switch(gpg_err_code (rc))
    {
    case 0:
      break;

    case GPG_ERR_INV_URI:
      err=CURLE_UNSUPPORTED_PROTOCOL;
      break;

    default:
      errstr=gpg_strerror (rc);
      err=CURLE_COULDNT_CONNECT;
      break;
    }
      
  return handle_error(curl,err,errstr);
}