static CURLcode ossl_seed(struct Curl_easy *data)
{
  /* This might get called before it has been added to a multi handle */
  if(data->multi && data->multi->ssl_seeded)
    return CURLE_OK;

  if(rand_enough()) {
    /* OpenSSL 1.1.0+ should return here */
    if(data->multi)
      data->multi->ssl_seeded = TRUE;
    return CURLE_OK;
  }
#ifdef HAVE_RANDOM_INIT_BY_DEFAULT
  /* with OpenSSL 1.1.0+, a failed RAND_status is a showstopper */
  failf(data, "Insufficient randomness");
  return CURLE_SSL_CONNECT_ERROR;
#else

#ifndef RANDOM_FILE
  /* if RANDOM_FILE isn't defined, we only perform this if an option tells
     us to! */
  if(data->set.str[STRING_SSL_RANDOM_FILE])
#define RANDOM_FILE "" /* doesn't matter won't be used */
#endif
  {
    /* let the option override the define */
    RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
                    data->set.str[STRING_SSL_RANDOM_FILE]:
                    RANDOM_FILE),
                   RAND_LOAD_LENGTH);
    if(rand_enough())
      return CURLE_OK;
  }

#if defined(HAVE_RAND_EGD)
  /* only available in OpenSSL 0.9.5 and later */
  /* EGD_SOCKET is set at configure time or not at all */
#ifndef EGD_SOCKET
  /* If we don't have the define set, we only do this if the egd-option
     is set */
  if(data->set.str[STRING_SSL_EGDSOCKET])
#define EGD_SOCKET "" /* doesn't matter won't be used */
#endif
  {
    /* If there's an option and a define, the option overrides the
       define */
    int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
                       data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
    if(-1 != ret) {
      if(rand_enough())
        return CURLE_OK;
    }
  }
#endif

  /* fallback to a custom seeding of the PRNG using a hash based on a current
     time */
  do {
    unsigned char randb[64];
    size_t len = sizeof(randb);
    size_t i, i_max;
    for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
      struct curltime tv = Curl_now();
      Curl_wait_ms(1);
      tv.tv_sec *= i + 1;
      tv.tv_usec *= (unsigned int)i + 2;
      tv.tv_sec ^= ((Curl_now().tv_sec + Curl_now().tv_usec) *
                    (i + 3)) << 8;
      tv.tv_usec ^= (unsigned int) ((Curl_now().tv_sec +
                                     Curl_now().tv_usec) *
                                    (i + 4)) << 16;
      memcpy(&randb[i * sizeof(struct curltime)], &tv,
             sizeof(struct curltime));
    }
    RAND_add(randb, (int)len, (double)len/2);
  } while(!rand_enough());

  {
    /* generates a default path for the random seed file */
    char fname[256];
    fname[0] = 0; /* blank it first */
    RAND_file_name(fname, sizeof(fname));
    if(fname[0]) {
      /* we got a file name to try */
      RAND_load_file(fname, RAND_LOAD_LENGTH);
      if(rand_enough())
        return CURLE_OK;
    }
  }

  infof(data, "libcurl is now using a weak random seed");
  return (rand_enough() ? CURLE_OK :
          CURLE_SSL_CONNECT_ERROR /* confusing error code */);
#endif
}
static CURLcode ossl_seed(struct Curl_easy *data)
{
   
  if(data->multi && data->multi->ssl_seeded)
    return CURLE_OK;

  if(rand_enough()) {
     
    if(data->multi)
      data->multi->ssl_seeded = TRUE;
    return CURLE_OK;
  }
#ifdef HAVE_RANDOM_INIT_BY_DEFAULT
   
  failf(data, "Insufficient randomness");
  return CURLE_SSL_CONNECT_ERROR;
#else

#ifndef RANDOM_FILE
   
  if(data->set.str[STRING_SSL_RANDOM_FILE])
#define RANDOM_FILE ""  
#endif
  {
     
    RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
                    data->set.str[STRING_SSL_RANDOM_FILE]:
                    RANDOM_FILE),
                   RAND_LOAD_LENGTH);
    if(rand_enough())
      return CURLE_OK;
  }

#if defined(HAVE_RAND_EGD)
   
   
#ifndef EGD_SOCKET
   
  if(data->set.str[STRING_SSL_EGDSOCKET])
#define EGD_SOCKET ""  
#endif
  {
     
    int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
                       data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
    if(-1 != ret) {
      if(rand_enough())
        return CURLE_OK;
    }
  }
#endif

   
  do {
    unsigned char randb[64];
    size_t len = sizeof(randb);
    size_t i, i_max;
    for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
      struct curltime tv = Curl_now();
      Curl_wait_ms(1);
      tv.tv_sec *= i + 1;
      tv.tv_usec *= (unsigned int)i + 2;
      tv.tv_sec ^= ((Curl_now().tv_sec + Curl_now().tv_usec) *
                    (i + 3)) << 8;
      tv.tv_usec ^= (unsigned int) ((Curl_now().tv_sec +
                                     Curl_now().tv_usec) *
                                    (i + 4)) << 16;
      memcpy(&randb[i * sizeof(struct curltime)], &tv,
             sizeof(struct curltime));
    }
    RAND_add(randb, (int)len, (double)len/2);
  } while(!rand_enough());

  {
     
    char fname[256];
    fname[0] = 0;  
    RAND_file_name(fname, sizeof(fname));
    if(fname[0]) {
       
      RAND_load_file(fname, RAND_LOAD_LENGTH);
      if(rand_enough())
        return CURLE_OK;
    }
  }

  infof(data, "libcurl is now using a weak random seed");
  return (rand_enough() ? CURLE_OK :
          CURLE_SSL_CONNECT_ERROR  );
#endif
}