int
main()
{
    gss_cred_id_t                       credential;
    int                                 listen_fd;
    int                                 accept_fd;
    struct sockaddr_in                  address = {0};
    globus_sockaddr_t                   connect_address;
    globus_socklen_t                    connect_address_len = sizeof(connect_address);
    struct thread_arg *                 arg = NULL;
    globus_thread_t                     thread_handle;
    int                                 i;
    int                                 ret;
    int                                 error;

    LTDL_SET_PRELOADED_SYMBOLS();

    globus_thread_set_model(THREAD_MODEL);

    globus_module_activate(GLOBUS_COMMON_MODULE);
    globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);

    printf("1..%d\n", NUM_CLIENTS);
    /* initialize global mutex */
    globus_mutex_init(&mutex, NULL);

    /* and the condition variable */

    globus_cond_init(&done, NULL);
    
    /* setup listener */
    address.sin_family = AF_INET;
    address.sin_port = 0;
    address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd == 0)
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    ret = bind(listen_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_in));
    if (ret != 0)
    {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    ret = getsockname(listen_fd, (struct sockaddr *) &connect_address, &connect_address_len);
    if (ret != 0)
    {
        perror("getsockname");
        exit(EXIT_FAILURE);
    }

    ret = listen(listen_fd, -1);
    if (ret != 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    /* acquire credentials */
    credential = globus_gsi_gssapi_test_acquire_credential();

    if(credential == GSS_C_NO_CREDENTIAL)
    {
	fprintf(stderr,"Unable to aquire credential\n");
	exit(-1);
    }

    /* start the clients here */
    for(i=0;i<NUM_CLIENTS;i++)
    {
	arg = malloc(sizeof(struct thread_arg));

	arg->address = &connect_address;
	arg->len = connect_address_len;

	arg->credential = credential;
	
        globus_mutex_lock(&mutex);
        {
            client_thread_count++;
        }
        globus_mutex_unlock(&mutex);

	globus_thread_create(&thread_handle,NULL,client_func,(void *) arg);
    }
    
    /* accept connections */

    globus_mutex_lock(&mutex);
    while (client_thread_count > 0)
    {
        while (pending_connects > 0)
	{
            accept_fd = accept(listen_fd,NULL,0);

            if(accept_fd < 0)
            {
                perror("accept");
                abort();
            }
	
            arg = malloc(sizeof(struct thread_arg));

            arg->fd = accept_fd;
            arg->credential = credential;

            server_thread_count++;
            pending_connects--;
            globus_thread_create(&thread_handle,NULL,server_func,(void *) arg);
        }
        globus_cond_wait(&done, &mutex);
    }

    /* wait for last thread to terminate */
    while (server_thread_count > 0)
    {
        globus_cond_wait(&done, &mutex);
    }
    globus_mutex_unlock(&mutex);


    /* destroy global mutex */

    globus_mutex_destroy(&mutex);

    /* and the condition variable */

    globus_cond_destroy(&done);
    
    /* close the listener */

    close(listen_fd);
    
    /* release credentials */

    globus_gsi_gssapi_test_release_credential(&credential); 

    globus_module_deactivate_all();

    exit(client_failed);
}
int
main()
{
    gss_cred_id_t                       credential;
    int                                 listen_fd;
    int                                 accept_fd;
    struct sockaddr_un *                address;
    struct context_arg *                arg = NULL;
    pid_t                               pid;

    /* ToDo: Make this run on windows */
#   ifdef WIN32
    printf("This Test Doesn't Run On Windows Yet\n");
    exit(0);
#   endif

    /* module activation */

    globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);
    globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);
    globus_module_activate(GLOBUS_COMMON_MODULE);
    
    /* setup listener */

    address = malloc(sizeof(struct sockaddr_un));

    memset(address,0,sizeof(struct sockaddr_un));

    address->sun_family = PF_UNIX;

    tmpnam(address->sun_path);
    
    listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);

    bind(listen_fd, (struct sockaddr *) address, sizeof(struct sockaddr_un));

    listen(listen_fd,1);

    /* acquire credentials */

    credential = globus_gsi_gssapi_test_acquire_credential();

    if(credential == GSS_C_NO_CREDENTIAL)
    {
        fprintf(stderr,"Unable to aquire credential\n");
        exit(-1);
    }

    pid = fork();

    if(pid == 0)
    {
        /* child */
     	arg = malloc(sizeof(struct context_arg));
        
	arg->address = address;
        
	arg->credential = credential;

        client_func(arg);
    }
    else
    {
        accept_fd = accept(listen_fd,NULL,0);
        
	if(accept_fd < 0)
	{
	    abort();
	}
	
	arg = malloc(sizeof(struct context_arg));
        
	arg->fd = accept_fd;
        
	arg->credential = credential;

        server_func(arg);
    }

    /* close the listener */

    close(listen_fd);
    
    /* release credentials */
    
    globus_gsi_gssapi_test_release_credential(&credential); 
    
    /* free address */
    
    free(address);
    
    globus_module_deactivate(GLOBUS_COMMON_MODULE);
    globus_module_deactivate(GLOBUS_GSI_GSSAPI_MODULE);
    globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE);

    exit(0);
}