Пример #1
0
/*************************************************************************
  Writes buf to socket and returns the response in an fz_FILE.
  Use only on blocking sockets.
*************************************************************************/
fz_FILE *fc_querysocket(int sock, void *buf, size_t size)
{
  FILE *fp;

#ifdef HAVE_FDOPEN
  fp = fdopen(sock, "r+b");
  if (fwrite(buf, 1, size, fp) != size) {
    log_error("socket %d: write error", sock);
  }
  fflush(fp);

  /* we don't use fc_closesocket on sock here since when fp is closed
   * sock will also be closed. fdopen doesn't dup the socket descriptor. */
#else  /* HAVE_FDOPEN */
  {
    char tmp[4096];
    int n;

#ifdef WIN32_NATIVE
    /* tmpfile() in mingw attempts to make a temp file in the root directory
     * of the current drive, which we may not have write access to. */
    {
      char filename[MAX_PATH];

      GetTempPath(sizeof(filename), filename);
      sz_strlcat(filename, "fctmp");

      fp = fc_fopen(filename, "w+b");
    }
#else  /* WIN32_NATIVE */

    fp = tmpfile();

#endif /* WIN32_NATIVE */

    if (fp == NULL) {
      return NULL;
    }

    fc_writesocket(sock, buf, size);

    while ((n = fc_readsocket(sock, tmp, sizeof(tmp))) > 0) {
      if (fwrite(tmp, 1, n, fp) != n) {
        log_error("socket %d: write error", sock);
      }
    }
    fflush(fp);

    fc_closesocket(sock);

    rewind(fp);
  }
#endif /* HAVE_FDOPEN */

  return fz_from_stream(fp);
}
Пример #2
0
/****************************************************************************
  Read the request string (or part of it) from the metaserver.
****************************************************************************/
static void meta_read_response(struct server_scan *scan)
{
  char buf[4096];
  int result;

  if (!scan->meta.fp) {
#ifdef WIN32_NATIVE
    char filename[MAX_PATH];

    GetTempPath(sizeof(filename), filename);
    cat_snprintf(filename, sizeof(filename), "fctmp%d", myrand(1000));

    scan->meta.fp = fc_fopen(filename, "w+b");
#else
    scan->meta.fp = tmpfile();
#endif

    if (!scan->meta.fp) {
      scan->error_func(scan, _("Could not open temp file."));
    }
  }

  while (1) {
    result = fc_readsocket(scan->sock, buf, sizeof(buf));

    if (result < 0) {
      if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
	/* Keep waiting. */
	return;
      }
      scan->error_func(scan, fc_strerror(fc_get_errno()));
      return;
    } else if (result == 0) {
      fz_FILE *f;
      char str[4096];

      /* We're done! */
      rewind(scan->meta.fp);

      f = fz_from_stream(scan->meta.fp);
      assert(f != NULL);

      /* skip HTTP headers */
      /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */
      while (fz_fgets(str, sizeof(str), f) && strcmp(str, "\r\n") != 0) {
	/* nothing */
      }

      /* XXX: TODO check for magic Content-Type: text/x-ini -vasc */

      /* parse HTTP message body */
      scan->servers = parse_metaserver_data(f);
      scan->meta.state = META_DONE;

      /* 'f' (hence 'meta.fp') was closed in parse_metaserver_data(). */
      scan->meta.fp = NULL;

      if (NULL == scan->servers) {
        my_snprintf(str, sizeof(str),
                    _("Failed to parse the metaserver data from http://%s."),
                    scan->meta.name);
        scan->error_func(scan, str);
      }

      return;
    } else {
      if (fwrite(buf, 1, result, scan->meta.fp) != result) {
	scan->error_func(scan, fc_strerror(fc_get_errno()));
      }
    }
  }
}