int cl_endpoint_list_get_autoclose_mode(cl_raw_list_t* list_p, cl_com_endpoint_t* endpoint, cl_xml_connection_autoclose_t* autoclose) {
   int back = CL_RETVAL_UNKNOWN_ENDPOINT;
   int ret_val = CL_RETVAL_OK;
   cl_endpoint_list_elem_t* elem = NULL;
   
   if (list_p == NULL || endpoint == NULL || autoclose == NULL) {
      return CL_RETVAL_PARAMS;
   }

   *autoclose = CL_CM_AC_UNDEFINED;

   /* lock list */
   if ( (ret_val = cl_raw_list_lock(list_p)) != CL_RETVAL_OK) {
      return ret_val;
   }

   elem = cl_endpoint_list_get_elem_endpoint(list_p, endpoint);
   if (elem != NULL) { 
      /* found matching endpoint */
      back = CL_RETVAL_OK;
      CL_LOG_INT(CL_LOG_INFO,"setting autoclose to:", elem->autoclose);
      *autoclose = elem->autoclose;
   } 

   /* unlock list */
   if ( (ret_val = cl_raw_list_unlock(list_p)) != CL_RETVAL_OK) {
      return ret_val;
   }
   return back;
}
void *my_log_thread(void *t_conf) {
   int do_exit = 0;
   /* get pointer to cl_thread_settings_t struct */
   cl_thread_settings_t *thread_config = (cl_thread_settings_t*)t_conf; 


   /* setup thread config ( at least done by call to cl_thread_func_startup() ) */
   if ( cl_thread_set_thread_config(thread_config) != CL_RETVAL_OK) {
      printf("cl_thread_set_thread_config() error\n");
   }


   CL_LOG( CL_LOG_INFO,   "starting initialization ...");
   /* setup thread  begin */

   /* enter setup code here ... */

   /* setup thread  end */

   /* thread init done, trigger startup conditon variable*/
   cl_thread_func_startup(thread_config);

   CL_LOG( CL_LOG_INFO,   "init done ...");

   CL_LOG( CL_LOG_INFO,  "starting main loop ...");

   /* ok, thread main */
   while (do_exit == 0) {
      int ret_val;

      /* check for cancel */
      cl_thread_func_testcancel(thread_config);

      /* sleep till event arives */
      if ((ret_val = cl_thread_wait_for_event(thread_config,0,25000)) != CL_RETVAL_OK) {  /* nothing to do */
         switch(ret_val) {
            case CL_RETVAL_CONDITION_WAIT_TIMEOUT:
               break;
            default: {
               CL_LOG_INT(CL_LOG_INFO,  ">got error<: ", ret_val);
               do_exit = 1;
            }
         }
      }
   }

   /* this only happens on error */
   CL_LOG( CL_LOG_INFO,  "exiting ...");

   /* at least set exit state */
   cl_thread_func_cleanup(thread_config);  
   return(NULL);
}
int cl_endpoint_list_set_entry_life_time(cl_raw_list_t* list_p, long entry_life_time ) {
   cl_endpoint_list_data_t* ldata = NULL;

   ldata = cl_endpoint_list_get_data(list_p);
   if (ldata != NULL) {
      ldata->entry_life_time = entry_life_time;
      CL_LOG_INT(CL_LOG_INFO,"setting entry life time to", entry_life_time);
      return CL_RETVAL_OK;
   } else {
      CL_LOG(CL_LOG_ERROR,"can't set new entry_life_time");
   }
   return CL_RETVAL_PARAMS;
}
int cl_endpoint_list_setup(cl_raw_list_t** list_p, 
                           char* list_name, 
                           long entry_life_time,
                           long refresh_interval,
                           bool create_hash) {

   int ret_val = CL_RETVAL_OK;
   struct timeval now;
   cl_endpoint_list_data_t* ldata = NULL;

   ldata = (cl_endpoint_list_data_t*) malloc(sizeof(cl_endpoint_list_data_t));
   if (ldata == NULL ) {
      return CL_RETVAL_MALLOC;
   }

   gettimeofday(&now, NULL);

   ldata->entry_life_time      = entry_life_time;
   ldata->refresh_interval     = refresh_interval;
   ldata->last_refresh_time    = now.tv_sec;
   

   if (ldata->entry_life_time == 0) {
      CL_LOG(CL_LOG_INFO,"using default value for entry_life_time");
      ldata->entry_life_time = CL_ENDPOINT_LIST_DEFAULT_LIFE_TIME;
   }

   if (ldata->refresh_interval == 0) {
      CL_LOG(CL_LOG_INFO,"using default value for refresh_interval");
      ldata->refresh_interval = CL_ENDPOINT_LIST_DEFAULT_REFRESH_TIME;
   }


   ret_val = cl_raw_list_setup(list_p,list_name, 1);
   if (ret_val != CL_RETVAL_OK) {
      sge_free(&ldata);
      return ret_val;
   }

   /* create hashtable */
   if (create_hash == true) {
      ldata->ht = sge_htable_create(4, dup_func_string, hash_func_string, hash_compare_string);
      if (ldata->ht == NULL) {
         cl_raw_list_cleanup(list_p);
         sge_free(&ldata);
         return CL_RETVAL_MALLOC;
      }
      CL_LOG_INT(CL_LOG_INFO,"created hash table with size =", 4);
   } else {
      CL_LOG(CL_LOG_INFO,"created NO hash table!");
      ldata->ht = NULL;
   }

   /* set private list data */
   (*list_p)->list_data = ldata;

   CL_LOG_INT(CL_LOG_INFO,"entry_life_time is: ", ldata->entry_life_time);
   CL_LOG_INT(CL_LOG_INFO,"refresh_interval is:", ldata->refresh_interval);

   return ret_val;
}
extern int main(int argc, char** argv)
{
  cl_raw_list_t* log_list = NULL;
  cl_thread_settings_t* thread_p = NULL;
  cl_thread_settings_t* log_thread = NULL;
  cl_thread_settings_t* dummy_thread_p = NULL;
  int count = 2;



  if (argc != 2) {
     printf("please enter 0 for standard log function, 1 for special\n");
     exit(1);
  }


  /* setup log list */
  if (atoi(argv[1]) == 0) {
     cl_log_list_setup(&log_list,"application",0,CL_LOG_IMMEDIATE, NULL);
  } else {
     cl_log_list_setup(&log_list,"application",0,CL_LOG_IMMEDIATE, my_log_flush_list);
  }

  /* setup log thread */
  log_thread = (cl_thread_settings_t*) malloc(sizeof(cl_thread_settings_t));
  cl_thread_setup(log_thread, log_list, "log thread", 1,my_log_thread, NULL, NULL, CL_TT_USER1);
  cl_log_list_set_log_level(log_list,CL_LOG_DEBUG );

  /* setup thread list */
  cl_thread_list_setup(&thread_list,"thread list");

  /* setup first thread */
  cl_thread_list_create_thread(thread_list, &dummy_thread_p, log_list, "1st thread", 1, my_test_thread, NULL, NULL, CL_TT_USER1);

  /* setup second thread */
  cl_thread_list_create_thread(thread_list, &dummy_thread_p, log_list, "2nd thread", 2, my_test_thread, NULL, NULL, CL_TT_USER1);

  
  thread_p = cl_thread_list_get_thread_by_id(thread_list, 1);
  CL_LOG_STR( CL_LOG_INFO,  "My thread name is ", thread_p->thread_name  );

  thread_p = cl_thread_list_get_thread_by_name(thread_list, "2nd thread");
  CL_LOG_STR( CL_LOG_INFO,  "My thread name is ", thread_p->thread_name  );

  while ( count  < 10  ) {
     int id;
     char new_thread_name[255];

     count++;

     CL_LOG_INT(CL_LOG_INFO,  "number of threads: ", (int)cl_raw_list_get_elem_count(thread_list) );

     thread_p = cl_thread_list_get_first_thread(thread_list);
     id = thread_p->thread_id;

     CL_LOG_INT( CL_LOG_INFO,  "delete thread: ", id );
     cl_thread_list_delete_thread_by_id(thread_list, id);
     CL_LOG_INT(CL_LOG_INFO,  "thread deleted, id: ", id );


     sprintf(new_thread_name,"thread nr %d", count);
     CL_LOG( CL_LOG_INFO,  "adding thread ...");
     cl_thread_list_create_thread(thread_list,&dummy_thread_p, log_list,new_thread_name, id, my_test_thread, NULL, NULL, CL_TT_USER1);
     CL_LOG( CL_LOG_INFO, "adding thread done");

  }

  
  /* remove all threads from thread list */
  while ( (thread_p=cl_thread_list_get_first_thread(thread_list)) != NULL ) {
     int id = thread_p->thread_id;
     CL_LOG_INT( CL_LOG_INFO,  "delete thread: ", id );
     CL_LOG_INT( CL_LOG_INFO,  "event calls: ", (int)thread_p->thread_event_count );

     cl_thread_list_delete_thread_by_id(thread_list, id);
     CL_LOG_INT( CL_LOG_INFO,  "thread deleted, id: ", id );
  }


  CL_LOG_INT( CL_LOG_INFO,  "log event calls: ", (int)log_thread->thread_event_count );

  CL_LOG( CL_LOG_INFO,  "cleaning up thread list");
  cl_thread_list_cleanup(&thread_list);

  /* shutdown of log thread */
  cl_thread_shutdown(log_thread);
  cl_thread_join(log_thread);
  cl_thread_cleanup(log_thread);
  free(log_thread);

  /* cleanup log list */
  CL_LOG( CL_LOG_INFO,  "cleaning up log list");
  printf( "cl_log_list_cleanup() returned: %s\n", cl_get_error_text(cl_log_list_cleanup(&log_list)));
  printf("main done\n");










  return 0;
}
void *my_test_thread(void *t_conf) {
   cl_thread_settings_t* thread_p = NULL;
   int counter = 0;
   int do_exit = 0;
   /* get pointer to cl_thread_settings_t struct */
   cl_thread_settings_t *thread_config = (cl_thread_settings_t*)t_conf; 

   /* setup thread config ( at least done by call to cl_thread_func_startup() ) */
   if (cl_thread_set_thread_config(thread_config) != CL_RETVAL_OK) {
      printf("cl_thread_set_thread_config() error\n");
   }
   
   CL_LOG( CL_LOG_INFO,   "starting initialization ...");
   /* setup thread  begin */

   /* enter setup code here ... */

   /* setup thread  end */

   /* thread init done, trigger startup conditon variable*/
   cl_thread_func_startup(thread_config);

   CL_LOG( CL_LOG_INFO,  "starting main loop ...");

   /* ok, thread main */
   while (do_exit == 0) {
      int ret_val;

      /* check for cancel */
      cl_thread_func_testcancel(thread_config); 

      CL_LOG( CL_LOG_INFO,  "try to get thread list lock ...");
      if (cl_raw_list_lock(thread_list) == CL_RETVAL_OK) {
         int id;
         CL_LOG( CL_LOG_INFO,  "locked thread list");

         if (thread_config->thread_id == 1) {
            thread_p = cl_thread_list_get_thread_by_id(thread_list,2);
            id = 2;
         } else {
            thread_p = cl_thread_list_get_thread_by_id(thread_list,1);
            id = 1;
         }
         if (thread_p) {
            if (thread_config->thread_id == 1) {
               cl_thread_trigger_event(thread_p);
               counter++;
               CL_LOG_INT( CL_LOG_INFO,  "events triggered: ", counter);
            }
         } else {
            CL_LOG_INT( CL_LOG_INFO,  "can't find thread : ", id);
         }
         CL_LOG( CL_LOG_INFO,  "unlocking thread list ...");
         cl_raw_list_unlock(thread_list);
      }

      /* sleep till event arives */
      if ((ret_val = cl_thread_wait_for_event(thread_config,0,10000)) != CL_RETVAL_OK) {  /* nothing to do */
         switch(ret_val) {
            case CL_RETVAL_CONDITION_WAIT_TIMEOUT:
/*               printf("thread %d: got timeout\n", thread_config->thread_id);  */
               break;
            default: {
               CL_LOG_INT( CL_LOG_INFO,  ">got error<: ", ret_val);
               do_exit = 1;
            }
         }
      }
   }


   /* this only happens on error */
   CL_LOG( CL_LOG_INFO,  "exiting ...");

   /* at least set exit state */
   cl_thread_func_cleanup(thread_config);  
   return(NULL);
}
int cl_host_list_setup(cl_raw_list_t** list_p, 
                       char* list_name,
                       cl_host_resolve_method_t method, 
                       char* host_alias_file, 
                       char* local_domain_name,
                       unsigned long entry_life_time,
                       unsigned long entry_update_time,
                       unsigned long entry_reresolve_time,
                       cl_bool_t create_hash) {
   int ret_val = CL_RETVAL_OK;
   cl_host_list_data_t* ldata = NULL;

   ldata = (cl_host_list_data_t*) malloc(sizeof(cl_host_list_data_t));
   if (ldata == NULL ) {
      return CL_RETVAL_MALLOC;
   }
   ldata->host_alias_file      = NULL;
   ldata->alias_file_changed   = 0;
   ldata->host_alias_list      = NULL;
   ldata->resolve_method       = method;
   ldata->entry_life_time      = entry_life_time;
   ldata->entry_update_time    = entry_update_time;
   ldata->entry_reresolve_time = entry_reresolve_time;
   ldata->last_refresh_time    = 0;

   if (local_domain_name == NULL && method == CL_LONG) {
      CL_LOG(CL_LOG_WARNING,"can't compare short host names without default domain when method is CL_LONG");
   }


   if (entry_life_time == 0) {
      unsigned long help_value = 0;

      help_value = cl_util_get_ulong_value(getenv("SGE_COMMLIB_HOST_LIST_LIFE_TIME"));
      if (help_value > 0) {
         CL_LOG(CL_LOG_INFO,"environment variable SGE_COMMLIB_HOST_LIST_LIFE_TIME is set");
         ldata->entry_life_time = help_value;
      } else {
         CL_LOG(CL_LOG_INFO,"using default value for entry_life_time");
         ldata->entry_life_time = CL_HOST_LIST_DEFAULT_LIFE_TIME;
      }
   }

   if (entry_update_time == 0) {
      unsigned long help_value = 0;

      help_value = cl_util_get_ulong_value(getenv("SGE_COMMLIB_HOST_LIST_UPDATE_TIME"));
      if (help_value > 0) {
         CL_LOG(CL_LOG_INFO,"environment variable SGE_COMMLIB_HOST_LIST_UPDATE_TIME is set");
         ldata->entry_update_time = help_value;
      } else {
         CL_LOG(CL_LOG_INFO,"using default value for entry_update_time");
         ldata->entry_update_time = CL_HOST_LIST_DEFAULT_UPDATE_TIME;
      }
   }

   if (entry_reresolve_time == 0) {
      unsigned long help_value = 0;

      help_value = cl_util_get_ulong_value(getenv("SGE_COMMLIB_HOST_LIST_RERESOLVE_TIME"));
      if (help_value > 0) {
         CL_LOG(CL_LOG_INFO,"environment variable SGE_COMMLIB_HOST_LIST_RERESOLVE_TIME is set");
         ldata->entry_reresolve_time = help_value;
      } else {
         CL_LOG(CL_LOG_INFO,"using default value for entry_reresolve_time");
         ldata->entry_reresolve_time = CL_HOST_LIST_DEFAULT_RERESOLVE_TIME;
      }
   }

   if ( ldata->entry_life_time > CL_HOST_LIST_MAX_LIFE_TIME) {
      CL_LOG_INT(CL_LOG_WARNING,"entry_life_time exceeds maximum of",CL_HOST_LIST_MAX_LIFE_TIME);
      CL_LOG(CL_LOG_WARNING,"using default value for entry_life_time");
      ldata->entry_life_time = CL_HOST_LIST_DEFAULT_LIFE_TIME;
   }

   if ( ldata->entry_update_time > CL_HOST_LIST_MAX_UPDATE_TIME) {
      CL_LOG_INT(CL_LOG_WARNING,"entry_update_time exceeds maximum of",CL_HOST_LIST_MAX_UPDATE_TIME);
      CL_LOG(CL_LOG_WARNING,"using default value for entry_update_time");
      ldata->entry_update_time = CL_HOST_LIST_DEFAULT_UPDATE_TIME;
   }

   if ( ldata->entry_reresolve_time > CL_HOST_LIST_MAX_RERESOLVE_TIME) {
      CL_LOG_INT(CL_LOG_WARNING,"entry_reresolve_time exceeds maximum of",CL_HOST_LIST_MAX_RERESOLVE_TIME);
      CL_LOG(CL_LOG_WARNING,"using default value for entry_reresolve_time");
      ldata->entry_reresolve_time = CL_HOST_LIST_DEFAULT_RERESOLVE_TIME;
   }

   if (ldata->entry_life_time <= ldata->entry_update_time || ldata->entry_life_time <= ldata->entry_reresolve_time) {
      free(ldata); 
      CL_LOG(CL_LOG_ERROR,"entry_life_time must be >= entry_update_time and >= entry_reresolve_time");
      cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_PARAMS, "SGE_COMMLIB_HOST_LIST_LIFE_TIME must be >= SGE_COMMLIB_HOST_LIST_UPDATE_TIME and >= SGE_COMMLIB_HOST_LIST_RERESOLVE_TIME");
      return CL_RETVAL_PARAMS;
   }
   if (ldata->entry_update_time <= ldata->entry_reresolve_time) {
      free(ldata); 
      CL_LOG(CL_LOG_ERROR,"entry_update_time must be >= entry_reresolve_time");
      cl_commlib_push_application_error(CL_LOG_ERROR, CL_RETVAL_PARAMS, "SGE_COMMLIB_HOST_LIST_UPDATE_TIME must be >= SGE_COMMLIB_HOST_LIST_RERESOLVE_TIME");
      return CL_RETVAL_PARAMS;
   }

   ret_val = cl_host_alias_list_setup(&(ldata->host_alias_list), "host alias list");
   if (ret_val != CL_RETVAL_OK) {
      free(ldata);
      CL_LOG(CL_LOG_ERROR,"error setting up host alias list");
      return ret_val;
   }

   if (host_alias_file != NULL) {
      ldata->host_alias_file = strdup(host_alias_file);
      ldata->alias_file_changed = 1;
      if (ldata->host_alias_file == NULL) {
         free(ldata);
         return CL_RETVAL_MALLOC;
      }
   } else {
      ldata->host_alias_file = NULL;
   }

   if (local_domain_name != NULL) {
      ldata->local_domain_name = strdup(local_domain_name);
      if (ldata->local_domain_name == NULL) {
         if (ldata->host_alias_file != NULL) {
            free(ldata->host_alias_file);
         }
         free(ldata);
         return CL_RETVAL_MALLOC;
      }
   } else {
      ldata->local_domain_name = NULL;
   }

   

   ret_val = cl_raw_list_setup(list_p,list_name, 1);
   if (ret_val != CL_RETVAL_OK) {
      if (ldata->host_alias_file != NULL) {
         free(ldata->host_alias_file);
      }
      if (ldata->local_domain_name != NULL) {
         free(ldata->local_domain_name);
      }
      free(ldata);
      return ret_val;
   }

   switch(ldata->resolve_method) {
      case CL_SHORT:
         CL_LOG(CL_LOG_INFO,"using short hostname for host compare operations");
         break;

      case CL_LONG:
         CL_LOG(CL_LOG_INFO,"using long hostname for host compare operations");
         break;

      default:
         CL_LOG(CL_LOG_WARNING,"undefined resolving method");
         break;
   }
 
   if (ldata->host_alias_file != NULL) {
      CL_LOG_STR(CL_LOG_INFO,"using host alias file:", ldata->host_alias_file);
   } else {
      CL_LOG(CL_LOG_INFO,"no host alias file specified");
   }
   if (ldata->local_domain_name != NULL) {
      CL_LOG_STR(CL_LOG_INFO,"using local domain name:", ldata->local_domain_name);
   } else {
      CL_LOG(CL_LOG_INFO,"no local domain specified");
   }

   /* create hashtable */
   if (create_hash == CL_TRUE) {
      ldata->ht = sge_htable_create(4, dup_func_string, hash_func_string, hash_compare_string);
      if (ldata->ht == NULL) {
         cl_raw_list_cleanup(list_p);
         if (ldata->host_alias_file != NULL) {
            free(ldata->host_alias_file);
         }
         if (ldata->local_domain_name != NULL) {
            free(ldata->local_domain_name);
         }
         free(ldata);
         return CL_RETVAL_MALLOC;
      }
      CL_LOG_INT(CL_LOG_INFO,"created hash table with size =", 4);
   } else {
      CL_LOG(CL_LOG_INFO,"created NO hash table!");
      ldata->ht = NULL;
   }

   /* set private list data */
   (*list_p)->list_data = ldata;

   CL_LOG_INT(CL_LOG_INFO,"entry_life_time is", (int)ldata->entry_life_time);
   CL_LOG_INT(CL_LOG_INFO,"entry_update_time is", (int)ldata->entry_update_time);
   CL_LOG_INT(CL_LOG_INFO,"entry_reresolve_time is", (int)ldata->entry_reresolve_time);

   return ret_val;
}
extern int main(int argc, char** argv)
{
    struct sigaction sa;
    static int runs = 100;


    cl_com_handle_t* handle = NULL;
    cl_com_message_t* message = NULL;
    cl_com_endpoint_t* sender = NULL;

    int bytes_received = 0;
    unsigned long total_bytes_sent = 0;
    unsigned long total_bytes_received = 0;
    unsigned long total_connections = 0;
    unsigned long total_connection_sum = 0;
#if 1
    char* welcome_text = "Welcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\nWelcome to the tcp framework module!Welcome to the tcp framework module!Welcome to the tcp framework module!\n";
#else
    char* welcome_text = "This message is from thread 1";
#endif

    struct timeval now;
    long start_time;
    long appl_start_time;
    long end_time;
    int retval = CL_RETVAL_PARAMS;
    int welcome_text_size;
    int close_connection = 0;
    unsigned long last_mid = 0;
    int i;
    cl_framework_t framework = CL_CT_TCP;
    cl_xml_connection_autoclose_t autoclose;

    /* setup signalhandling */
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sighandler_client;  /* one handler for all signals */
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGHUP, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);


    if (argc < 7) {
        printf("wrong parameters, param1 = server host, param2 = port number, param3 = client id, param4=debug_level, param5=sleep time, param6=do_close, [param7=framework(TCP/SSL)]\n");
        exit(1);
    }
    prof_mt_init();
    cl_com_setup_commlib(CL_NO_THREAD, (cl_log_t)atoi(argv[4]), NULL);
    if (atoi(argv[6]) != 0) {
        close_connection = 1;
    }
    if (argv[7]) {
        framework = CL_CT_UNDEFINED;
        if (strcmp(argv[7], "TCP") == 0) {
            framework=CL_CT_TCP;
            printf("using TCP framework\n");
        }
        if (strcmp(argv[7], "SSL") == 0) {
            framework=CL_CT_SSL;
            printf("using SSL framework\n");
        }
        if (framework == CL_CT_UNDEFINED) {
            printf("unexpected framework type\n");
            exit(1);
        }
    }

    cl_com_set_alias_file("./alias_file");
    if ( framework == CL_CT_SSL) {
        cl_ssl_setup_t ssl_config;
        ssl_config.ssl_method           = CL_SSL_v23;                 /*  v23 method                                  */
        ssl_config.ssl_CA_cert_pem_file = getenv("SSL_CA_CERT_FILE"); /*  CA certificate file                         */
        ssl_config.ssl_CA_key_pem_file  = NULL;                       /*  private certificate file of CA (not used)   */
        ssl_config.ssl_cert_pem_file    = getenv("SSL_CERT_FILE");    /*  certificates file                           */
        ssl_config.ssl_key_pem_file     = getenv("SSL_KEY_FILE");     /*  key file                                    */
        ssl_config.ssl_rand_file        = getenv("SSL_RAND_FILE");    /*  rand file (if RAND_status() not ok)         */
        ssl_config.ssl_crl_file         = getenv("SSL_CRL_FILE");     /*  revocation list file                        */
        ssl_config.ssl_reconnect_file   = NULL;                       /*  file for reconnect data    (not used)       */
        ssl_config.ssl_refresh_time     = 0;                          /*  key alive time for connections (not used)   */
        ssl_config.ssl_password         = NULL;                       /*  password for encrypted keyfiles (not used)  */
        ssl_config.ssl_verify_func      = NULL;                       /*  function callback for peer user/name check  */

        if (ssl_config.ssl_CA_cert_pem_file == NULL ||
                ssl_config.ssl_cert_pem_file    == NULL ||
                ssl_config.ssl_key_pem_file     == NULL ||
                ssl_config.ssl_rand_file        == NULL) {
            printf("please set the following environment variables:\n");
            printf("SSL_CA_CERT_FILE         = CA certificate file\n");
            printf("SSL_CERT_FILE            = certificates file\n");
            printf("SSL_KEY_FILE             = key file\n");
            printf("(optional) SSL_RAND_FILE = rand file (if RAND_status() not ok)\n");
        }
        cl_com_specify_ssl_configuration(&ssl_config);
    }
    CL_LOG_STR(CL_LOG_INFO,"connection to server on host", argv[1]);
    CL_LOG_INT(CL_LOG_INFO,"using port",atoi(argv[2]));

    CL_LOG_STR(CL_LOG_INFO,"component is","client");
    CL_LOG_INT(CL_LOG_INFO,"id ist",atoi(argv[3]));
#define SELECT_TIMEOUT 1
#if 0
#define CREATE_SERVICE
#endif

#ifdef CREATE_SERVICE
    cl_com_append_known_endpoint_from_name(argv[1], "server", 1,atoi(argv[2]),CL_CM_AC_DISABLED , 1);
    handle=cl_com_create_handle(NULL,framework,CL_CM_CT_MESSAGE , CL_TRUE, 0 , CL_TCP_DEFAULT, "client", atoi(argv[3]),SELECT_TIMEOUT,0 );
    if (handle == NULL) {
        printf("could not get handle\n");
        exit(1);
    } else {
        int my_port;
        cl_com_get_service_port(handle,&my_port);
        printf("I'm reachable at port %d!\n", my_port);
    }
#else
    handle=cl_com_create_handle(NULL,framework,CL_CM_CT_MESSAGE , CL_FALSE, atoi(argv[2]) , CL_TCP_DEFAULT,"client", atoi(argv[3]),SELECT_TIMEOUT,0 );
    if (handle == NULL) {
        printf("could not get handle\n");
        exit(1);
    }
#endif

    cl_com_set_auto_close_mode(handle,CL_CM_AC_ENABLED );
    cl_com_get_auto_close_mode(handle,&autoclose);
    if (autoclose != CL_CM_AC_ENABLED ) {
        printf("could not enable autoclose\n");
        exit(1);
    }

    printf("local hostname is \"%s\"\n", handle->local->comp_host);
    printf("local component is \"%s\"\n", handle->local->comp_name);
    printf("local component id is \"%ld\"\n", handle->local->comp_id);

#ifdef CREATE_SERVICE
    cl_com_get_known_endpoint_port_from_name(argv[1], "server", 1, &i);
    printf("connecting to port \"%d\" on host \"%s\"\n", i, argv[1]);
#else
    cl_com_get_connect_port(handle, &i);
    printf("connecting to port \"%d\" on host \"%s\"\n", i, argv[1]);
#endif


    gettimeofday(&now,NULL);
    start_time =    now.tv_sec;
    appl_start_time = start_time;
    welcome_text_size = strlen(welcome_text) + 1;

    if (getenv("CL_RUNS")) {
        runs = atoi(getenv("CL_RUNS"));
    } else {
        runs = -1;  /* disable runs shutdown */
    }
    while(do_shutdown != 1) {
        unsigned long mid = 0;
        int my_sent_error = 0;

        CL_LOG(CL_LOG_INFO,"main loop");
        if (runs > 0) {
            runs--;
        }

        /* printf("sending to \"%s\" ...\n", argv[1]);  */

        /*     CL_LOG(CL_LOG_ERROR,"sending ack message ..."); */

        my_sent_error = cl_commlib_send_message(handle, argv[1], "server", 1, CL_MIH_MAT_ACK, (cl_byte_t**)&welcome_text , welcome_text_size, &mid ,0,0, CL_TRUE, CL_FALSE);
        if ( retval == CL_RETVAL_CONNECTION_NOT_FOUND ) {
            CL_LOG(CL_LOG_ERROR,"after new connection");
        }

        if (last_mid >= mid || mid == 1) {
            total_connections++;
            total_connection_sum++;
        }
        last_mid = mid;

#if 1
        if (my_sent_error != CL_RETVAL_OK) {
            printf("cl_commlib_send_message() returned %s\n", cl_get_error_text(my_sent_error));
#ifdef CREATE_SERVICE
            cl_com_get_known_endpoint_port_from_name(argv[1], "server", 1, &i);
            printf("connecting to port \"%d\" on host \"%s\"\n", i, argv[1]);
#else
            cl_com_get_connect_port(handle, &i);
            printf("connecting to port \"%d\" on host \"%s\"\n", i, argv[1]);
#endif

            /* exit(1); */
#if CL_DO_SLOW
            sleep(atoi(argv[5]));
#endif
            cl_commlib_trigger(handle,1);
            continue;
        }
#endif
#if 1
        retval = CL_RETVAL_PARAMS;
        while (retval != CL_RETVAL_OK ) {


            while ( (retval=cl_commlib_receive_message(handle,NULL, NULL, 0, CL_FALSE, 0, &message, &sender)) == CL_RETVAL_OK) {
                if (message != NULL) {
                    cl_com_free_endpoint(&sender);
                    cl_com_free_message(&message);
                } else {
                    break;
                }
            }

            if ( retval == CL_RETVAL_CONNECTION_NOT_FOUND ) {
                CL_LOG(CL_LOG_ERROR,"connection not found (1)");
                break;
            }

            retval = cl_commlib_check_for_ack(handle, argv[1], "server", 1, mid, CL_TRUE );
            if (retval != CL_RETVAL_MESSAGE_WAIT_FOR_ACK && retval != CL_RETVAL_OK) {
                printf("retval of cl_commlib_check_for_ack(%ld) is %s\n",mid,cl_get_error_text(retval));
                /* exit(1);  */
                break;
            }
            if (retval == CL_RETVAL_OK) {
                CL_LOG_INT(CL_LOG_INFO,"received ack for message mid", (int)mid);
            } else {
                cl_commlib_trigger(handle, 1);
            }

            if ( retval == CL_RETVAL_CONNECTION_NOT_FOUND ) {
                CL_LOG(CL_LOG_ERROR,"connection not found (2)");
                break;
            }



            /*        printf("retval of cl_commlib_check_for_ack(%ld) is %s\n",mid,cl_get_error_text(retval));  */
        }
        if (retval == CL_RETVAL_CONNECTION_NOT_FOUND) {
            cl_commlib_trigger(handle, 1);
            continue;
        }
#endif


        total_bytes_sent  = total_bytes_sent + welcome_text_size;
        CL_LOG_INT(CL_LOG_INFO,"bytes sent:", welcome_text_size);

        bytes_received = 0;
        while (bytes_received != welcome_text_size ) {

            cl_commlib_trigger(handle, 1);


            CL_LOG_INT(CL_LOG_INFO,"waiting for mid .... ", (int)mid);
            retval = cl_commlib_receive_message(handle,NULL, NULL, 0, CL_FALSE, mid, &message, &sender);


            CL_LOG_STR(CL_LOG_INFO,"waiting for bytes ...", cl_get_error_text(retval));
            if (retval == CL_RETVAL_CONNECTION_NOT_FOUND) {
#if CL_DO_SLOW
                /*           CL_LOG(CL_LOG_ERROR,"connection not found"); */

                if (atoi(argv[5]) > 0) {
                    printf("sleeping...\n");
                    sleep(atoi(argv[5]));
                }
#endif
                break;
            }
            if (message != NULL) {

                /*   printf("received message from \"%s\"\n", sender->comp_host); */
                CL_LOG_INT(CL_LOG_INFO,"bytes received:", (int)message->message_length);
                if (strcmp((char*)message->message, welcome_text) != 0) {
                    printf("------------------------> message transfer error\n");
                }
                total_bytes_received = total_bytes_received + message->message_length;
                bytes_received = bytes_received + (int)message->message_length;
                cl_com_free_endpoint(&sender);
                cl_com_free_message(&message);
            }

            while ( (retval = cl_commlib_receive_message(handle,NULL, NULL, 0, CL_FALSE, 0, &message, &sender)) == CL_RETVAL_OK) {
                if (message != NULL) {
                    cl_com_free_endpoint(&sender);
                    cl_com_free_message(&message);
                } else {
                    break;
                }
            }

            if (retval == CL_RETVAL_CONNECTION_NOT_FOUND) {
                CL_LOG(CL_LOG_ERROR,"connection not found (3)");
                break;

            }


#if CL_DO_SLOW
            sleep(atoi(argv[5]));
#endif
            if (do_shutdown == 1) {
                break;
            }
        }


#if CL_DO_SLOW
        sleep(atoi(argv[5]));
#endif
        gettimeofday(&now,NULL);
        end_time =    now.tv_sec;
        if (end_time - start_time >= 2 ) {
            cl_com_connection_t* con = NULL;
            cl_connection_list_elem_t* elem = NULL;
            /*        printf("Kbit/s sent: %.2f   ", ((total_bytes_sent * 8.0)/1024.0) /  (double)(end_time - start_time));
                    printf("Kbit/s read: %.2f   ", ((total_bytes_received * 8.0)/1024.0) /  (double)(end_time - start_time)); */
            printf("KBit/s     : %.2f   ", (((total_bytes_received + total_bytes_sent) * 8.0)/1024.0) /  (double)(end_time - start_time));
            printf("connections/s: %.2f ", (double) total_connections / (double)(end_time - start_time));
            printf("avg. connections/s: %.2f", (double) total_connection_sum / (double)(end_time - appl_start_time));
            cl_raw_list_lock(handle->connection_list);
            elem = cl_connection_list_get_first_elem(handle->connection_list);
            if (elem != NULL) {
                con = elem->connection;
                if (elem->connection->local) {
                    printf("[for comp host, comp name, comp id: \"%s\", \"%s\", \"%ld\"]    \n",con->local->comp_host, con->local->comp_name , con->local->comp_id);
                }
            } else {
                printf("     \n");
            }
            cl_raw_list_unlock(handle->connection_list);


            start_time =    now.tv_sec;
            total_bytes_sent = 0;
            total_bytes_received = 0;
            total_connections = 0;
            fflush(stdout);
        }
        if (close_connection != 0) {

            while (cl_commlib_shutdown_handle(handle, CL_TRUE) == CL_RETVAL_MESSAGE_IN_BUFFER) {
                printf("got message\n");
                message = NULL;
                cl_commlib_receive_message(handle,NULL, NULL, 0, CL_FALSE, 0, &message, &sender);
                if (message != NULL) {
                    cl_com_free_endpoint(&sender);
                    cl_com_free_message(&message);
                } else {
                    printf("error shutdown handle");
                    exit(-1);
                    break;
                }
            }
#ifdef CREATE_SERVICE
            handle=cl_com_create_handle(NULL,framework,CL_CM_CT_MESSAGE , CL_TRUE, 0 , CL_TCP_DEFAULT, "client", atoi(argv[3]),SELECT_TIMEOUT,0 );
            if (handle == NULL) {
                printf("could not get handle\n");
                exit(-1);
            } else {
                int my_port;
                cl_com_get_service_port(handle,&my_port);
                printf("I'm reachable at port %d!\n", my_port);
            }
#else
            handle=cl_com_create_handle(NULL,framework,CL_CM_CT_MESSAGE , CL_FALSE, atoi(argv[2]) , CL_TCP_DEFAULT, "client", atoi(argv[3]), SELECT_TIMEOUT,0 );
            if (handle == NULL) {
                printf("could not get handle\n");
                exit(-1);
            }
#endif
            cl_com_set_auto_close_mode(handle,CL_CM_AC_ENABLED );
            cl_com_get_auto_close_mode(handle,&autoclose);
            if (autoclose != CL_CM_AC_ENABLED ) {
                printf("could not enable autoclose\n");
                exit(1);
            }
        }
        if (runs == 0) {
            do_shutdown = 1;
        }
    }
    printf("do_shutdown received\n");
    fflush(stdout);
    while (cl_commlib_shutdown_handle(handle, CL_TRUE) == CL_RETVAL_MESSAGE_IN_BUFFER) {
        printf("got message\n");
        message = NULL;

        cl_commlib_receive_message(handle,NULL, NULL, 0, CL_FALSE, 0, &message, &sender);
        if (message != NULL) {
            cl_com_free_endpoint(&sender);
            cl_com_free_message(&message);
        } else {
            break;
        }
    }
    printf("cleanup commlib ...\n");
    cl_com_cleanup_commlib();

    printf("main done\n");
    fflush(stdout);
    return 0;
}