#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h>
 
#include "openssl/crypto.h"

#define NUMT 16
 
static void *pull_one_url(void *url)
{
  CURL *curl;
  int i;
  char buffer[CURL_ERROR_SIZE];
  int num_tries = 100;
  int num_successes = 0;
 
  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_URL, "https://10.17.11.31");
  curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
  curl_easy_setopt(curl, CURLOPT_SSLCERT, "mycert.pfx");
  curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "p12");
  curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "exportpass");
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0L);
  curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer);

  for( i = 0; i < num_tries; i++ )
  {
      if( curl_easy_perform(curl) == 0 )
          num_successes++;
      else
      {
          fprintf(stderr, "ERROR: %s\n", buffer);
      }
  }
  curl_easy_cleanup(curl);

  printf("DEBUG: %ud :: %i/%i\n", (unsigned long)pthread_self(), num_successes, num_tries);
 
  return NULL;
}
 
static pthread_mutex_t **locks = NULL;
static int n_locks = 0;

static void
ssl_lock(int mode, int n, const char *file, int line)
{
    if (mode & CRYPTO_LOCK) pthread_mutex_lock(locks[n]);
    else pthread_mutex_unlock(locks[n]);
}
 
static unsigned long
ssl_thread_id(void)
{
    return (unsigned long)pthread_self();
}

int main(int argc, char **argv)
{
    pthread_t tid[NUMT];
    int i;
    int error;
  
  n_locks = CRYPTO_num_locks();
  if (n_locks) {
      locks = (pthread_mutex_t **) malloc(n_locks * sizeof(*locks));
      for (i=0; i < n_locks; i++) {
          locks[i] = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
          if( pthread_mutex_init(locks[i], NULL) )
              exit(1);
      }
        
      CRYPTO_set_locking_callback(ssl_lock);
      CRYPTO_set_id_callback(ssl_thread_id);
  }

  /* Must initialize libcurl before any threads are started */ 
  curl_global_init(CURL_GLOBAL_ALL);

  {
      int cnt = 0;
      for( cnt = 0; cnt < 1; cnt++ )
      {
          for(i=0; i< NUMT; i++) {
              error = pthread_create(&tid[i],
                                     NULL, /* default attributes please */ 
                                     pull_one_url,
                                     (void *)NULL);
              if(0 != error)
                  fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
              else
                  fprintf(stderr, "Thread %d, started\n", i);
          }
 
          /* now wait for all threads to terminate */ 
          for(i=0; i< NUMT; i++) {
              error = pthread_join(tid[i], NULL);
              fprintf(stderr, "Thread %d terminated\n", i);
          }
      }
  }
 
  return 0;
}


