#include <stdio.h>
#include <stdlib.h>  
#include <string.h>

#include <pthread.h>

#define MAX_LEN 256
#define NTHREADS 60

#undef QUEUE

#include <curl/curl.h>

void ourWriteOut(CURL *curl);

static char *UA="(X11; U; Linux i686;\0";
//static char *UA="(Windows\0";

pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;


void chopstr(char *str)
{ 
  while (*str != '\012' && *str != '\015') ++str;
    *str='\0';
}

int geturl(char *url,FILE *file)
{ 
  if (fgets(url, MAX_LEN, file) == NULL)
    return 0;
  else {
    chopstr(url);
    return strlen(url);
  }
}

size_t 
WriteNothing(void *ptr, size_t size, size_t nmemb, void *data)
{
  return size*nmemb;
}

void  *pull_one_url()
{
  CURL *curl;
  FILE *stream = stdout;
  int rc,len;
  char url[MAX_LEN];
  pthread_t cthread;

  
  for (;;) {
      len=geturl(url,stdin);
      if ( len > 0 ) {
#ifdef QUEUE
      pthread_mutex_lock(&fastmutex);
#endif
      curl = curl_easy_init();
      
      curl_easy_setopt(curl, CURLOPT_URL, url);
      curl_easy_setopt(curl, CURLOPT_USERAGENT, UA);
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
      curl_easy_setopt(curl, CURLOPT_MUTE, 1);
      curl_easy_setopt(curl, CURLOPT_FILETIME, 1);
      curl_easy_setopt(curl, CURLOPT_PASSWDFUNCTION, NULL );
      curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1 );
      curl_easy_setopt(curl, CURLOPT_TIMEOUT, 100);
      curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT,200);
      curl_easy_setopt(curl, CURLOPT_HEADER, 0);
      curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
      curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteNothing);
      rc = curl_easy_perform(curl);

  cthread = pthread_self();

#ifndef QUEUE
      pthread_mutex_lock(&fastmutex);
#endif
       fprintf(stream,"%li|%i|%i|%s|",cthread,rc,(int)time(NULL),url);
       ourWriteOut(curl);
       fflush(stream);
#ifndef QUEUE
      pthread_mutex_unlock(&fastmutex);
#endif
      curl_easy_cleanup(curl);
#ifdef QUEUE
      pthread_mutex_unlock(&fastmutex);
#endif
  } else {
      break;
  }
 }
 return NULL;
}

    
int main(int argc, char **argv)
{
  pthread_t tid[NTHREADS];
  int i, error;

  curl_global_init(CURL_GLOBAL_ALL);

  for(i=0; i< NTHREADS; i++) {
      error = pthread_create(&tid[i],
                             NULL, /* default attributes please */
                             pull_one_url, NULL);
      if(0 != error)
        fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
  }

  for(i=0; i< NTHREADS; i++) {
    error = pthread_join(tid[i], NULL);
//    fprintf(stderr, "Thread %d terminated\n", i);
  }

  curl_global_cleanup();
  fprintf(stderr,"That's all, folks !\n");
  return 0;
}
