Exemple #1
0
void
examine_doactions (swf_extractor * swf, int * error, swf_doaction_list * list)
{
    swf_doaction * node;

    if (list == NULL || *error != SWF_ENoError)
    {
        return;
    }

    dprintf ("[examine_doactions : list is not null]\n");

    node = list->first;

    while (node != NULL)
    {
		/* take urls that aren't internal FSCommand: calls */
        if (node->code == sactionGetURL && strncmp("FSCommand:", node->url, 10))
        {
            dprintf ("[examine_doactions : got a URL '%s']\n", node->url);

            add_url (swf, error, node->url);
        }

        /* todo : is this necessary? */
        if ((node->code == sactionPushData) && (node->push_data_type == 0))
        {
            dprintf ("[examine_doactions : got a push_data_string '%s']\n", node->push_data_string);

            add_string (swf, error, node->push_data_string);
        }

        node = node->next;
    }
}
Exemple #2
0
void pocket_add(const char *key, const char *token, const char* url) 
{
    struct buffer s;

    buffer_init(&s);
    request(URL_ADD, add_url(key, token, url), &s, 0);
    buffer_cleanup(&s);
}
int init_global(void){//str *info_set_mapping){


    
    int i, j;
    char *s, *p;
    int count = -1;

    for(i=0; i< db_urls_count; i++){

        s = db_urls_list[i];
        LM_DBG("line = %s\n", s);

        if(s && strlen(s) && s[0]!='#'){

            if(strncmp("define", s, strlen("define")) == 0){
                s += strlen("define")+1;
                p = strchr(s, ' ');
                /* set1=FAILOVER */
                *p = 0;
                p++;
                LM_DBG("set_mode = {%s}, mode = {%s}\n", s, p);
                add_set(s, p);
                /*LM_ERR("done\n"); */
                count++;
            }
            else{
                /* mysql:........ */
                LM_DBG("db = %s\n", s);
                add_url(count, s);
            }
        }
 
    }
    for(i = 0; i< global->size; i++)
        for(j=0; j<global->set_list[i].size; j++){

            global->set_list[i].db_list[j].dbf.cap = 0;

            if(db_bind_mod(&global->set_list[i].db_list[j].db_url,
                    &global->set_list[i].db_list[j].dbf)){
                LM_ERR("cant bind db : %.*s",
			global->set_list[i].db_list[j].db_url.len,
                        global->set_list[i].db_list[j].db_url.s);
                goto error;
            }
        }

    LM_DBG("global done\n");
    /*is_initialized = 1; */
    return 0;

    error:

    destroy();
    return -1;
}
Exemple #4
0
static void read_urls(FILE *fp)
{
	char line[1024], *p;

	while (fgets(line, sizeof(line), fp)) {
		p = strrchr(line, '\n');
		if (p)
			*p = '\0';
		add_url(line);
	}
}
int process_http_packet(const uint8_t* const bytes,
                       int len,
                       http_table_t* const http_table,
                       uint16_t flow_id)
{
  if (len <=0) return -1;
  char * argv[3];
  int n;
  if((n=tokenize((char*)bytes,argv,3,' ')) ==3) {
   if(strcasecmp(argv[0],"GET")!=0) // a GET command
    return -1; 
  }  
  else return -1;
  int flagcut=0;
  int length=(int)strlen(argv[1]);
  if(length>MAX_URL)
    {argv[1][MAX_URL-1]='\0';
     flagcut=1;
    } 
#ifndef DISABLE_ANONYMIZATION
  add_url(http_table, flow_id,argv[1],flagcut);
#endif
  return 0;
}
Exemple #6
0
static int handle_config(const char *key, const char *value, void *cb)
{
	const char *name;
	const char *subkey;
	struct remote *remote;
	struct branch *branch;
	if (!prefixcmp(key, "branch.")) {
		name = key + 7;
		subkey = strrchr(name, '.');
		if (!subkey)
			return 0;
		branch = make_branch(name, subkey - name);
		if (!strcmp(subkey, ".remote")) {
			if (!value)
				return config_error_nonbool(key);
			branch->remote_name = xstrdup(value);
			if (branch == current_branch)
				default_remote_name = branch->remote_name;
		} else if (!strcmp(subkey, ".merge")) {
			if (!value)
				return config_error_nonbool(key);
			add_merge(branch, xstrdup(value));
		}
		return 0;
	}
	if (!prefixcmp(key, "url.")) {
		struct rewrite *rewrite;
		name = key + 4;
		subkey = strrchr(name, '.');
		if (!subkey)
			return 0;
		rewrite = make_rewrite(name, subkey - name);
		if (!strcmp(subkey, ".insteadof")) {
			if (!value)
				return config_error_nonbool(key);
			add_instead_of(rewrite, xstrdup(value));
		}
	}
	if (prefixcmp(key,  "remote."))
		return 0;
	name = key + 7;
	if (*name == '/') {
		warning("Config remote shorthand cannot begin with '/': %s",
			name);
		return 0;
	}
	subkey = strrchr(name, '.');
	if (!subkey)
		return error("Config with no key for remote %s", name);
	remote = make_remote(name, subkey - name);
	remote->origin = REMOTE_CONFIG;
	if (!strcmp(subkey, ".mirror"))
		remote->mirror = git_config_bool(key, value);
	else if (!strcmp(subkey, ".skipdefaultupdate"))
		remote->skip_default_update = git_config_bool(key, value);

	else if (!strcmp(subkey, ".url")) {
		const char *v;
		if (git_config_string(&v, key, value))
			return -1;
		add_url(remote, v);
	} else if (!strcmp(subkey, ".push")) {
		const char *v;
		if (git_config_string(&v, key, value))
			return -1;
		add_push_refspec(remote, v);
	} else if (!strcmp(subkey, ".fetch")) {
		const char *v;
		if (git_config_string(&v, key, value))
			return -1;
		add_fetch_refspec(remote, v);
	} else if (!strcmp(subkey, ".receivepack")) {
		const char *v;
		if (git_config_string(&v, key, value))
			return -1;
		if (!remote->receivepack)
			remote->receivepack = v;
		else
			error("more than one receivepack given, using the first");
	} else if (!strcmp(subkey, ".uploadpack")) {
		const char *v;
		if (git_config_string(&v, key, value))
			return -1;
		if (!remote->uploadpack)
			remote->uploadpack = v;
		else
			error("more than one uploadpack given, using the first");
	} else if (!strcmp(subkey, ".tagopt")) {
		if (!strcmp(value, "--no-tags"))
			remote->fetch_tags = -1;
	} else if (!strcmp(subkey, ".proxy")) {
		return git_config_string((const char **)&remote->http_proxy,
					 key, value);
	}
	return 0;
}
Exemple #7
0
static void add_url_alias(struct remote *remote, const char *url)
{
	add_url(remote, alias_url(url));
}
Exemple #8
0
airport::BasicCrawler::BasicCrawler(airport::Url &url):maxThreads(DEFAULT_CRAWLER_MAX_THREADS)
{
    add_url(url);
}
Exemple #9
0
void 
airport::BasicCrawler::add_url(const char *urlCString)
{
    airport::Url url(urlCString);
    add_url(url);
}
Exemple #10
0
airport::BasicCrawler::BasicCrawler(std::string &urlString):maxThreads(DEFAULT_CRAWLER_MAX_THREADS)
{
    add_url(urlString);
}
Exemple #11
0
airport::BasicCrawler::BasicCrawler(const char *urlCString):maxThreads(DEFAULT_CRAWLER_MAX_THREADS)
{
    add_url(urlCString);
}
Exemple #12
0
void 
airport::BasicCrawler::add_url(std::string &urlString)
{
    airport::Url url(urlString);
    add_url(url);
}
Exemple #13
0
/* The core of recursive retrieving.  Endless recursion is avoided by
   having all URL-s stored to a linked list of URL-s, which is checked
   before loading any URL.  That way no URL can get loaded twice.

   The function also supports specification of maximum recursion depth
   and a number of other goodies.  */
uerr_t
recursive_retrieve (const char *file, const char *this_url)
{
  char *constr, *filename, *newloc;
  char *canon_this_url = NULL;
  int dt, inl;
  int this_url_ftp;            /* See below the explanation */
  uerr_t err;
  struct urlinfo *rurl;
  urlpos *url_list, *cur_url;
  char *rfile; /* For robots */
  struct urlinfo *u;

  assert (this_url != NULL);
  assert (file != NULL);
  /* If quota was exceeded earlier, bail out.  */
  if (opt.quota && (opt.downloaded > opt.quota))
    return QUOTEXC;
  /* Cache the current URL in the list.  */
  if (first_time)
    {
      ulist = add_slist (ulist, this_url, 0);
      urls_downloaded = NULL;
      urls_html = NULL;
      /* Enter this_url to the slist, in original and "enhanced" form.  */
      u = newurl ();
      err = parseurl (this_url, u, 0);
      if (err == URLOK)
	{
	  ulist = add_slist (ulist, u->url, 0);
	  urls_downloaded = add_url (urls_downloaded, u->url, file);
	  urls_html = add_slist (urls_html, file, NOSORT);
	  if (opt.no_parent)
	    base_dir = xstrdup (u->dir); /* Set the base dir.  */
	  /* Set the canonical this_url to be sent as referer.  This
	     problem exists only when running the first time.  */
	  canon_this_url = xstrdup (u->url);
	}
      else
	{
	  DEBUGP (("Double yuck!  The *base* URL is broken.\n"));
	  base_dir = NULL;
	}
      freeurl (u, 1);
      depth = 1;
      robots_host = NULL;
      forbidden = NULL;
      first_time = 0;
    }
  else
    ++depth;

  /* Bail out if opt.reclevel is exceeded.  */
  if ((opt.reclevel != 0) && (depth > opt.reclevel))
    {
      DEBUGP (("Recursion depth %d exceeded max. depth %d.\n",
	       depth, opt.reclevel));
      --depth;
      return RECLEVELEXC;
    }

  /* Determine whether this_url is an FTP URL.  If it is, it means
     that the retrieval is done through proxy.  In that case, FTP
     links will be followed by default and recursion will not be
     turned off when following them.  */
  this_url_ftp = (urlproto (this_url) == URLFTP);

  /* Get the URL-s from an HTML file: */
  url_list = get_urls_html (file,
			    canon_this_url ? canon_this_url : this_url, 0);

  /* Decide what to do with each of the URLs.  A URL will be loaded if
     it meets several requirements, discussed later.  */
  for (cur_url = url_list; cur_url; cur_url = cur_url->next)
    {
      /* If quota was exceeded earlier, bail out.  */
      if (opt.quota && (opt.downloaded > opt.quota))
	break;
      /* Parse the URL for convenient use in other functions, as well
	 as to get the optimized form.  It also checks URL integrity.  */
      u = newurl ();
      if (parseurl (cur_url->url, u, 0) != URLOK)
	{
	  DEBUGP (("Yuck!  A bad URL.\n"));
	  freeurl (u, 1);
	  continue;
	}
      if (u->proto == URLFILE)
	{
	  DEBUGP (("Nothing to do with file:// around here.\n"));
	  freeurl (u, 1);
	  continue;
	}
      assert (u->url != NULL);
      constr = xstrdup (u->url);

      /* Several checkings whether a file is acceptable to load:
	 1. check if URL is ftp, and we don't load it
	 2. check for relative links (if relative_only is set)
	 3. check for domain
	 4. check for no-parent
	 5. check for excludes && includes
	 6. check for suffix
	 7. check for same host (if spanhost is unset), with possible
	 gethostbyname baggage
	 8. check for robots.txt

	 Addendum: If the URL is FTP, and it is to be loaded, only the
	 domain and suffix settings are "stronger".

	 Note that .html and (yuck) .htm will get loaded
	 regardless of suffix rules (but that is remedied later with
	 unlink).

	 More time- and memory- consuming tests should be put later on
	 the list.  */

      /* inl is set if the URL we are working on (constr) is stored in
	 ulist.  Using it is crucial to avoid the incessant calls to
	 in_slist, which is quite slow.  */
      inl = in_slist (ulist, constr);

      /* If it is FTP, and FTP is not followed, chuck it out.  */
      if (!inl)
	if (u->proto == URLFTP && !opt.follow_ftp && !this_url_ftp)
	  {
	    DEBUGP (("Uh, it is FTP but i'm not in the mood to follow FTP.\n"));
	    ulist = add_slist (ulist, constr, 0);
	    inl = 1;
	  }
      /* If it is absolute link and they are not followed, chuck it
	 out.  */
      if (!inl && u->proto != URLFTP)
	if (opt.relative_only && !(cur_url->flags & URELATIVE))
	  {
	    DEBUGP (("It doesn't really look like a relative link.\n"));
	    ulist = add_slist (ulist, constr, 0);
	    inl = 1;
	  }
      /* If its domain is not to be accepted/looked-up, chuck it out.  */
      if (!inl)
	if (!accept_domain (u))
	  {
	    DEBUGP (("I don't like the smell of that domain.\n"));
	    ulist = add_slist (ulist, constr, 0);
	    inl = 1;
	  }
      /* Check for parent directory.  */
      if (!inl && opt.no_parent
	  /* If the new URL is FTP and the old was not, ignore
             opt.no_parent.  */
	  && !(!this_url_ftp && u->proto == URLFTP))
	{
	  /* Check for base_dir first.  */
	  if (!(base_dir && frontcmp (base_dir, u->dir)))
	    {
	      /* Failing that, check for parent dir.  */
	      struct urlinfo *ut = newurl ();
	      if (parseurl (this_url, ut, 0) != URLOK)
		DEBUGP (("Double yuck!  The *base* URL is broken.\n"));
	      else if (!frontcmp (ut->dir, u->dir))
		{
		  /* Failing that too, kill the URL.  */
		  DEBUGP (("Trying to escape parental guidance with no_parent on.\n"));
		  ulist = add_slist (ulist, constr, 0);
		  inl = 1;
		}
	      freeurl (ut, 1);
	    }
	}
      /* If the file does not match the acceptance list, or is on the
	 rejection list, chuck it out.  The same goes for the
	 directory exclude- and include- lists.  */
      if (!inl && (opt.includes || opt.excludes))
	{
	  if (!accdir (u->dir, ALLABS))
	    {
	      DEBUGP (("%s (%s) is excluded/not-included.\n", constr, u->dir));
	      ulist = add_slist (ulist, constr, 0);
	      inl = 1;
	    }
	}
      if (!inl)
	{
	  char *suf = NULL;
	  /* We check for acceptance/rejection rules only for non-HTML
	     documents.  Since we don't know whether they really are
	     HTML, it will be deduced from (an OR-ed list):

	     1) u->file is "" (meaning it is a directory)
	     2) suffix exists, AND:
	     a) it is "html", OR
	     b) it is "htm"

	     If the file *is* supposed to be HTML, it will *not* be
	     subject to acc/rej rules.  That's why the `!'.  */
	  if (!
	      (!*u->file
	       || (((suf = suffix (constr)) != NULL)
		   && (!strcmp (suf, "html") || !strcmp (suf, "htm")))))
	    {
	      if (!acceptable (u->file))
		{
		  DEBUGP (("%s (%s) does not match acc/rej rules.\n",
			  constr, u->file));
		  ulist = add_slist (ulist, constr, 0);
		  inl = 1;
		}
	    }
	  FREE_MAYBE (suf);
	}
      /* Optimize the URL (which includes possible DNS lookup) only
	 after all other possibilities have been exhausted.  */
      if (!inl)
	{
	  if (!opt.simple_check)
	    opt_url (u);
	  else
	    {
	      char *p;
	      /* Just lowercase the hostname.  */
	      for (p = u->host; *p; p++)
		*p = tolower (*p);
	      free (u->url);
	      u->url = str_url (u, 0);
	    }
	  free (constr);
	  constr = xstrdup (u->url);
	  inl = in_slist (ulist, constr);
	  if (!inl && !((u->proto == URLFTP) && !this_url_ftp))
	    if (!opt.spanhost && this_url && !same_host (this_url, constr))
	      {
		DEBUGP (("This is not the same hostname as the parent's.\n"));
		ulist = add_slist (ulist, constr, 0);
		inl = 1;
	      }
	}
      /* What about robots.txt?  */
      if (!inl && opt.use_robots && u->proto == URLHTTP)
	{
	  /* Since Wget knows about only one set of robot rules at a
	     time, /robots.txt must be reloaded whenever a new host is
	     accessed.

	     robots_host holds the host the current `forbid' variable
	     is assigned to.  */
	  if (!robots_host || !same_host (robots_host, u->host))
	    {
	      FREE_MAYBE (robots_host);
	      /* Now make robots_host the new host, no matter what the
		 result will be.  So if there is no /robots.txt on the
		 site, Wget will not retry getting robots all the
		 time.  */
	      robots_host = xstrdup (u->host);
	      free_vec (forbidden);
	      forbidden = NULL;
	      err = retrieve_robots (constr, ROBOTS_FILENAME);
	      if (err == ROBOTSOK)
		{
		  rurl = robots_url (constr, ROBOTS_FILENAME);
		  rfile = url_filename (rurl);
		  forbidden = parse_robots (rfile);
		  freeurl (rurl, 1);
		  free (rfile);
		}
	    }

	  /* Now that we have (or don't have) robots, we can check for
	     them.  */
	  if (!robots_match (u, forbidden))
	    {
	      DEBUGP (("Stuffing %s because %s forbids it.\n", this_url,
		       ROBOTS_FILENAME));
	      ulist = add_slist (ulist, constr, 0);
	      inl = 1;
	    }
	}

      filename = NULL;
      /* If it wasn't chucked out, do something with it.  */
      if (!inl)
	{
	  DEBUGP (("I've decided to load it -> "));
	  /* Add it to the list of already-loaded URL-s.  */
	  ulist = add_slist (ulist, constr, 0);
	  /* Automatically followed FTPs will *not* be downloaded
	     recursively.  */
	  if (u->proto == URLFTP)
	    {
	      /* Don't you adore side-effects?  */
	      opt.recursive = 0;
	    }
	  /* Reset its type.  */
	  dt = 0;
	  /* Retrieve it.  */
	  retrieve_url (constr, &filename, &newloc,
		       canon_this_url ? canon_this_url : this_url, &dt);
	  if (u->proto == URLFTP)
	    {
	      /* Restore...  */
	      opt.recursive = 1;
	    }
	  if (newloc)
	    {
	      free (constr);
	      constr = newloc;
	    }
	  /* In case of convert_links: If there was no error, add it to
	     the list of downloaded URLs.  We might need it for
	     conversion.  */
	  if (opt.convert_links && filename)
	    {
	      if (dt & RETROKF)
		{
		  urls_downloaded = add_url (urls_downloaded, constr, filename);
		  /* If the URL is HTML, note it.  */
		  if (dt & TEXTHTML)
		    urls_html = add_slist (urls_html, filename, NOSORT);
		}
	    }
	  /* If there was no error, and the type is text/html, parse
	     it recursively.  */
	  if (dt & TEXTHTML)
	    {
	      if (dt & RETROKF)
		recursive_retrieve (filename, constr);
	    }
	  else
	    DEBUGP (("%s is not text/html so we don't chase.\n",
		     filename ? filename: "(null)"));
	  /* If an suffix-rejected file was loaded only because it was HTML,
	     undo the error now */
	  if (opt.delete_after || (filename && !acceptable (filename)))
	    {
	      logprintf (LOG_VERBOSE,
			 (opt.delete_after ? _("Removing %s.\n")
			  : _("Removing %s since it should be rejected.\n")),
			 filename);
	      if (unlink (filename))
		logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
	      dt &= ~RETROKF;
	    }
	  /* If everything was OK, and links are to be converted, let's
	     store the local filename.  */
	  if (opt.convert_links && (dt & RETROKF) && (filename != NULL))
	    {
	      cur_url->flags |= UABS2REL;
	      cur_url->local_name = xstrdup (filename);
	    }
	}
      DEBUGP (("%s already in list, so we don't load.\n", constr));
      /* Free filename and constr.  */
      FREE_MAYBE (filename);
      FREE_MAYBE (constr);
      freeurl (u, 1);
      /* Increment the pbuf for the appropriate size.  */
    }
  if (opt.convert_links)
    convert_links (file, url_list);
  /* Free the linked list of URL-s.  */
  free_urlpos (url_list);
  /* Free the canonical this_url.  */
  FREE_MAYBE (canon_this_url);
  /* Decrement the recursion depth.  */
  --depth;
  if (opt.quota && (opt.downloaded > opt.quota))
    return QUOTEXC;
  else
    return RETROK;
}
Exemple #14
0
int 
main(int argc, char *argv[])
{
  int            x; 
  int            result;
  DATA           D = new_data();
  CREW           crew;           /* thread pool - crew.h */
  LINES          *lines;         /* defined in setup.h   */
  CLIENT         *client;        /* defined in setup.h   */
  URL            **urls;         /* urls struct array    */
  pthread_t      cease;          /* the shutdown thread  */
  pthread_t      timer;          /* the timer thread     */
  pthread_attr_t scope_attr;     /* set to PTHREAD_SCOPE_SYSTEM */
  unsigned int   randrseed;      /* seed pthread_rand_np */
  char           exlogmsg[512];
  void *statusp;
  sigset_t sigs;

  sigemptyset(&sigs);
  sigaddset(&sigs, SIGHUP);
  sigaddset(&sigs, SIGINT);
  sigaddset(&sigs, SIGALRM);
  sigaddset(&sigs, SIGTERM);
  sigprocmask(SIG_BLOCK, &sigs, NULL);

  lines = xcalloc(sizeof(LINES),1);
  lines->index   = 0;
  lines->line    = NULL;

  memset(&my, 0, sizeof(struct CONFIG));

  parse_rc_cmdline(argc, argv); 
  if(init_config() < 0){        /* defined in init.h   */
    exit( EXIT_FAILURE );       /* polly was a girl... */
  } 
  parse_cmdline(argc, argv);    /* defined above       */
  ds_module_check();            /* check config integ  */

  if(my.get){
    my.cusers  = 1;
    my.reps    = 1;
    my.logging = FALSE;
    my.bench   = TRUE;
  } 

  if(my.config){
    show_config(TRUE);    
  }

  if(my.url != NULL){
    my.length = 1; 
  } else { 
    my.length = read_cfg_file( lines, my.file ); 
  }

  if(my.length == 0){ 
    display_help();
  }

  /* cookie is an EXTERN, defined in setup */ 
  cookie = xcalloc(sizeof(COOKIE), 1); 
  cookie->first = NULL;
  if((result = pthread_mutex_init( &(cookie->mutex), NULL)) !=0){
    joe_fatal( "pthread_mutex_init" );
  } 

  /* memory allocation for threads and clients */
  urls   = xmalloc(my.length * sizeof(URL));
  client = xmalloc(sizeof(CLIENT) * my.cusers);
  if((crew = new_crew(my.cusers, my.cusers, FALSE)) == NULL){
    joe_fatal("unable to allocate memory for %d simulated browser", my.cusers);  
  }

  /** 
   * determine the source of the url(s),
   * command line or file, and add them
   * to the urls struct.
   */
  if(my.url != NULL){
    urls[0]   =  add_url(my.url, 1);         /* from command line  */
  } else { 
    for(x = 0; x < my.length; x ++){
      urls[x] =  add_url(lines->line[x], x); /* from urls.txt file */
    }
  } 

  /**
   * display information about the siege
   * to the user and prepare for verbose 
   * output if necessary.
   */
  if(!my.get){
    fprintf(stderr, "** "); 
    display_version(FALSE);
    fprintf(stderr, "** Preparing %d concurrent users for battle.\n", my.cusers);
    fprintf(stderr, "The server is now under siege...");
    if(my.verbose){ fprintf(stderr, "\n"); }
	if(my.extralog) { 
		snprintf(exlogmsg, sizeof exlogmsg, "** Preparing %d concurrent users for battle.", my.cusers);
		log_extra(exlogmsg);
		log_extra("The server is now under siege...");
	}
  }

  /**
   * record start time before spawning threads
   * as the threads begin hitting the server as
   * soon as they are created.
   */
  data_set_start(D);

  /**
   * for each concurrent user, spawn a thread and
   * loop until condition or pthread_cancel from the
   * handler thread.
   */
  pthread_attr_init(&scope_attr);
  pthread_attr_setscope(&scope_attr, PTHREAD_SCOPE_SYSTEM);
#if defined(_AIX)
  /* AIX, for whatever reason, defies the pthreads standard and  *
   * creates threads detached by default. (see pthread.h on AIX) */
  pthread_attr_setdetachstate(&scope_attr, PTHREAD_CREATE_JOINABLE);
#endif

  /** 
   * invoke OpenSSL's thread safety
   */
#ifdef HAVE_SSL
  SSL_thread_setup();
#endif

  /**
   * create the signal handler and timer;  the
   * signal handler thread (cease) responds to
   * ctrl-C (sigterm) and the timer thread sends
   * sigterm to cease on time out.
   */
  if((result = pthread_create(&cease, NULL, (void*)sig_handler, (void*)crew)) < 0){
    joe_fatal("failed to create handler: %d\n", result);
  }
  if(my.secs > 0){
    if((result = pthread_create(&timer, NULL, (void*)siege_timer, (void*)cease)) < 0){
      joe_fatal("failed to create handler: %d\n", result);
    } 
  }
  
  randrseed = time(0);

  /**
   * loop until my.cusers and create a corresponding thread...
   */  
  for(x = 0; x < my.cusers && crew_get_shutdown(crew) != TRUE; x++){
    client[x].id              = x; 
    client[x].bytes           = 0;
    client[x].time            = 0.0;
    client[x].hits            = 0;
    client[x].code            = 0;
    client[x].ok200           = 0;   
    client[x].fail            = 0; 
    client[x].U               = urls;
    client[x].auth.www        = 0;
    client[x].auth.proxy      = 0;
    client[x].auth.type.www   = BASIC;
    client[x].auth.type.proxy = BASIC;
    client[x].rand_r_SEED     = pthread_rand_np(&randrseed);
    result = crew_add(crew, (void*)start_routine, &(client[x]));
    if(result == FALSE){ 
      my.verbose = FALSE;
      fprintf(stderr, "Unable to spawn additional threads; you may need to\n");
      fprintf(stderr, "upgrade your libraries or tune your system in order\n"); 
      fprintf(stderr, "to exceed %d users.\n", my.cusers);
      joe_fatal("system resources exhausted"); 
    }
  } /* end of for pthread_create */

  crew_join(crew, TRUE, &statusp);

#ifdef HAVE_SSL
  SSL_thread_cleanup();
#endif

  /**
   * collect all the data from all the threads that
   * were spawned by the run.
   */
  for(x = 0; x < ((crew_get_total(crew) > my.cusers || 
                   crew_get_total(crew)==0 ) ? my.cusers : crew_get_total(crew)); x++){
    data_increment_count(D, client[x].hits);
    data_increment_bytes(D, client[x].bytes);
    data_increment_total(D, client[x].time);
    data_increment_code (D, client[x].code);
    data_increment_ok200(D, client[x].ok200);
    data_increment_fail (D, client[x].fail);
    data_set_highest    (D, client[x].bigtime);
    data_set_lowest     (D, client[x].smalltime);
    client[x].rand_r_SEED = pthread_rand_np(&randrseed);
  } /* end of stats accumulation */
  
  /**
   * record stop time
   */
  data_set_stop(D);

  /**
   * cleanup crew
   */ 
  crew_destroy(crew);

  if(my.get){
    if(data_get_count(D) > 0){
      exit(EXIT_SUCCESS);
    } else {
      printf("[done]\n");
      exit(EXIT_FAILURE);
    }
  }

  /**
   * take a short nap  for  cosmetic  effect
   * this does NOT affect performance stats.
   */
  pthread_usleep_np(10000);
  if(my.verbose)
    fprintf(stderr, "done.\n");
  else
    fprintf(stderr, "\b      done.\n");
  if(my.extralog)
	log_extra("done.");

  /**
   * prepare and print statistics.
   */
  if(my.failures > 0 && my.failed >= my.failures){
    fprintf(stderr, "%s aborted due to excessive socket failure; you\n", program_name);
    fprintf(stderr, "can change the failure threshold in $HOME/.%src\n", program_name);
  }
  fprintf(stderr, "\bTransactions:\t\t%12u hits\n",        data_get_count(D));
  fprintf(stderr, "Availability:\t\t%12.2f %%\n",          data_get_count(D)==0 ? 0 :
                                                           (double)data_get_count(D) /
                                                           (data_get_count(D)+my.failed)
                                                           *100
  );
  fprintf(stderr, "Elapsed time:\t\t%12.2f secs\n",        data_get_elapsed(D));
  fprintf(stderr, "Data transferred:\t%12.2f MB\n",        data_get_megabytes(D)); /*%12llu*/
  fprintf(stderr, "Response time:\t\t%12.2f secs\n",       data_get_response_time(D));
  fprintf(stderr, "Transaction rate:\t%12.2f trans/sec\n", data_get_transaction_rate(D));
  fprintf(stderr, "Throughput:\t\t%12.2f MB/sec\n",        data_get_throughput(D));
  fprintf(stderr, "Concurrency:\t\t%12.2f\n",              data_get_concurrency(D));
  fprintf(stderr, "Successful transactions:%12u\n",        data_get_code(D)); 
  if(my.debug){
    fprintf(stderr, "HTTP OK received:\t%12u\n",             data_get_ok200(D));
  }
  fprintf(stderr, "Failed transactions:\t%12u\n",          my.failed);
  fprintf(stderr, "Longest transaction:\t%12.2f\n",        data_get_highest(D));
  fprintf(stderr, "Shortest transaction:\t%12.2f\n",       data_get_lowest(D));
  fprintf(stderr, " \n");
  if(my.mark)    mark_log_file(my.markstr);
  if(my.logging) log_transaction(D);

  data_destroy(D);
  if(my.url == NULL){
    for(x = 0; x < my.length; x++)
       xfree(lines->line[x]);
    xfree(lines->line);
    xfree(lines);
  }  

  exit(EXIT_SUCCESS);	
} /* end of int main **/