globus_result_t
globus_i_gsi_cred_error_join_chains_result(
    globus_result_t                     outter_error,
    globus_result_t                     inner_error)
{
    globus_result_t                     result;
    globus_object_t *                   result_error_obj = NULL;
    globus_object_t *                   outter_error_obj = NULL;
    globus_object_t *                   inner_error_obj = NULL;
    globus_object_t *                   temp_error_obj = NULL;
    static char *                       _function_name_ =
        "globus_i_gsi_cred_error_join_chains";
    GLOBUS_I_GSI_CRED_DEBUG_ENTER;

    outter_error_obj = globus_error_get(outter_error);
    inner_error_obj = globus_error_get(inner_error);
    if(outter_error_obj && inner_error_obj)
    {
        temp_error_obj = outter_error_obj;
        while(globus_error_get_cause(temp_error_obj))
        {
            temp_error_obj = globus_error_get_cause(temp_error_obj);
        }

        temp_error_obj = globus_error_initialize_base(temp_error_obj,
                                                      globus_error_get_source(temp_error_obj),
                                                      inner_error_obj);
        result_error_obj = outter_error_obj;
    }
    else if(inner_error_obj)
    {
        result_error_obj = inner_error_obj;
    }
    else
    {
        result_error_obj = 
            globus_error_construct_error(
                GLOBUS_GSI_CREDENTIAL_MODULE,
                NULL,
                GLOBUS_GSI_CRED_ERROR_CREATING_ERROR_OBJ,
                __FILE__,
                _function_name_,
                __LINE__,
                "Couldn't join inner and outer error chains");
    }

    result = globus_error_put(result_error_obj);

    GLOBUS_I_GSI_CRED_DEBUG_EXIT;
    return result;
}
void
test2_writev_callback(
    void *				callback_arg,
    globus_io_handle_t *		handle,
    globus_result_t			result,
    struct iovec *			iov,
    globus_size_t			iovcnt,
    globus_size_t			nbytes)
{
    globus_object_t *			err = GLOBUS_NULL;
    test_monitor_t *			monitor;
    
    monitor = (test_monitor_t *) callback_arg;
    
    if(result != GLOBUS_SUCCESS)
    {
	err = globus_error_get(result);
    }

    globus_mutex_lock(&monitor->mutex);

    if(result != GLOBUS_SUCCESS &&
       !globus_io_eof(err))
    {
	monitor->use_err = GLOBUS_TRUE;
	monitor->err = err;
    }
    
    monitor->done = GLOBUS_TRUE;

    globus_cond_signal(&monitor->cond);
    globus_mutex_unlock(&monitor->mutex);    
    
    return;
}
void
test1_read_callback(
    void *				callback_arg,
    globus_io_handle_t *		handle,
    globus_result_t			result,
    globus_byte_t *			buf,
    globus_size_t			nbytes)
{
    globus_object_t *			err;
    test_monitor_t *			monitor;
    
    monitor = (test_monitor_t *) callback_arg;
    
    if(result != GLOBUS_SUCCESS)
    {
	err = globus_error_get(result);
    }

    globus_mutex_lock(&monitor->mutex);

    if(result != GLOBUS_SUCCESS &&
       !globus_io_eof(err))
    {
	monitor->use_err = GLOBUS_TRUE;
	monitor->err = err;
    }
    buf[nbytes >= test_buffer_size ? test_buffer_size-1 : nbytes] = '\0';
    
    monitor->done = GLOBUS_TRUE;

    globus_cond_signal(&monitor->cond);
    globus_mutex_unlock(&monitor->mutex);    
    
    return;
}
void
test1_connect_callback(
    void *				callback_arg,
    globus_io_handle_t *		handle,
    globus_result_t			result)
{
    globus_object_t *			err;
    test_monitor_t *			monitor;
    
    monitor = (test_monitor_t *) callback_arg;
    
    if(result != GLOBUS_SUCCESS)
    {
	err = globus_error_get(result);
    }

    globus_mutex_lock(&monitor->mutex);

    if(result != GLOBUS_SUCCESS)
    {
	monitor->use_err = GLOBUS_TRUE;
	monitor->err = err;
    }
    
    monitor->done = GLOBUS_TRUE;

    globus_cond_signal(&monitor->cond);
    globus_mutex_unlock(&monitor->mutex);    
    
    return;
}
/**
 * This function destroys a globus_gsi_callback_data_t.
 * @ingroup globus_gsi_callback_data
 *
 * @param callback_data
 *        The structure to be destroyed
 *
 * @return
 *        GLOBUS_SUCCESS unless an error occurred, in which case, 
 *        a globus error object ID is returned
 */
globus_result_t
globus_gsi_callback_data_destroy(
    globus_gsi_callback_data_t          callback_data)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    static char *                       _function_name_ =
        "globus_gsi_callback_data_destroy";

    GLOBUS_I_GSI_CALLBACK_DEBUG_ENTER;

    if(!callback_data)
    {
        goto exit;
    }

    if(callback_data->cert_chain)
    { 
        sk_X509_pop_free(callback_data->cert_chain, X509_free); 
    } 
    
    if(callback_data->cert_dir)
    {
        globus_libc_free(callback_data->cert_dir);
    }

    /* extension_oids have to be free independantly */

    globus_object_free(globus_error_get(callback_data->error));

    globus_libc_free(callback_data);

 exit:
    GLOBUS_I_GSI_CALLBACK_DEBUG_EXIT;
    return result;
}   
static
void
gfork_l_child_error(
    gfork_i_lib_handle_t *              handle,
    globus_result_t                     in_result)
{
    globus_result_t                     result;

    switch(handle->state)
    {
    /* we are already doing it */
    case GFORK_STATE_CLOSING:
        break;

    case GFORK_STATE_OPEN:
        handle->error_obj = globus_error_get(in_result);
        result = globus_xio_register_close(
                     handle->write_xio, NULL,
                     gfork_l_child_write_close_cb, handle);
        if(result != GLOBUS_SUCCESS)
        {
            /* wtf ? */
        }
        handle->state = GFORK_STATE_CLOSING;

        break;

    default:
        globus_assert(0 && "Invalid state");
    }
}
/**
 * Initialize a previously allocated error of type
 * GLOBUS_ERROR_TYPE_GSSAPI
 * @ingroup globus_gssapi_error_object 
 *
 * @param error
 *        The previously allocated error object.
 * @param base_source
 *        Pointer to the originating module.
 * @param base_cause
 *        The error object causing the error. If this is the original
 *        error this paramater may be NULL.
 * @param major_status
 *        The GSSAPI major status
 * @param minor_status
 *        The GSSAPI minor status
 * @return
 *        The resulting error object. You may have to call
 *        globus_error_put() on this object before passing it on.
 */
globus_object_t *
globus_error_initialize_gssapi_error(
    globus_object_t *                   error,
    globus_module_descriptor_t *        base_source,
    globus_object_t *                   base_cause,
    const OM_uint32                     major_status,
    const OM_uint32                     minor_status)
{
    globus_l_gssapi_error_data_t *      instance_data;
    globus_object_t *                   minor_obj;
    gss_OID_set                         actual_mechs;
    OM_uint32                           local_minor_status;
    extern gss_OID                      gss_mech_globus_gssapi_openssl;
    
    instance_data = (globus_l_gssapi_error_data_t *)
        malloc(sizeof(globus_l_gssapi_error_data_t));

    instance_data->major_status = major_status;
    instance_data->minor_status = minor_status;
    instance_data->is_globus_gsi = GLOBUS_FALSE;
    
    if(gss_indicate_mechs(
        &local_minor_status, &actual_mechs) == GSS_S_COMPLETE)
    {
        int                             boolean;
        
        if(gss_test_oid_set_member(
            &local_minor_status,
            gss_mech_globus_gssapi_openssl,
            actual_mechs,
            &boolean) == GSS_S_COMPLETE && boolean)
        {
            instance_data->is_globus_gsi = GLOBUS_TRUE;
        }
        
        gss_release_oid_set(&local_minor_status, &actual_mechs);
    }
    
    if(instance_data->is_globus_gsi)
    {
        minor_obj = globus_error_get((globus_result_t) minor_status);
        if(!base_cause)
        {
            base_cause = minor_obj;
        }
        else if(minor_obj)
        {
            base_cause = globus_error_initialize_base(
                minor_obj, globus_error_get_source(base_cause), base_cause);
        }
    }
        
    globus_object_set_local_instance_data(error, instance_data);
    
    return globus_error_initialize_base(error, base_source, base_cause);
}/* globus_error_initialize_gssapi_error() */
/*
 * Check if this user is OK to login under GSI. User has been authenticated
 * as identity in global 'client_name.value' and is trying to log in as passed
 * username in 'name'.
 *
 * Returns non-zero if user is authorized, 0 otherwise.
 */
static int
ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name)
{
    int authorized = 0;
    globus_result_t res;
#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
    char lname[256] = "";
#endif

#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
        return 0;
    }
#endif

    /* use new globus_gss_assist_map_and_authorize() interface if available */
#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
    debug("calling globus_gss_assist_map_and_authorize()");
    if (GLOBUS_SUCCESS !=
            (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
                    name, lname, 256))) {
        debug("%s", globus_error_print_chain(globus_error_get(res)));
    } else if (lname[0] && strcmp(name, lname) != 0) {
        debug("GSI user maps to %s, not %s", lname, name);
    } else {
        authorized = 1;
    }
#else
    debug("calling globus_gss_assist_userok()");
    if (GLOBUS_SUCCESS !=
            (res = (globus_gss_assist_userok(client->displayname.value,
                    name)))) {
        debug("%s", globus_error_print_chain(globus_error_get(res)));
    } else {
        authorized = 1;
    }
#endif

    logit("GSI user %s is%s authorized as target user %s",
          (char *) client->displayname.value, (authorized ? "" : " not"), name);

    return authorized;
}
void mdsip_test_result(globus_xio_handle_t xio_handle,globus_result_t res,mdsip_client_t *ctx,char *msg)
{
  if(res != GLOBUS_SUCCESS)
  {
    fprintf(stderr, "ERROR:%s ---\n       %s\n", 
	    msg,globus_object_printable_to_string(globus_error_get(res)));
    if (xio_handle != NULL)
      globus_xio_register_close(xio_handle,NULL,mdsip_close_cb,ctx);
  }

}
void globus_err_handler(const char *routine, const char *caller,
			globus_result_t result)
{
  int myrank,nprocs;
  globus_object_t *err;

  MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
  MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
  err = globus_error_get(result);
  FPRINTF(stderr, "[%d/%d] %s error \"%s\", called from %s\n",
	  myrank,nprocs,routine,globus_object_printable_to_string(err),caller);
}
void globus_print_error(
    globus_result_t                     error_result)
{
    globus_object_t *                   error_obj = NULL;
    char *                              error_string = NULL;
    
    error_obj = globus_error_get(error_result);
    error_string = globus_error_print_chain(error_obj);
    globus_libc_fprintf(stderr, "%s\n", error_string);
    globus_libc_free(error_string);
    globus_object_free(error_obj);
}
/*
 * Return the local username associated with the GSI credentials.
 */
int
ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user)
{
    globus_result_t res;
#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
    char lname[256] = "";
#endif

#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
        return 0;
    }
#endif

    /* use new globus_gss_assist_map_and_authorize() interface if available */
#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
    debug("calling globus_gss_assist_map_and_authorize()");
    if (GLOBUS_SUCCESS !=
            (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
                    NULL, lname, 256))) {
        debug("%s", globus_error_print_chain(globus_error_get(res)));
        logit("failed to map GSI user %s", (char *)client->displayname.value);
        return 0;
    }
    *user = strdup(lname);
#else
    debug("calling globus_gss_assist_gridmap()");
    if (GLOBUS_SUCCESS !=
            (res = globus_gss_assist_gridmap(client->displayname.value, user))) {
        debug("%s", globus_error_print_chain(globus_error_get(res)));
        logit("failed to map GSI user %s", (char *)client->displayname.value);
        return 0;
    }
#endif

    logit("GSI user %s mapped to target user %s",
          (char *) client->displayname.value, *user);

    return 1;
}
void
test_res(
    globus_result_t                         res)
{
    if(res == GLOBUS_SUCCESS)
    {
        return;
    }

    fprintf(stderr, "ERROR: %s\n", globus_object_printable_to_string(
        globus_error_get(res)));

    globus_assert(0);
}
void
test_res(
    globus_result_t                         res,
    int                                     line)
{
    if(res == GLOBUS_SUCCESS)
    {
        return;
    }

    fprintf(stderr, "ERROR @ %d: %s\n", line, globus_error_print_chain(
        globus_error_get(res)));

    globus_assert(0);
}
globus_result_t
globus_i_gsi_gssapi_error_chain_result(
    globus_result_t                     chain_result,
    int                                 error_type,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_result_t                     result;
    globus_object_t *                   error_object;
    
    static char *                       _function_name_ =
        "globus_i_gsi_gssapi_error_chain_result";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    error_object = 
        globus_error_construct_error(
            GLOBUS_GSI_GSSAPI_MODULE,
            globus_error_get(chain_result),
            error_type,
            filename,
            function_name,
            line_number, 
            "%s%s%s",
            (error_type < 0 || error_type >= GLOBUS_GSI_GSSAPI_ERROR_LAST)
                ? _GGSL("Unknown error")
                : _GGSL(globus_l_gsi_gssapi_error_strings[error_type]),
            short_desc ? ": " : "",
            short_desc ? short_desc : "");
        
    if(long_desc)
    {    
        globus_error_set_long_desc(error_object, long_desc);
    }

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_GSSAPI_INTERNAL_DEBUG_EXIT;
    return result;
}
globus_result_t
globus_i_gsi_cert_utils_error_chain_result(
    globus_result_t                     chain_result,
    int                                 error_type,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_object_t *                   error_object;
    globus_result_t                     result;

    static char *                       _function_name_ =
        "globus_i_gsi_cert_utilsential_error_chain_result";
    
    GLOBUS_I_GSI_CERT_UTILS_DEBUG_ENTER;
    
    error_object =
        globus_error_construct_error(
            GLOBUS_GSI_CERT_UTILS_MODULE,
            globus_error_get(chain_result),
            error_type,
            filename,
            function_name,
            line_number, 
            "%s%s%s",
            _CUSL(globus_l_gsi_cert_utils_error_strings[error_type]),
            short_desc ? ": " : "",
            short_desc ? short_desc : "");

    if(long_desc)
    {
        globus_error_set_long_desc(error_object, long_desc);
    }

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_CERT_UTILS_DEBUG_EXIT;

    return result;
}
static
void
globus_l_io_authorization_test_connect_callback(
	void *				arg,
	globus_io_handle_t *		handle,
	globus_result_t			result)
{
    globus_l_io_authorization_test_monitor_t *
					monitor;

    monitor = (globus_l_io_authorization_test_monitor_t *) arg;
    if(result != GLOBUS_SUCCESS)
    { 
        printf("# %s\n", globus_object_printable_to_string(
                   globus_error_get(result)));
        exit(1);
    }
    globus_mutex_lock(&monitor->mutex);
    monitor->connected = GLOBUS_TRUE;
    globus_cond_signal(&monitor->cond);
    globus_mutex_unlock(&monitor->mutex);
}
static
void
globus_l_xio_win32_blocking_cb(
    globus_result_t                     result,
    globus_size_t                       nbytes,
    void *                              user_arg)
{
    globus_l_xio_win32_blocking_info_t * blocking_info;
    GlobusXIOName(globus_l_xio_win32_blocking_cb);
    
    GlobusXIOSystemDebugEnter();
    
    blocking_info = (globus_l_xio_win32_blocking_info_t *) user_arg;
    if(result != GLOBUS_SUCCESS)
    {
        blocking_info->error = globus_error_get(result);
    }
    blocking_info->nbytes = nbytes;
    SetEvent(blocking_info->event);
    
    GlobusXIOSystemDebugExit();
}
/*
 * called locked
 */
static
void
gfs_l_xio_cp_error(
    gfs_i_xio_cp_handle_t *             cp_h,
    globus_result_t                     result)
{
    globus_xio_handle_t                 xio_h;

    /* call this for shutdown in error cases, but some error cases will
        be a result of closing. */
    if(cp_h->state != GFS_CIO_CP_STATE_OPEN)
    {
        return;
    }

    cp_h->state = GFS_CIO_CP_STATE_ERROR;
    cp_h->err_obj = globus_error_get(result);

    while(!globus_fifo_empty(cp_h->read_all_q))
    {
        xio_h = (globus_xio_handle_t) globus_fifo_dequeue(cp_h->read_all_q);

        result = globus_xio_register_close(
            xio_h,
            NULL,
            gfs_l_xio_cp_read_close_cb,
            cp_h);
        if(result != GLOBUS_SUCCESS)
        {
            cp_h->read_handle_count--;
        }
    }

    if(cp_h->read_handle_count <= 0)
    {
        gfs_l_xio_close_write_handles(cp_h);
    }
}
int main(int argc,
	 char *argv[])
{
    globus_ftp_client_handle_t			handle;
    globus_ftp_client_operationattr_t		attr;
    globus_byte_t *				buffer;
    globus_size_t				buffer_length;
    globus_result_t				result;
    char *					src;
    char *					dst;
    globus_ftp_client_handleattr_t		handle_attr;
    globus_ftp_control_mode_t			mode;
    int						i;
    globus_ftp_control_parallelism_t		parallelism;

    globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    globus_ftp_client_handleattr_init(&handle_attr);
    globus_ftp_client_operationattr_init(&attr);

    parallelism.mode = GLOBUS_FTP_CONTROL_PARALLELISM_FIXED;
    parallelism.fixed.size = 1;
    
    mode = GLOBUS_FTP_CONTROL_MODE_STREAM;

    for(i = 1; i < argc; i++)
    {
	if(strcmp(argv[i], "-P") == 0 && i + 1 < argc)
	{
	    mode = GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK;

	    parallelism.mode = GLOBUS_FTP_CONTROL_PARALLELISM_FIXED;
	    parallelism.fixed.size = atoi(argv[i+1]);

	    test_remove_arg(&argc, argv, &i, 1);
	}
    }
    test_parse_args(argc, 
		    argv,
		    &handle_attr,
		    &attr,
		    &src,
		    &dst);

    buffer = globus_libc_malloc(SIZE);
    buffer_length = SIZE;
    
    globus_mutex_init(&lock, GLOBUS_NULL);
    globus_cond_init(&cond, GLOBUS_NULL);

    globus_ftp_client_operationattr_set_mode(&attr,
				             mode);
    globus_ftp_client_operationattr_set_parallelism(&attr,
					            &parallelism);
    globus_ftp_client_operationattr_set_read_all(&attr,
					         GLOBUS_TRUE,
					         intermediate_cb,
					         GLOBUS_NULL);
    globus_ftp_client_handle_init(&handle, &handle_attr);

    done = GLOBUS_FALSE;
    result = globus_ftp_client_get(&handle,
				   src,
				   &attr,
				   GLOBUS_NULL,
				   done_cb,
				   0);
    if(result != GLOBUS_SUCCESS)
    {
	fprintf(stderr, globus_object_printable_to_string(globus_error_get(result)));
	error = GLOBUS_TRUE;
	done = GLOBUS_TRUE;
    }
    else
    {
	globus_ftp_client_register_read(
	    &handle,
	    buffer,
	    buffer_length,
	    data_cb,
	    0);
    }
    globus_mutex_lock(&lock);
    while(!done)
    {
	globus_cond_wait(&cond, &lock);
    }
    globus_mutex_unlock(&lock);

    globus_ftp_client_handle_destroy(&handle);
    globus_libc_free(buffer);
    
    globus_module_deactivate_all();

    if(test_abort_count && error)
    {
	return 0;
    }
    return error;
}
/*
 * Function:    main
 *
 * Description: 
 *              
 * Parameters:  
 *
 * Returns:     
 */
int
main(int argc, char **argv)
{
    int                                 rc;
    globus_result_t                     result;
    globus_object_t *                   error = NULL;
    char *                              errstring;
    globus_io_handle_t                  handle;
    globus_io_handle_t                  stdout_handle;
    globus_size_t                       bytes;
    globus_size_t                       i;
    globus_byte_t                       buf[1024];
#ifdef TARGET_ARCH_WIN32
	HANDLE						outputFile;
    globus_io_handle_t			write_handle;

	if ( argc < 3 )
	{
		usage( argv[0] );
		return -1;
	}
#endif

    globus_module_activate(GLOBUS_COMMON_MODULE);
    globus_module_activate(GLOBUS_IO_MODULE);

#ifndef TARGET_ARCH_WIN32
    result = globus_io_file_open("/etc/group",
				 O_RDONLY,
				 0600,
				 GLOBUS_NULL,
				 &handle);
#else
    result = globus_io_file_open( argv[1],
				 O_RDONLY,
				 0600,
				 GLOBUS_NULL,
				 &handle);
#endif

    if(result != GLOBUS_SUCCESS)
    {
        error = globus_error_get(result);
        errstring = globus_object_printable_to_string(error);
#ifndef TARGET_ARCH_WIN32
        globus_libc_printf("test failed to open /etc/group: %s\n", errstring);
#else
        globus_libc_printf("test failed to open %s: %s\n", argv[1], errstring);
#endif
        goto done;
    }
    
#ifndef TARGET_ARCH_WIN32
    result = globus_io_file_posix_convert(
        fileno(stdout),
        GLOBUS_NULL,
        &stdout_handle);
#else
	outputFile= CreateFile( argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
	 FILE_FLAG_OVERLAPPED, NULL );
	if ( outputFile == INVALID_HANDLE_VALUE )
	{
		printf( "An error occurred while trying to create the output file (error is %d)...exiting\n",
		 GetLastError() );
		return -1;
	}
    result= globus_io_file_windows_convert(
		outputFile,
		GLOBUS_NULL,
		&write_handle);
#endif
    if(result != GLOBUS_SUCCESS)
    {
        error = globus_error_get(result);
        errstring = globus_object_printable_to_string(error);
        globus_libc_printf("test failed to convert stdout to io handle: %s\n",
                           errstring);
        goto done;
    }

    do
    {
        result = globus_io_read(&handle,
                                buf,
                                sizeof(buf),
                                sizeof(buf),
                                &bytes);
        if(result == GLOBUS_SUCCESS ||
           ((error = globus_error_get(result)) &&
            (globus_object_type_match(globus_object_get_type(error),
                                      GLOBUS_IO_ERROR_TYPE_EOF))))
        {
            globus_size_t           nbytes2;
            
#ifndef TARGET_ARCH_WIN32
	globus_io_write(&stdout_handle,
			buf,
			bytes,
			&nbytes2);
#else
		globus_io_write( &write_handle,
				buf,
				bytes,
				&nbytes2);
#endif
        }
        else
        {
            errstring = globus_object_printable_to_string(error);
            globus_libc_printf("test failed to read /etc/group: %s\n",
                               errstring);
            goto done;

        }
    }
    while(result == GLOBUS_SUCCESS);

 done:

    if(error)
    {
        globus_object_free(error);
    }
    
    globus_io_close(&handle);
#ifndef TARGET_ARCH_WIN32
    globus_io_close(&stdout_handle);
#else
    globus_io_close( &write_handle);
#endif

    globus_module_deactivate(GLOBUS_IO_MODULE);
    globus_module_deactivate(GLOBUS_COMMON_MODULE);

    return 0;
}
int main()
{
    OM_uint32                           init_maj_stat;
    OM_uint32                           accept_maj_stat;
    OM_uint32                           maj_stat;
    OM_uint32                           min_stat;
    OM_uint32                           ret_flags;
    OM_uint32                           req_flags = 0;
    OM_uint32                           time_rec;
    gss_buffer_desc                     send_tok;
    gss_buffer_desc                     recv_tok;
    gss_buffer_desc *                   token_ptr;
    gss_OID                             mech_type;
    gss_name_t                          target_name;
    gss_ctx_id_t                        init_context;
    gss_ctx_id_t                        accept_context;
    gss_ctx_id_t                        del_init_context;
    gss_ctx_id_t                        del_accept_context;
    gss_cred_id_t                       delegated_cred;
    gss_cred_id_t                       imported_cred;
    gss_cred_id_t                       cred_handle;
    char *                              error_str;
    globus_result_t                     result;
    globus_gsi_cert_utils_cert_type_t   cert_type;
    int                                 rc = EXIT_SUCCESS;

    printf("1..1\n");
    /* Activate Modules */
    globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);

    /* Initialize variables */
    
    token_ptr = GSS_C_NO_BUFFER;
    init_context = GSS_C_NO_CONTEXT;
    accept_context = GSS_C_NO_CONTEXT;
    del_init_context = GSS_C_NO_CONTEXT;
    del_accept_context = GSS_C_NO_CONTEXT;
    delegated_cred = GSS_C_NO_CREDENTIAL;
    accept_maj_stat = GSS_S_CONTINUE_NEEDED;
    ret_flags = 0;
    req_flags |= GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG;


    /* acquire the credential */

    maj_stat = gss_acquire_cred(&min_stat,
                                NULL,
                                GSS_C_INDEFINITE,
                                GSS_C_NO_OID_SET,
                                GSS_C_BOTH,
                                &cred_handle,
                                NULL,
                                NULL);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    
    /* get the subject name */
    
    maj_stat = gss_inquire_cred(&min_stat, 
                                cred_handle,
                                &target_name,
                                NULL,
                                NULL,
                                NULL);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }


    /* set up the first security context */
    
    init_maj_stat = gss_init_sec_context(&min_stat,
                                         cred_handle,
                                         &init_context,
                                         target_name,
                                         GSS_C_NULL_OID,
                                         0,
                                         0,
                                         GSS_C_NO_CHANNEL_BINDINGS,
                                         token_ptr,
                                         NULL,
                                         &send_tok,
                                         NULL,
                                         NULL);


    if(init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    while(1)
    {
        
        accept_maj_stat=gss_accept_sec_context(&min_stat,
                                               &accept_context,
                                               GSS_C_NO_CREDENTIAL,
                                               &send_tok, 
                                               GSS_C_NO_CHANNEL_BINDINGS,
                                               NULL,
                                               &mech_type,
                                               &recv_tok,
                                               &ret_flags,
                                               /* ignore time_rec */
                                               NULL, 
                                               NULL);

        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }

        init_maj_stat = gss_init_sec_context(&min_stat,
                                             GSS_C_NO_CREDENTIAL,
                                             &init_context,
                                             target_name,
                                             GSS_C_NULL_OID,
                                             0,
                                             0,
                                             GSS_C_NO_CHANNEL_BINDINGS,
                                             &recv_tok,
                                             NULL,
                                             &send_tok,
                                             NULL,
                                             NULL);
        
        
        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }

    printf("# %s:%d: Successfully established initial security context\n",
           __FILE__,
           __LINE__);


    /* delegate our credential over the initial security context and
     * insert a restriction extension into the delegated credential.
     * This is a post GT 2.0 feature.
     */


    init_maj_stat = gss_init_delegation(&min_stat,
                                        init_context,
                                        cred_handle,
                                        GSS_C_NO_OID,
                                        GSS_C_NO_OID_SET,
                                        GSS_C_NO_BUFFER_SET,
                                        token_ptr,
                                        req_flags,
                                        0,
                                        &send_tok);
    

    if(init_maj_stat != GSS_S_COMPLETE &&
       init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    while(1)
    {
        accept_maj_stat=gss_accept_delegation(&min_stat,
                                              accept_context,
                                              GSS_C_NO_OID_SET,
                                              GSS_C_NO_BUFFER_SET,
                                              &send_tok,
                                              req_flags,
                                              0,
                                              &time_rec,
                                              &delegated_cred,
                                              &mech_type,
                                              &recv_tok);
        
        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }

        init_maj_stat = gss_init_delegation(&min_stat,
                                            init_context,
                                            cred_handle,
                                            GSS_C_NO_OID,
                                            GSS_C_NO_OID_SET,
                                            GSS_C_NO_BUFFER_SET,
                                            &recv_tok,
                                            req_flags,
                                            0,
                                            &send_tok);


        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }
    
    printf("# %s:%d: Successfully delegated credential\n",
           __FILE__,
           __LINE__);

    /* export and import the delegated credential */
    /* this can be done both to a buffer and to a file */
    /* New in GT 2.0 */

    maj_stat = gss_export_cred(&min_stat,
                               delegated_cred,
                               GSS_C_NO_OID,
                               0,
                               &send_tok);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    
    maj_stat = gss_import_cred(&min_stat,
                               &imported_cred,
                               GSS_C_NO_OID,
                               0,
                               &send_tok,
                               0,
                               &time_rec);


    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    printf("# %s:%d: Successfully exported/imported the delegated credential\n",
           __FILE__,
           __LINE__);

    /* set up another security context using the delegated credential */
    
    init_maj_stat = gss_init_sec_context(&min_stat,
                                         imported_cred,
                                         &del_init_context,
                                         target_name,
                                         GSS_C_NULL_OID,
                                         0,
                                         0,
                                         GSS_C_NO_CHANNEL_BINDINGS,
                                         token_ptr,
                                         NULL,
                                         &send_tok,
                                         NULL,
                                         NULL);


    if(init_maj_stat != GSS_S_COMPLETE &&
       init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }


    
    while(1)
    {
        accept_maj_stat=gss_accept_sec_context(&min_stat,
                                               &del_accept_context,
                                               imported_cred,
                                               &send_tok, 
                                               GSS_C_NO_CHANNEL_BINDINGS,
                                               NULL,
                                               &mech_type,
                                               &recv_tok,
                                               &ret_flags,
                                               /* ignore time_rec */
                                               NULL, 
                                               NULL);

        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }
        
        init_maj_stat = gss_init_sec_context(&min_stat,
                                             imported_cred,
                                             &del_init_context,
                                             target_name,
                                             GSS_C_NULL_OID,
                                             0,
                                             0,
                                             GSS_C_NO_CHANNEL_BINDINGS,
                                             &recv_tok,
                                             NULL,
                                             &send_tok,
                                             NULL,
                                             NULL);
        
        
        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }

    /* got sec context based on delegated cred now */
    printf("# %s:%d: Successfully established security context with delegated credential\n",
           __FILE__,
           __LINE__);

    /* Verify that the delegated credential is a limited proxy */
    result = globus_gsi_cred_get_cert_type(
        ((gss_cred_id_desc *)imported_cred)->cred_handle,
        &cert_type);
    if(result != GLOBUS_SUCCESS)
    {
        char *                          error_str;
        globus_object_t *               error_obj;

        error_obj = globus_error_get(result);
        error_str = globus_error_print_chain(error_obj);
        fprintf(stderr, "%s", error_str);
        globus_libc_free(error_str);
        globus_object_free(error_obj);
        rc = EXIT_FAILURE;
        goto fail;
    }

    if (! GLOBUS_GSI_CERT_UTILS_IS_LIMITED_PROXY(cert_type))
    {
        fprintf(stderr,
                "Invalid certificate type. Expected a limited proxy, got %d\n",
                (int) cert_type);
        rc = EXIT_FAILURE;
        goto fail;
    }

fail:
    printf("%s gssapi_limited_delegation_test\n",
            (rc==EXIT_SUCCESS) ? "ok" : "not ok");
    globus_module_deactivate_all();
    
    exit(rc);    
}
void
test2(void)
{
    globus_result_t			result;
    globus_object_t *			err;
    test_monitor_t 			monitor;
    globus_io_handle_t			handle;
    globus_size_t			bytes_read;
    char				buf[6];
    struct iovec			iov[6];

    test_monitor_initialize(&monitor, GLOBUS_NULL);
    
    /* simple connection to known services with read and write */
    result = globus_io_tcp_connect(
	"antares.mcs.anl.gov",
	25,
	GLOBUS_NULL,
	&handle);

    if(result != GLOBUS_SUCCESS)
    {
	globus_libc_printf("test 1 failed connecting\n");
	
	goto finish;
    }

    result = globus_io_read(&handle,
			    test_buffer,
			    test_buffer_size,
			    1,
			    &bytes_read);
    if(result != GLOBUS_SUCCESS)
    {
	globus_libc_printf("test 1 failed reading\n");
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 read message:\n%s\n",
			   test_buffer);
    }
    
    buf[0]='q';
    buf[1]='u';
    buf[2]='i';
    buf[3]='t';
    buf[4]='\r';
    buf[5]='\n';
    iov[0].iov_base=buf;
    iov[0].iov_len=1;
    iov[1].iov_base=buf+1;
    iov[1].iov_len=1;
    iov[2].iov_base=buf+2;
    iov[2].iov_len=1;
    iov[3].iov_base=buf+3;
    iov[3].iov_len=1;
    iov[4].iov_base=buf+4;
    iov[4].iov_len=1;
    iov[5].iov_base=buf+5;
    iov[5].iov_len=1;
    
    result = globus_io_register_writev(&handle,
				       iov,
				       6,
				       test2_writev_callback,
				       &monitor);
    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed writing\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 wrote message:\n%s\n",
			   test_buffer);
    }
    test_monitor_reset(&monitor);
    
    result = globus_io_register_read(&handle,
				     test_buffer,
				     test_buffer_size,
				     1,
				     test1_read_callback,
				     &monitor);
    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed reading\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 read message:\n%s\n",
			   test_buffer);
    }

    test_monitor_reset(&monitor);

    result = globus_io_close(&handle);
    if(result != GLOBUS_SUCCESS)
    {
	err = globus_error_get(result);
	
	globus_libc_printf("test 1 failed closing\n");
    }

    globus_libc_printf("test 1 successful\n");
    
  finish:
    test_monitor_destroy(&monitor);
}
void ADIOI_GRIDFTP_Open(ADIO_File fd, int *error_code)
{
    static char myname[]="ADIOI_GRIDFTP_Open";
    int myrank, nprocs, keyfound;
    char hintval[MPI_MAX_INFO_VAL+1];
    globus_ftp_client_handleattr_t hattr;
    globus_result_t result;

    MPI_Comm_size(fd->comm, &nprocs);
    MPI_Comm_rank(fd->comm, &myrank);

    /* activate Globus ftp client module -- can be called multiple times, so
       it's safest to call once per file/connection */
    globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    fd->fd_sys = num_gridftp_handles;
    /* No shared file pointers for now */
    fd->shared_fp_fname = NULL;
    *error_code = MPI_SUCCESS;

    /* Access modes here mean something very different here than they
       would on a "real" filesystem...  As a result, the amode and hint
       processing here is intermingled and a little weird because many
       of them have to do with the connection rather than the file itself.
       The thing that sucks about this is that read and write ops will
       have to check themselves if the file is being accessed rdonly, rdwr,
       or wronly.
       */
    result=globus_ftp_client_handleattr_init(&hattr);
    if ( result != GLOBUS_SUCCESS )
	{
	    

	    globus_err_handler("globus_ftp_client_handleattr_init",
			       myname,result);
	    fd->fd_sys = -1;
	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
		    myname, __LINE__, MPI_ERR_IO,
		    "**io",
		    "**io %s", globus_object_printable_to_string(globus_error_get(result)));
	    return;
	}
    result = globus_ftp_client_operationattr_init(&(oattr[fd->fd_sys]));
    if ( result != GLOBUS_SUCCESS )
	{
	    globus_err_handler("globus_ftp_client_operationattr_init",
			       myname,result);
	    fd->fd_sys = -1;
	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
		    myname, __LINE__, MPI_ERR_IO,
		    "**io",
		    "**io %s", globus_object_printable_to_string(globus_error_get(result)));
	    return;
	}


    /* Always use connection caching unless told otherwise */
    result=globus_ftp_client_handleattr_set_cache_all(&hattr,GLOBUS_TRUE);
    if ( result !=GLOBUS_SUCCESS )
	globus_err_handler("globus_ftp_client_handleattr_set_cache_all",myname,result);

    /* Assume that it's safe to cache a file if it's read-only */
    if ( (fd->access_mode&ADIO_RDONLY) &&
	 (result=globus_ftp_client_handleattr_add_cached_url(&hattr,fd->filename))!=GLOBUS_SUCCESS )
	globus_err_handler("globus_ftp_client_handleattr_add_cached_url",myname,result);

    /* Since we're (almost by definition) doing things that FTP S (stream)
       control mode can't handle, default to E (extended block) control mode
       for gsiftp:// URLs.  ftp:// URLs use standard stream control mode 
       by default.  This behavior can be overridden by the ftp_control_mode
       hint. */

    /*
    if ( !strncmp(fd->filename,"gsiftp:",7) && 
	 (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK))!=GLOBUS_SUCCESS )
	globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
    else if ( !strncmp(fd->filename,"ftp:",4) && 
	      (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_STREAM))!=GLOBUS_SUCCESS )
	globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
    */

    /* Set append mode if necessary */
    if ( (fd->access_mode&ADIO_APPEND) && 
	 ((result=globus_ftp_client_operationattr_set_append(&(oattr[fd->fd_sys]),GLOBUS_TRUE))!=GLOBUS_SUCCESS) )
	globus_err_handler("globus_ftp_client_operationattr_set_append",myname,result);

    /* Other hint and amode processing that would affect hattr and/or 
       oattr[] (eg. parallelism, striping, etc.) goes here */
    if ( fd->info!=MPI_INFO_NULL )
	{
	    ADIOI_Info_get(fd->info,"ftp_control_mode",MPI_MAX_INFO_VAL,hintval,&keyfound);
	    if ( keyfound )
		{
		    if ( ( !strcmp(hintval,"extended") || !strcmp(hintval,"extended_block") ) && 
			 (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK))!=GLOBUS_SUCCESS )
			globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
		    else if ( !strcmp(hintval,"block") && 
			      (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_BLOCK))!=GLOBUS_SUCCESS )
			globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
		    else if ( !strcmp(hintval,"compressed") && 
			      (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_COMPRESSED))!=GLOBUS_SUCCESS )
			globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
		    else if ( !strcmp(hintval,"stream") && 
			      (result=globus_ftp_client_operationattr_set_mode(&(oattr[fd->fd_sys]),GLOBUS_FTP_CONTROL_MODE_STREAM))!=GLOBUS_SUCCESS )
			globus_err_handler("globus_ftp_client_operationattr_set_mode",myname,result);
		}

	    ADIOI_Info_get(fd->info,"parallelism",MPI_MAX_INFO_VAL,hintval,&keyfound);
	    if ( keyfound )
		{
		    int nftpthreads;
		    
		    if ( sscanf(hintval,"%d",&nftpthreads)==1 )
			{
			    globus_ftp_control_parallelism_t parallelism;

			    parallelism.mode = GLOBUS_FTP_CONTROL_PARALLELISM_FIXED;
			    parallelism.fixed.size = nftpthreads;
			    if ( (result=globus_ftp_client_operationattr_set_parallelism(&(oattr[fd->fd_sys]),
											 &parallelism))!=GLOBUS_SUCCESS )
				globus_err_handler("globus_ftp_client_operationattr_set_parallelism",myname,result);
			}
		}

	    ADIOI_Info_get(fd->info,"striped_ftp",MPI_MAX_INFO_VAL,hintval,&keyfound);
	    if ( keyfound )
		{
		    /* if set to "true" or "enable", set up round-robin block layout */
		    if ( !strncmp("true",hintval,4) || !strncmp("TRUE",hintval,4) ||
			 !strncmp("enable",hintval,4) || !strncmp("ENABLE",hintval,4) )
			{
			    ADIOI_Info_get(fd->info,"striping_factor",MPI_MAX_INFO_VAL,hintval,&keyfound);
			    if ( keyfound )
				{
				    int striping_factor;

				    if ( sscanf(hintval,"%d",&striping_factor)==1 )
					{
					    globus_ftp_control_layout_t layout;

					    layout.mode = GLOBUS_FTP_CONTROL_STRIPING_BLOCKED_ROUND_ROBIN;
					    layout.round_robin.block_size = striping_factor;
					    if ( (result=globus_ftp_client_operationattr_set_layout(&(oattr[fd->fd_sys]),
												    &layout))!=GLOBUS_SUCCESS  )
						globus_err_handler("globus_ftp_client_operationattr_set_layout",
								   myname,result);
					}
				}
			}
		}

	    ADIOI_Info_get(fd->info,"tcp_buffer",MPI_MAX_INFO_VAL,hintval,&keyfound);
	    if ( keyfound )
		{
		    /* set tcp buffer size */
		    int buffer_size;
		    if ( sscanf(hintval,"%d",&buffer_size)==1 )
			{
			    globus_ftp_control_tcpbuffer_t tcpbuf;

			    tcpbuf.mode = GLOBUS_FTP_CONTROL_TCPBUFFER_FIXED;
			    tcpbuf.fixed.size = buffer_size;
			    if ( (result=globus_ftp_client_operationattr_set_tcp_buffer(&(oattr[fd->fd_sys]),
											&tcpbuf))!=GLOBUS_SUCCESS )
				globus_err_handler("globus_ftp_client_operationattr_set_tcp_buffer",myname,result);
			}
		}

	    ADIOI_Info_get(fd->info,"transfer_type",MPI_MAX_INFO_VAL,hintval,&keyfound);
	    if ( keyfound )
		{
		    globus_ftp_control_type_t filetype;
		    /* set transfer type (i.e. ASCII or binary) */
		    if ( !strcmp("ascii",hintval) || !strcmp("ASCII",hintval) )
			{
			    filetype=GLOBUS_FTP_CONTROL_TYPE_ASCII;
			}
		    else
			{
			    filetype=GLOBUS_FTP_CONTROL_TYPE_IMAGE;
			}
		    if ( (result=globus_ftp_client_operationattr_set_type(&(oattr[fd->fd_sys]),filetype))!=GLOBUS_SUCCESS )
			globus_err_handler("globus_ftp_client_operationattr_set_type",myname,result);
		}
	}
    else
	FPRINTF(stderr,"no MPI_Info object associated with %s\n",fd->filename);

    /* Create the ftp handle */
    result=globus_ftp_client_handle_init(&(gridftp_fh[fd->fd_sys]),&hattr);
    if ( result != GLOBUS_SUCCESS )
	{
	    globus_err_handler("globus_ftp_client_handle_init",myname,result);
	    fd->fd_sys = -1;
	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
		    myname, __LINE__, MPI_ERR_IO,
		    "**io",
		    "**io %s", globus_object_printable_to_string(globus_error_get(result)));
	    return;
	}

    /* Check for existence of the file */
    globus_mutex_init(&lock, GLOBUS_NULL);
    globus_cond_init(&cond, GLOBUS_NULL);
    file_exists=GLOBUS_FALSE;
    exists_done=GLOBUS_FALSE;
    if ( myrank==0 )
	{
	    if ( (result=globus_ftp_client_exists(&(gridftp_fh[fd->fd_sys]),
						  fd->filename,
						  &(oattr[fd->fd_sys]),
						  exists_cb,
						  GLOBUS_NULL))!=GLOBUS_SUCCESS )
		{
		    globus_err_handler("globus_ftp_client_exists",myname,result);
		    fd->fd_sys = -1; 
		    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				    myname, __LINE__, MPI_ERR_IO,
				    "**io", "**io %s", 
				    globus_object_printable_to_string(globus_error_get(result)));
		    return;
		}
	    /* wait till the callback completes */
	    globus_mutex_lock(&lock);
	    while ( exists_done!=GLOBUS_TRUE )
		globus_cond_wait(&cond,&lock);
	    globus_mutex_unlock(&lock);
	}
    MPI_Barrier(fd->comm);
    MPI_Bcast(&file_exists,1,MPI_INT,0,fd->comm);

    /* It turns out that this is handled by MPI_File_open() directly */
    if ( (file_exists!=GLOBUS_TRUE) && (fd->access_mode&ADIO_CREATE) &&
	 !(fd->access_mode&ADIO_EXCL) && !(fd->access_mode&ADIO_RDONLY) )
	{
	    if ( myrank==0 )
		{
		    /* if the file doesn't exist, write a single NULL to it */
		    globus_byte_t touchbuf=(globus_byte_t)'\0';
		    touch_ctl_done=GLOBUS_FALSE;
		    if ( (result=globus_ftp_client_put(&(gridftp_fh[fd->fd_sys]),
						       fd->filename,
						       &(oattr[fd->fd_sys]),
						       GLOBUS_NULL,
						       touch_ctl_cb,
						       GLOBUS_NULL))!=GLOBUS_SUCCESS )
			{
			    globus_err_handler("globus_ftp_client_put",myname,result);
			    fd->fd_sys = -1;
			    *error_code = MPIO_Err_create_code(MPI_SUCCESS, 
				MPIR_ERR_RECOVERABLE,
				myname, __LINE__, MPI_ERR_IO,
				"**io", "**io %s", 
				globus_object_printable_to_string(globus_error_get(result)));
			    return;
			}
		    result=globus_ftp_client_register_write(&(gridftp_fh[fd->fd_sys]),
				  (globus_byte_t *)&touchbuf, 0,
				  (globus_off_t)0, GLOBUS_TRUE,
				  touch_data_cb, GLOBUS_NULL);

		    if ( result != GLOBUS_SUCCESS )
			{
			    globus_err_handler("globus_ftp_client_register_write",myname,result);
			    *error_code = MPIO_Err_create_code(MPI_SUCCESS, 
				MPIR_ERR_RECOVERABLE,
				myname, __LINE__, MPI_ERR_IO,
				"**io", "**io %s", 
				globus_object_printable_to_string(globus_error_get(result)));
			    return;
			}
		    globus_mutex_lock(&lock);
		    while ( touch_ctl_done!=GLOBUS_TRUE )
			globus_cond_wait(&cond,&lock);
		    globus_mutex_unlock(&lock);
		}
	    MPI_Barrier(fd->comm);
	}
    else if ( (fd->access_mode&ADIO_EXCL) && (file_exists==GLOBUS_TRUE) )
	{
	    fd->fd_sys = -1;
	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
			    myname, __LINE__, MPI_ERR_IO, 
			    "**io", 0);
	    return;
	}
    else if ( (fd->access_mode&ADIO_RDONLY) && (file_exists!=GLOBUS_TRUE) )
	{
	    if ( myrank==0 )
		{
		    FPRINTF(stderr,"WARNING:  read-only file %s does not exist!\n",fd->filename);
		}
	}
    num_gridftp_handles++;
}
int
client_test(
    http_test_info_t *			info,
    int					timer)	
{
    int                                 rc = 0;
    globus_result_t                     result;
    int                                 header_cnt = 0;
    char                                content_length_buffer[64];
    globus_xio_http_header_t            headers[2];
    globus_xio_handle_t                 handle;
    int                                 i;
    size_t                              nbytes;
    globus_xio_data_descriptor_t        descriptor;
    int                                 status_code;
    char *                              reason_phrase;


    globus_utp_start_timer(timer);
    if (info->transfer_encoding != NULL)
    {
        headers[header_cnt].name = "Transfer-Encoding";
        headers[header_cnt].value = info->transfer_encoding;

        header_cnt++;

    }

    if ((info->version == GLOBUS_XIO_HTTP_VERSION_1_0) ||
            ((info->transfer_encoding != NULL)
                && strcmp(info->transfer_encoding, IDENTITY) == 0))
    {
        sprintf(content_length_buffer, "%lu", (unsigned long) info->size);

        headers[header_cnt].name = "Content-Length";
        headers[header_cnt].value = &content_length_buffer[0];

        header_cnt++;
    }

    handle = NULL;

    result = http_test_client_request(
	    &handle,
	    info->tcp_driver,
	    info->http_driver,
	    info->stack,
	    info->contact,
	    "%2fpost-test",
	    "POST",
	    info->version,
	    headers,
	    header_cnt);

    if (result != GLOBUS_SUCCESS)
    {
	fprintf(stderr, "Error making request: %s\n",
		globus_object_printable_to_string(
		globus_error_get(result)));
	rc = 50;
	goto error_exit;
    }

    for (i = 0; i < info->iterations; i++)
    {
	result = globus_xio_write(
		handle,
		info->buffer,
		info->size,
		info->size,
		&nbytes,
		NULL);

	if (result == GLOBUS_SUCCESS)
	{
	    if (nbytes != info->size)
	    {
		fprintf(stderr, "Didn't write all I expected.\n");
	    }
	}
	else
	{
	    fprintf(stderr, "Error writing data: %s\n",
		globus_object_printable_to_string(globus_error_peek(result)));
	}
    }
    globus_xio_handle_cntl(
	    handle,
	    info->http_driver,
	    GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY);
    /* READ RESPONSE */
    result = globus_xio_data_descriptor_init(&descriptor, handle);
    if (result != GLOBUS_SUCCESS)
    {
	rc = 51;

        goto close_exit;
    }
    result = globus_xio_read(
            handle,
            info->buffer,
            0,
            0,
            NULL,
            descriptor);
    if (result != GLOBUS_SUCCESS)
    {
        rc = 51;
        goto close_exit;
    }

    result = globus_xio_data_descriptor_cntl(
            descriptor,
            info->http_driver,
            GLOBUS_XIO_HTTP_GET_RESPONSE,
            &status_code,
            &reason_phrase,
            NULL,
            NULL);
    if (result != GLOBUS_SUCCESS || status_code < 200 || status_code > 299)
    {
        fprintf(stderr, "Get failed with \"%03d %s\"\n",
                status_code,
                reason_phrase);

        rc = 51;
        goto close_exit;
    }

    result = globus_xio_read(
            handle,
            info->buffer,
            info->size,
            1,
            &nbytes,
            NULL);
    if (result && !http_is_eof(result))
    {       
        fprintf(stderr, "Error reading eof from http: %s\n",
                globus_error_print_friendly(globus_error_get(result)));
    }

close_exit:
    globus_xio_close(handle, NULL);
    globus_utp_stop_timer(timer);

error_exit:

    return rc;
}
static
void
globus_l_xio_test_server_request_callback(
    void *                              user_arg,
    globus_result_t                     result,
    const char *                        method,
    const char *                        uri,
    globus_xio_http_version_t           http_version,
    globus_hashtable_t                  headers)
{
    http_test_server_t *                test_server;
    http_test_info_t *			info;
    globus_xio_http_header_t            response_headers[2];
    globus_size_t                       header_cnt=0;
    char                                content_length_buffer[64];
    int                                 rc=0;
    int					i;
    size_t				nbytes;

    test_server = (http_test_server_t*) user_arg;
    info = test_server->info;
    if (result == GLOBUS_SUCCESS &&
            method != NULL && uri != NULL &&
            (strcmp(method, "POST") == 0) &&
            (strcmp(uri, "/post-test") == 0))
    {
	
	for (i = 0; i < info->iterations; i++)
	{
	    result = globus_xio_read(
		    test_server->handle,
		    info->buffer,
		    info->size,
		    info->size,
		    &nbytes,
		    NULL);

	    if (result != GLOBUS_SUCCESS || nbytes != info->size)
	    {
		fprintf(stderr, "Error reading from http: %s\n",
		    globus_object_printable_to_string(
			globus_error_peek(result)));
	    }
	}
    }
    else
    {
        rc = 404;
        goto error_respond_exit;
    } 
    result = globus_xio_read(
	    test_server->handle,
	    info->buffer,
	    info->size,
	    1,
	    &nbytes,
	    NULL);

    if (result && !http_is_eof(result))
    {
        fprintf(stderr, "Error reading eof from http: %s\n",
                globus_error_print_friendly(globus_error_get(result)));
    }

    if (info->transfer_encoding != NULL)
    {
	response_headers[header_cnt].name = "Transfer-Encoding";
	response_headers[header_cnt].value = info->transfer_encoding;

	header_cnt++;
    }

    if ((http_version == GLOBUS_XIO_HTTP_VERSION_1_0) ||
	    ((info->transfer_encoding != NULL)
		&& strcmp(info->transfer_encoding, IDENTITY) == 0))
    {
	    sprintf(content_length_buffer, "%lu", (unsigned long) info->size);

	    response_headers[header_cnt].name = "Content-Length";
	    response_headers[header_cnt].value = &content_length_buffer[0];

	    header_cnt++;
    }

    result = http_test_server_respond(
	    test_server,
	    rc,
	    NULL,
	    response_headers,
	    header_cnt);

    if (result != GLOBUS_SUCCESS)
    {
	goto error_exit;
    }
    result = globus_xio_write(
            test_server->handle,
            info->buffer,
            1,
            1,
            &nbytes,
            NULL);
    globus_xio_handle_cntl(
            test_server->handle,
            info->http_driver,
            GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY);
    info->size = throughput_next_size(info->size);
    if (info->size == -1)
    {
        http_test_server_close_handle(test_server);
        http_test_server_shutdown(test_server);
    }

    return;

error_respond_exit:
    http_test_server_respond(
            test_server,
            rc,
            NULL,
            NULL,
            0);

error_exit:
    http_test_server_close_handle(test_server);
    http_test_server_shutdown(test_server);

}
Beispiel #27
0
/**
 * @brief Wrap
 * @ingroup globus_gsi_gss_assist
 *
 * @param minor_status
 *        GSSAPI return code.  If the call was successful, the minor 
 *        status is equal to GLOBUS_SUCCESS.  Otherwise, it is an
 *        error object ID for which  
 *        globus_error_get() and globus_object_free()
 *        can be used to get and destroy it.
 * @param context_handle
 *        the context. 
 * @param data
 *        pointer to application data to wrap and send
 * @param length
 *        length of the @a data array
 * @param token_status
 *        assist routine get/send token status 
 * @param gss_assist_send_token
 *        a send_token routine 
 * @param gss_assist_send_context
 *        first arg for the send_token
 * @param fperr
 *        file handle to write error message to.
 *
 * @return
 *        GSS_S_COMPLETE on success
 *        Other GSSAPI errors on failure.  
 *
 * @see gss_wrap()
 */
OM_uint32
globus_gss_assist_wrap_send(
    OM_uint32 *                         minor_status,
    const gss_ctx_id_t                  context_handle,
    char *			        data,
    size_t			        length,
    int *			        token_status,
    int (*gss_assist_send_token)(void *, void *, size_t),
    void *                              gss_assist_send_context,
    FILE *                              fperr)
{
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    globus_result_t                     local_result = GLOBUS_SUCCESS;
    gss_buffer_desc                     input_token_desc  = GSS_C_EMPTY_BUFFER;
    gss_buffer_t                        input_token       = &input_token_desc;
    gss_buffer_desc                     output_token_desc = GSS_C_EMPTY_BUFFER;
    gss_buffer_t                        output_token      = &output_token_desc;
    static char *                       _function_name_ =
        "globus_gss_assist_wrap_send";
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;

    *token_status = 0;
    input_token->value = data;
    input_token->length = length;

    major_status = gss_wrap(&local_minor_status,
                            context_handle,
                            0,
                            GSS_C_QOP_DEFAULT,
                            input_token,
                            NULL,
                            output_token);
  
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
        3, (globus_i_gsi_gss_assist_debug_fstream,
            _GASL("Wrap_send:maj:%8.8x min:%8.8x inlen:%u outlen:%u\n"),
            (unsigned int) major_status, 
            (unsigned int) *minor_status, 
            input_token->length = length,
            output_token->length));

    if (major_status != GSS_S_COMPLETE)
    {
        globus_object_t *               error_obj;
        globus_object_t *               error_copy;

        error_obj = globus_error_get((globus_result_t) local_minor_status);
        error_copy = globus_object_copy(error_obj);

        local_minor_status = (OM_uint32) globus_error_put(error_obj);
        if(fperr)
        {
            globus_gss_assist_display_status(
                stderr,
                _GASL("gss_assist_wrap_send failure:"),
                major_status,
                local_minor_status,
                *token_status);
        }
        
        local_result = globus_error_put(error_copy);
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
            local_result,
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_WRAP);
        *minor_status = (OM_uint32) local_result;
        goto release_output_token;
    }

    *token_status = (*gss_assist_send_token)(gss_assist_send_context,
                                             output_token->value,
                                             output_token->length);
    if(*token_status != 0)
    {
        GLOBUS_GSI_GSS_ASSIST_ERROR_RESULT(
            local_result,
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_WRAP,
            (_GASL("Error sending output token. token status: %d\n"), 
             *token_status));
        *minor_status = (OM_uint32) local_result;
        major_status = GSS_S_FAILURE;
        goto release_output_token;
    }

    major_status = gss_release_buffer(& local_minor_status,
                                      output_token);
    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSS_ASSIST_ERROR_CHAIN_RESULT(
            local_result,
            GLOBUS_GSI_GSS_ASSIST_ERROR_WITH_WRAP);
        *minor_status = (OM_uint32) local_result;
    }

    goto exit;

 release_output_token:

    gss_release_buffer(&local_minor_status,
                       output_token);

 exit:
    
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
    return major_status;
}
/* must be safe to call from win32 thread
 */
static
void
globus_l_xio_win32_socket_handle_write(
    globus_l_xio_win32_socket_t *       handle,
    globus_i_xio_system_op_info_t *     write_info)
{
    globus_size_t                       nbytes;
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_win32_socket_handle_write);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);

    result = GLOBUS_SUCCESS;

    if(write_info->op)
    {
        globus_xio_operation_refresh_timeout(write_info->op);
    }
    
    switch(write_info->type)
    {
      case GLOBUS_I_XIO_SYSTEM_OP_CONNECT:
        {
            int                         err;
            globus_socklen_t            errlen;

            errlen = sizeof(err);
            if(getsockopt(
                handle->socket, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen)
                    == SOCKET_ERROR)
            {
                err = WSAGetLastError();
            }

            if(err)
            {
                result = GlobusXIOErrorSystemError("connect", err);
            }
        }
        break;

      case GLOBUS_I_XIO_SYSTEM_OP_WRITE:
        /* we loop repeatedly here to use up all available space until
         * the write would return EWOULDBLOCK.  at that time, we'll get
         * another event to land us back here
         */
        do
        {
            result = globus_i_xio_system_socket_try_write(
                handle->socket,
                write_info->sop.data.iov,
                write_info->sop.data.iovc,
                write_info->sop.data.flags,
                write_info->sop.data.addr,
                &nbytes);
            if(result == GLOBUS_SUCCESS)
            {
                if(nbytes > 0)
                {
                    write_info->nbytes += nbytes;
                    GlobusIXIOUtilAdjustIovec(
                        write_info->sop.data.iov,
                        write_info->sop.data.iovc, nbytes);
                }
                else if(write_info->sop.data.iovc > 0 &&
                    write_info->sop.data.iov[0].iov_len > 0)
                {
                    /* we consumed write event */
                    handle->ready_events &= ~FD_WRITE;
                }
            }
        } while(nbytes > 0 && write_info->nbytes < write_info->waitforbytes);
        break;

      default:
        globus_assert(0 && "Unexpected type for write operation");
        return;
        break;
    }
  
    if(result != GLOBUS_SUCCESS)
    {
        write_info->error = globus_error_get(result);
    }
    
    /* always true for connect operations */
    if(write_info->nbytes >= write_info->waitforbytes ||
        result != GLOBUS_SUCCESS)
    {
        write_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE;
    }

    GlobusXIOSystemDebugExitFD(handle->socket);
}
/* must be safe to call from win32 thread
 */
static
void
globus_l_xio_win32_socket_handle_read(
    globus_l_xio_win32_socket_t *       handle,
    globus_i_xio_system_op_info_t *     read_info)
{
    globus_size_t                       nbytes;
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_win32_socket_handle_read);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);

    result = GLOBUS_SUCCESS;

    if(read_info->op)
    {
        globus_xio_operation_refresh_timeout(read_info->op);
    }
    
    GlobusXIOSystemDebugPrintf(
        GLOBUS_I_XIO_SYSTEM_DEBUG_INFO,
        ("[%s] In globus_l_xio_win32_socket_handle_read fd=%lu, read_info->type=%d\n",
             _xio_name,
             (unsigned long)handle->socket, (int) read_info->type));
    switch(read_info->type)
    {
      case GLOBUS_I_XIO_SYSTEM_OP_ACCEPT:
        {
            SOCKET                      new_fd;

            new_fd = accept(handle->socket, 0, 0);
            
            if(new_fd == INVALID_SOCKET)
            {
                int                     error = WSAGetLastError();
                
                if(error != WSAECONNRESET && error != WSAEWOULDBLOCK)
                {
                    char errbuf[64];
                    sprintf(errbuf, "accept, fd=%ld, error=%d",
                        (long) handle->socket, error);
                    result = GlobusXIOErrorSystemError(errbuf, error);
                    GlobusXIOSystemDebugPrintf(
                        GLOBUS_I_XIO_SYSTEM_DEBUG_INFO,
                        ("[%s] Tried to accept new connection on fd=%lu, %s\n",
                             _xio_name,
                             (unsigned long)handle->socket, errbuf));

                }
                else
                {
                    char errbuf[64];
                    sprintf(errbuf, "accept, fd=%ld, error=%d",
                        (long) handle->socket, error);
                    GlobusXIOSystemDebugPrintf(
                        GLOBUS_I_XIO_SYSTEM_DEBUG_INFO,
                        ("[%s] Tried to accept new connection on fd=%lu, %s\n",
                             _xio_name,
                             (unsigned long)handle->socket, errbuf));
                }
            }
            else
            {
                unsigned long           flag = 0;
                
                /* clear inherited attrs */
                WSAEventSelect(new_fd, 0, 0);
                ioctlsocket(new_fd, FIONBIO, &flag);
    
                *read_info->sop.non_data.out_fd = new_fd;
                read_info->nbytes++;
                GlobusXIOSystemDebugPrintf(
                    GLOBUS_I_XIO_SYSTEM_DEBUG_INFO,
                    ("[%s] Accepted new connection on fd=%lu, fd=%lu\n",
                         _xio_name,
                         (unsigned long)handle->socket, (unsigned long)new_fd));
            }
        }
        break;

      case GLOBUS_I_XIO_SYSTEM_OP_READ:
        /* we loop repeatedly here to read all available data until
         * the read would return EWOULDBLOCK.  at that time, we'll get
         * another event to land us back here.
         * (This looping is necessary to work around a winsock bug where we
         * aren't notified of the peer closing the connection on short lived
         * connections)
         */
        do
        {
            result = globus_i_xio_system_socket_try_read(
                handle->socket,
                read_info->sop.data.iov,
                read_info->sop.data.iovc,
                read_info->sop.data.flags,
                read_info->sop.data.addr,
                &nbytes);
            if(result == GLOBUS_SUCCESS)
            {
                if(nbytes > 0)
                {
                    read_info->nbytes += nbytes;
                    GlobusIXIOUtilAdjustIovec(
                        read_info->sop.data.iov,
                        read_info->sop.data.iovc, nbytes);
                }
                else if(read_info->sop.data.iovc > 0 &&
                    read_info->sop.data.iov[0].iov_len > 0)
                {
                    /* we consumed read event */
                    handle->ready_events &= ~FD_READ;
                }
            }
        } while(nbytes > 0 && read_info->nbytes < read_info->waitforbytes);
        break;

      default:
        globus_assert(0 && "Unexpected type for read operation");
        return;
        break;
    }
    
    if(result != GLOBUS_SUCCESS)
    {
        read_info->error = globus_error_get(result);
    }
    
    /* always true for accept operations */
    if(read_info->nbytes >= read_info->waitforbytes ||
        result != GLOBUS_SUCCESS)
    {
        read_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE;
    }

    GlobusXIOSystemDebugExitFD(handle->socket);
}
int main(int argc,
	 char *argv[])
{
    globus_ftp_client_handle_t			handle;
    globus_ftp_client_operationattr_t 		attr;
    globus_ftp_client_handleattr_t		handle_attr;
    globus_byte_t				buffer[SIZE];
    globus_size_t				buffer_length = sizeof(buffer);
    globus_result_t				result;
    globus_off_t				size;
    char *					src;
    char *					dst;

    LTDL_SET_PRELOADED_SYMBOLS();
    globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    globus_ftp_client_handleattr_init(&handle_attr);
    globus_ftp_client_operationattr_init(&attr);
    
    test_parse_args(argc, 
		    argv,
		    &handle_attr,
		    &attr,
		    &src,
		    &dst);

    globus_mutex_init(&lock, GLOBUS_NULL);
    globus_cond_init(&cond, GLOBUS_NULL);

    globus_ftp_client_handle_init(&handle, &handle_attr);

    done = GLOBUS_FALSE;
    result = globus_ftp_client_size(&handle,
				   src,
				   &attr,
				   &size,
				   done_cb,
				   0);
    if(result != GLOBUS_SUCCESS)
    {
	fprintf(stderr, "%s", globus_object_printable_to_string(globus_error_get(result)));
	error = GLOBUS_TRUE;
	done = GLOBUS_TRUE;
    }
    globus_mutex_lock(&lock);
    while(!done)
    {
	globus_cond_wait(&cond, &lock);
    }
    globus_mutex_unlock(&lock);

    globus_ftp_client_handle_destroy(&handle);

    globus_module_deactivate_all();

    if(test_abort_count && error)
    {
	return 0;
    }
    if(error == GLOBUS_SUCCESS)
    {
	printf("%"GLOBUS_OFF_T_FORMAT"\n", size);
    }
    return error;
}