Logo Search packages:      
Sourcecode: condor version File versions  Download package

void globus_i_ftp_client_response_callback ( void *  user_arg,
globus_ftp_control_handle_t *  handle,
globus_object_t *  in_error,
globus_ftp_control_response_t *  response 
)

FTP response callback.

This function is invoked whenever an FTP response is received on an FTP control connection. It processes the FTP state machine to figure out what to do next.

Parameters:
user_arg A void * which is set to the globus_i_ftp_client_target_t associated with this response.
handle The control handle associated with this response.
error A Globus error object or the value GLOBUS_SUCCESS if the response was received and parsed without error.
response The parsed response string from the server. This is interpreted based on the command currently being processed by the control library.

Definition at line 267 of file globus_ftp_client_state.c.

References globus_i_ftp_client_operationattr_t::allocated_size, globus_i_ftp_client_operationattr_t::allow_ipv6, globus_i_ftp_client_operationattr_t::append, globus_i_ftp_client_handle_t::attr, globus_i_ftp_client_target_s::attr, globus_i_ftp_client_operationattr_t::auth_info, globus_i_ftp_client_target_s::auth_info, globus_i_ftp_client_target_s::authz_assert, globus_i_ftp_client_operationattr_t::authz_assert, globus_i_ftp_client_operationattr_t::buffer, globus_i_ftp_client_operationattr_t::cache_authz_assert, globus_i_ftp_client_target_s::cached_data_conn, globus_i_ftp_client_handle_t::checksum_alg, globus_i_ftp_client_handle_t::checksum_length, globus_i_ftp_client_handle_t::checksum_offset, globus_i_ftp_client_handle_t::chmod_file_mode, globus_i_ftp_client_target_s::control_handle, globus_i_ftp_client_operationattr_t::cwd_first, globus_i_ftp_client_target_s::data_prot, globus_i_ftp_client_operationattr_t::data_prot, globus_i_ftp_client_target_s::dcau, globus_i_ftp_client_operationattr_t::dcau, globus_i_ftp_client_operationattr_t::delayed_pasv, globus_i_ftp_client_target_s::delayed_pasv, globus_i_ftp_client_data_target_t::dest, globus_i_ftp_client_handle_t::dest, globus_i_ftp_client_handle_t::dest_url, globus_i_ftp_client_target_s::disk_stack_str, globus_i_ftp_client_operationattr_t::disk_stack_str, globus_i_ftp_client_handle_t::dst_response_pending_queue, globus_i_ftp_client_handle_t::err, globus_i_ftp_client_target_s::features, globus_i_ftp_client_handle_t::features_pointer, globus_i_ftp_client_operationattr_t::force_striped, globus_i_ftp_client_response_callback(), globus_i_ftp_client_target_activate(), globus_i_ftp_client_transfer_complete(), globus_l_ftp_client_connection_error(), globus_l_ftp_client_layout_string(), globus_l_ftp_client_parallelism_string(), globus_l_ftp_client_parse_feat(), globus_l_ftp_client_parse_pasv(), globus_l_ftp_client_parse_restart_marker(), globus_l_ftp_client_parse_site_help(), globus_l_ftp_client_send_get(), globus_l_ftp_client_send_put(), globus_l_ftp_client_update_buffer_feature(), globus_i_ftp_client_target_s::layout, globus_i_ftp_client_operationattr_t::layout, globus_i_ftp_client_target_s::mask, globus_i_ftp_client_target_s::mode, globus_i_ftp_client_operationattr_t::mode, globus_i_ftp_client_operationattr_t::module_alg_str, globus_i_ftp_client_target_s::net_stack_list, globus_i_ftp_client_target_s::net_stack_str, globus_i_ftp_client_operationattr_t::net_stack_str, globus_i_ftp_client_handle_t::no_callback_count, globus_i_ftp_client_handle_t::num_pasv_addresses, globus_i_ftp_client_handle_t::op, globus_i_ftp_client_data_target_t::operation, globus_i_ftp_client_handleattr_t::outstanding_commands, globus_i_ftp_client_target_s::owner, globus_i_ftp_client_target_s::parallelism, globus_i_ftp_client_operationattr_t::parallelism, globus_i_ftp_client_handle_t::pasv_address, globus_i_ftp_client_target_s::pbsz, globus_i_ftp_client_handleattr_t::pipeline_callback, globus_i_ftp_client_handleattr_t::pipeline_done, globus_i_ftp_client_handle_t::restart_marker, globus_i_ftp_client_operationattr_t::resume_third_party, globus_i_ftp_client_handleattr_t::rfc1738_url, globus_i_ftp_client_handle_t::size_pointer, globus_i_ftp_client_data_target_t::source, globus_i_ftp_client_handle_t::source, globus_i_ftp_client_handle_t::source_size, globus_i_ftp_client_handle_t::source_url, globus_i_ftp_client_handle_t::src_response_pending_queue, globus_i_ftp_client_target_s::state, globus_i_ftp_client_handle_t::state, globus_i_ftp_client_target_s::tcp_buffer, globus_i_ftp_client_target_s::type, globus_i_ftp_client_operationattr_t::type, globus_i_ftp_client_target_s::url, and globus_i_ftp_client_target_s::url_string.

Referenced by globus_i_ftp_client_response_callback(), globus_i_ftp_client_target_activate(), globus_l_ftp_client_send_get(), and globus_l_ftp_client_send_put().

{
    globus_i_ftp_client_target_t *        target;
    globus_object_t *                           error;
    globus_i_ftp_client_handle_t *        client_handle;
    globus_result_t                       result;
    globus_bool_t                   registered=GLOBUS_FALSE;
    char *                          tmpstr = GLOBUS_NULL;
    const char *                    buffer_cmd = GLOBUS_NULL;
    char *                          parallelism_opt = GLOBUS_NULL;
    char *                          layout_opt = GLOBUS_NULL;
    char *                                      list_str = GLOBUS_NULL;    
    unsigned long                   pbsz = 0;
    int                                   rc, oldrc, i;
    char *                                      pathname;
    globus_bool_t                     gridftp2_getput;
    GlobusFuncName(globus_i_ftp_client_response_callback);
    
    target = (globus_i_ftp_client_target_t *) user_arg;
    client_handle = target->owner;
    
    globus_i_ftp_client_debug_printf(1, (stderr, 
        "globus_i_ftp_client_response_callback() entering\n"));
    globus_i_ftp_client_debug_states(2, client_handle);

    globus_assert(! GLOBUS_I_FTP_CLIENT_BAD_MAGIC(&client_handle));
    
    if(in_error)
    {
        error = globus_object_copy(in_error);
    }
    else
    {
        error = GLOBUS_NULL;
    }
   
    globus_i_ftp_client_handle_lock(client_handle);
    
    if(response)
    {
        globus_i_ftp_client_plugin_notify_response(
            client_handle,
            target->url_string,
            target->mask,
            error,
            response);
    }

    if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
        client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART)
    {
      goto finish;
    }        

    /* The behaviour of several states depends on whether to use the
     * GFD.47 (a.k.a GridFTP 2) GETPUT extension.
     */
    result = globus_l_ftp_client_use_gridftp2_getput(target, &gridftp2_getput);
    if (result != GLOBUS_SUCCESS)
    {
        goto result_fault;
    }

    /* This redo is used to make a second run through the state
     * machine, which a few states will require.
     */
    
    pathname = target->url.url_path ? target->url.url_path : "/";
    
redo:
    switch(target->state)
    {
    case GLOBUS_FTP_CLIENT_TARGET_CONNECT:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          /* Successfully connected. Begin authentication */
          target->state = GLOBUS_FTP_CLIENT_TARGET_AUTHENTICATE;

          globus_i_ftp_client_plugin_notify_authenticate(
            client_handle,
            target->url_string,
            &target->auth_info);

          if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
          {
            break;
          }

          globus_assert(
            client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT
            ||
            client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

          result =
            globus_ftp_control_authenticate(
                handle,
                &target->attr->auth_info,
                target->url.scheme_type==GLOBUS_URL_SCHEME_GSIFTP,
                globus_i_ftp_client_response_callback,
                user_arg);
                                                        
          if(result != GLOBUS_SUCCESS)
          {
            /*
             * If authentication fails without registration, notify the
             * plugins, then deal with the fault.
             */
            goto result_fault;

          }
      }
      else if(error || response->response_class
            != GLOBUS_FTP_POSITIVE_PRELIMINARY_REPLY)
      {
          /* Connection failed, deal with it (connect_error
           * unlocks the handle)
           */
          if(!error && response && response->response_buffer)
          {
            error = GLOBUS_I_FTP_CLIENT_ERROR_RESPONSE(response);
          }
          goto notify_fault;
      }
      /* Else, (success + 1yz response), which just means: server will
       * get to you in a moment)
       */
      break;
    case GLOBUS_FTP_CLIENT_TARGET_AUTHENTICATE:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
#           if BUILD_DEBUG
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_FAULT;
          }
#           else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_HELP;
          }
#         endif
          goto redo;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }
      break;
# if BUILD_DEBUG
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_FAULT:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      target->state = GLOBUS_FTP_CLIENT_TARGET_SITE_FAULT;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_INFORMATION;

      tmpstr = globus_libc_getenv("GLOBUS_FTP_CLIENT_FAULT_MODE");

      if(! tmpstr)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_HELP;

          goto redo;
      }

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "SITE FAULT %s" CRLF,
          tmpstr);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT
          ||
          client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      result =
          globus_ftp_control_send_command(
            handle,
            "SITE FAULT %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            tmpstr);

      globus_libc_unsetenv("GLOBUS_FTP_CLIENT_FAULT_MODE");

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SITE_FAULT:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_HELP;
          goto redo;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }
      break;

# endif
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_SITE_HELP:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      target->state = GLOBUS_FTP_CLIENT_TARGET_SITE_HELP;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_INFORMATION;
      
        target->features = globus_i_ftp_client_features_init();
        if(!target->features)
        {
            error = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();
          goto notify_fault;
        }

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "SITE HELP" CRLF);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT
          ||
          client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      result =
          globus_ftp_control_send_command(
            handle,
            "SITE HELP" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;
    case GLOBUS_FTP_CLIENT_TARGET_SITE_HELP:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      if(error != GLOBUS_SUCCESS)
      {
          goto notify_fault;
      }
      else if(response->response_class==GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          /*
           * Parse the reply to find out what is implemented by this
           * server
           */
          error = globus_l_ftp_client_parse_site_help(target, response);
          if(error != GLOBUS_SUCCESS)
            {
                goto notify_fault;
            }
      }

      target->state = GLOBUS_FTP_CLIENT_TARGET_FEAT;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_INFORMATION;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "FEAT" CRLF);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      result =
          globus_ftp_control_send_command(
            handle,
            "FEAT" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;
    case GLOBUS_FTP_CLIENT_TARGET_FEAT:
      globus_assert(
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_CONNECT);

      if(error != GLOBUS_SUCCESS)
      {
          goto notify_fault;
      }
      if(response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          /*
           * Parse the reply to find out what is implemented by this
           * server
           */
          globus_l_ftp_client_parse_feat(target, response);
      }

      if (client_handle->op == GLOBUS_FTP_CLIENT_FEAT)
      {
            target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;
      }     
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_TYPE;
      }

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT)
      {
          client_handle->state =
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION;
      }
      else
      {
          client_handle->state =
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION;
      }
      goto redo;
    
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_TYPE:
      target->state = GLOBUS_FTP_CLIENT_TARGET_TYPE;

      if(target->attr->type == target->type)
      {
          goto skip_type;
      }

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "TYPE %c",
          (char) target->attr->type);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION
          ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "TYPE %c" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          (char) target->attr->type);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_TYPE:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          target->type = target->attr->type;
          result = globus_ftp_control_local_type(target->control_handle,
                                       target->type,
                                       8);
          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_type:
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_AUTHZ_ASSERT;
        goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_AUTHZ_ASSERT:
        target->state = GLOBUS_FTP_CLIENT_TARGET_AUTHZ_ASSERT;

        if (!target->attr->authz_assert)
        {
            goto skip_authz_assert;
        }
        if(target->authz_assert &&
           !strcmp(target->attr->authz_assert, target->authz_assert) &&
           target->attr->cache_authz_assert)
        {
            goto skip_authz_assert;
        }

        target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_MISC;

        globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "SITE AUTHZ_ASSERT %s",
            target->attr->authz_assert);
        
        if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT || 
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
        {   
            break;
        }
        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION
            ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);
        
        result = globus_ftp_control_send_command(
            target->control_handle,
            "SITE AUTHZ_ASSERT %s" CRLF,
            globus_i_ftp_client_response_callback,
            target,
            target->attr->authz_assert);
        
        if(result != GLOBUS_SUCCESS)
        {   
            goto result_fault;
        }

        break;

    case GLOBUS_FTP_CLIENT_TARGET_AUTHZ_ASSERT:
        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        if((!error) &&
           response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
        {
            if (target->authz_assert)
            {
                if (strcmp(target->authz_assert, target->attr->authz_assert))
                {
                    globus_free(target->authz_assert);
                    target->authz_assert = globus_libc_strdup(
                                            target->attr->authz_assert);
                }
            }
            else
            {
                target->authz_assert = 
                    globus_libc_strdup(target->attr->authz_assert);
            }
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

            goto notify_fault;
        }

    skip_authz_assert:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SETNETSTACK;
      goto redo;


    case GLOBUS_FTP_CLIENT_TARGET_SETUP_SETNETSTACK:
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETNETSTACK;
        if(target->attr->net_stack_str == NULL ||  
            (target->net_stack_str != NULL && 
            strcmp(target->attr->net_stack_str, target->net_stack_str) == 0))
        {
            goto skip_setnetstack;
        }
        
        memset(&target->cached_data_conn,
               '\0',
               sizeof(globus_i_ftp_client_data_target_t));

        target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
        globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "SITE SETNETSTACK %s" CRLF,
            target->attr->net_stack_str);

        if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
        {
            break;
        }

        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        result = globus_ftp_control_send_command(
            target->control_handle,
            "SITE SETNETSTACK %s" CRLF,
            globus_i_ftp_client_response_callback,
            target,
            target->attr->net_stack_str);
        if(result != GLOBUS_SUCCESS)
        {
            goto result_fault;
        }

        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETNETSTACK:
        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        if((!error) &&
           response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
        {
            globus_xio_stack_t          stack;
            
            if(target->net_stack_str)
            {
                globus_free(target->net_stack_str);
            }
            target->net_stack_str = 
                globus_libc_strdup(target->attr->net_stack_str);
            
            if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER)
            {
                if(target->net_stack_list)
                {
                    globus_i_ftp_control_unload_xio_drivers(
                        target->net_stack_list);
                    target->net_stack_list = GLOBUS_NULL;
                }
                        
                result = globus_i_ftp_control_load_xio_drivers(
                    target->net_stack_str, &target->net_stack_list);
                if(result != GLOBUS_SUCCESS)
                {
                    target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
        
                    goto notify_fault;
                }
                result = globus_i_ftp_control_create_stack(
                    target->control_handle, target->net_stack_list, &stack);
                if(result != GLOBUS_SUCCESS)
                {
                    target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
        
                    goto notify_fault;
                }
            
                result = globus_i_ftp_control_data_set_stack(
                    target->control_handle, stack);
                if(result != GLOBUS_SUCCESS)
                {
                    target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
        
                    goto notify_fault;
                }
                globus_xio_stack_destroy(stack);
            }      
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

            goto notify_fault;
        }

    skip_setnetstack:
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SETDISKSTACK;
        goto redo;


    case GLOBUS_FTP_CLIENT_TARGET_SETUP_SETDISKSTACK:
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETDISKSTACK;
        if(target->attr->disk_stack_str == NULL ||  
            (target->disk_stack_str != NULL && 
            strcmp(target->attr->disk_stack_str, target->disk_stack_str) == 0))
        {
            goto skip_setdiskstack;
        }
        
        memset(&target->cached_data_conn,
               '\0',
               sizeof(globus_i_ftp_client_data_target_t));

        target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
        globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "SITE SETDISKSTACK %s" CRLF,
            target->attr->disk_stack_str);

        if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
        {
            break;
        }

        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        result = globus_ftp_control_send_command(
            target->control_handle,
            "SITE SETDISKSTACK %s" CRLF,
            globus_i_ftp_client_response_callback,
            target,
            target->attr->disk_stack_str);
        if(result != GLOBUS_SUCCESS)
        {
            goto result_fault;
        }

        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETDISKSTACK:
        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        if((!error) &&
           response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
        {
            if(target->disk_stack_str)
            {
                globus_free(target->disk_stack_str);
            }
            target->disk_stack_str = 
                globus_libc_strdup(target->attr->disk_stack_str);
            
            if(client_handle->op == GLOBUS_FTP_CLIENT_GET)
            {
                /* if not a 3pt or put gotta set stack on local deal 
                for now this will eb an error */
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

                goto notify_fault;
            }      
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

            goto notify_fault;
        }

    skip_setdiskstack:
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_MODE;
        goto redo;


    case GLOBUS_FTP_CLIENT_TARGET_SETUP_MODE:
      target->state = GLOBUS_FTP_CLIENT_TARGET_MODE;
      if(target->attr->mode == target->mode)
      {
          goto skip_mode;
      }
      memset(&target->cached_data_conn,
             '\0',
             sizeof(globus_i_ftp_client_data_target_t));

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "MODE %c" CRLF,
          (char) target->attr->mode);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "MODE %c" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          (char) target->attr->mode);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_MODE:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          target->mode = target->attr->mode;
          result = globus_ftp_control_local_mode(target->control_handle,
                                       target->mode);
          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_mode:
      if(client_handle->op == GLOBUS_FTP_CLIENT_CKSM)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CKSM;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_SIZE;
      }
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_CKSM:


      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;
      
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_INFORMATION;

      globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,  
            "CKSM %s %" GLOBUS_OFF_T_FORMAT " %" GLOBUS_OFF_T_FORMAT " %s" CRLF,
          client_handle->checksum_alg,
          client_handle->checksum_offset,
          client_handle->checksum_length,
            pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
        {
            break;
        }

        globus_assert(client_handle->state ==
                      GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
                      client_handle->state ==
                      GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        result = globus_ftp_control_send_command(
            target->control_handle,
            "CKSM %s %" GLOBUS_OFF_T_FORMAT " %" GLOBUS_OFF_T_FORMAT " %s" CRLF,
            globus_i_ftp_client_response_callback,
            target,
          client_handle->checksum_alg,
          client_handle->checksum_offset,
          client_handle->checksum_length,
            pathname);

        if(result != GLOBUS_SUCCESS)
        {
            goto result_fault;
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_SIZE:
      /*
       * Doing a SIZE isn't necessary but is nice for
       * - resuming  stream mode 3rd party transfers
       *
       * Skip if
       * - server doesn't do SIZE
       * - not interesting
       *   where interesting is
       *   - destination of stream mode 3rd party transfer w/ resume
       *     attr set to true
       */
      if(globus_i_ftp_client_feature_get(
            target->features, 
            GLOBUS_FTP_CLIENT_FEATURE_SIZE) == GLOBUS_FALSE
         ||
         (!
             (
               (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
                target == client_handle->dest &&
                target->attr->resume_third_party &&
                target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM)
               ||
                   (client_handle->op == GLOBUS_FTP_CLIENT_SIZE)
             )
         )
        )
      {
          if(client_handle->op == GLOBUS_FTP_CLIENT_SIZE)
          {
            error = GLOBUS_I_FTP_CLIENT_ERROR_UNSUPPORTED_FEATURE("SIZE");

            goto notify_fault;

          }
          goto skip_size;
      }

      if(client_handle->op == GLOBUS_FTP_CLIENT_SIZE)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SIZE;
      }

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_INFORMATION;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "SIZE %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
                  client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "SIZE %s" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SIZE:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION
          ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if(error != GLOBUS_SUCCESS)
      {
          goto notify_fault;
      }
      if(response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          globus_i_ftp_client_feature_set(
              target->features,
              GLOBUS_FTP_CLIENT_FEATURE_SIZE,
              GLOBUS_FTP_CLIENT_TRUE);

          if(client_handle->source == target)
          {
            globus_libc_scan_off_t((char *) response->response_buffer+4,
                               &client_handle->source_size,
                               GLOBUS_NULL);
          }
          else
          {
            globus_byte_t * size;
            const globus_byte_t * p;
            globus_byte_t *q;

            size = globus_libc_malloc(
                strlen((char *) response->response_buffer+3));
            for(p = response->response_buffer+4, q = size;
                isdigit(*p);
                p++,q++)
            {
                *q = *p;
            }
            *q = '\0';

            if(target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM &&
               client_handle->restart_marker.type ==
               GLOBUS_FTP_CLIENT_RESTART_NONE)
            {
                client_handle->restart_marker.type =
                  GLOBUS_FTP_CLIENT_RESTART_STREAM;

                globus_libc_scan_off_t(
                  (char *) size,
                  &client_handle->restart_marker.stream.offset,
                  GLOBUS_NULL);

                client_handle->restart_marker.stream.ascii_offset =
                  client_handle->restart_marker.stream.offset;
            }
            globus_libc_free(size);
          }

      }
      else if(response->code / 10 == 50)
      {
          /* A 500 response means the server doesn't know about SIZE */
          globus_i_ftp_client_feature_set(
              target->features,
              GLOBUS_FTP_CLIENT_FEATURE_SIZE,
              GLOBUS_FTP_CLIENT_FALSE);

      }
      else if(response->code == 550 && /* file unavailable */
            client_handle->dest == target)
      {
          /*
           * The file may not exist on the remote side if we're
           * restarting.
           */
          ;
      }
      else
      {
          /* Any other response is not good. */
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
          if((!client_handle->err) && (!error))
          {
            error = GLOBUS_I_FTP_CLIENT_ERROR_RESPONSE(response);
          }
          goto connection_error;
      }

    skip_size:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_BUFSIZE;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_BUFSIZE:
      target->state = GLOBUS_FTP_CLIENT_TARGET_BUFSIZE;

      /*
       * TODO: compare buffer mode/size properly for all instances
       * of union components
       */
      if(target->attr->buffer.mode == target->tcp_buffer.mode &&
         target->attr->buffer.fixed.size == target->tcp_buffer.fixed.size)
      {
          goto skip_bufsize;
      }
    if(!(client_handle->op == GLOBUS_FTP_CLIENT_GET ||
        client_handle->op == GLOBUS_FTP_CLIENT_PUT ||
        client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
        client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
        client_handle->op == GLOBUS_FTP_CLIENT_MLSD ||
        client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER))
    {
        goto skip_bufsize;
    }
    
      buffer_cmd = globus_l_ftp_client_guess_buffer_command(client_handle,
                                                target);
      if(buffer_cmd == GLOBUS_NULL)
      {
          error = GLOBUS_I_FTP_CLIENT_ERROR_UNSUPPORTED_FEATURE(
              "Adjust socket buffer");

          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

      /* Choose the proper string to pass along with the chosen
       * buffer size command.
       */
      switch(target->attr->buffer.mode)
      {
      case GLOBUS_FTP_CONTROL_TCPBUFFER_DEFAULT:
          target->attr->buffer.fixed.size = 0UL;
      case GLOBUS_FTP_CONTROL_TCPBUFFER_FIXED:
          break;
      case GLOBUS_FTP_CONTROL_TCPBUFFER_AUTOMATIC:
          error = GLOBUS_I_FTP_CLIENT_ERROR_UNSUPPORTED_FEATURE("ABUF");

          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "%s %lu" CRLF,
          buffer_cmd,
          target->attr->buffer.fixed.size);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
                  client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "%s %lu" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          buffer_cmd,
          target->attr->buffer.fixed.size);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_BUFSIZE:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          globus_l_ftp_client_update_buffer_feature(
              client_handle, target, GLOBUS_FTP_CLIENT_TRUE);

          target->tcp_buffer = target->attr->buffer;

          result = globus_ftp_control_local_tcp_buffer(
            target->control_handle,
            &target->tcp_buffer);

          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }
      else if(error)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }
      else
      {
          globus_l_ftp_client_update_buffer_feature(
              client_handle, target, GLOBUS_FTP_CLIENT_FALSE);

          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_BUFSIZE;
          goto redo;
      }

    skip_bufsize:
      if(target->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK &&
          (client_handle->op == GLOBUS_FTP_CLIENT_GET ||
           client_handle->op == GLOBUS_FTP_CLIENT_MLSD ||
           client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
           client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
           (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
            target == client_handle->source)))
      {
          /* Only send OPTS RETR if the source control handle will
           * be used.
           */
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REMOTE_RETR_OPTS;
      }
      else if(target->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK &&
            client_handle->op == GLOBUS_FTP_CLIENT_PUT)
      {
          /* Only do local_layout and local_parallelism if we are
           * receiving the data (not 3rd party)
           */
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_LOCAL_RETR_OPTS;
      }
      else
      {
          goto skip_opts_retr;
      }

      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_REMOTE_RETR_OPTS:

      parallelism_opt = globus_l_ftp_client_parallelism_string(target);
      layout_opt = globus_l_ftp_client_layout_string(target);

      if((!parallelism_opt) && (!layout_opt))
      {
          goto skip_opts_retr;
      }

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;

      globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "OPTS RETR %s%s" CRLF,
            layout_opt ? layout_opt : "",
            parallelism_opt ? parallelism_opt : "");

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          if(parallelism_opt)
          {
              globus_libc_free(parallelism_opt);
          }
          if(layout_opt)
          {
              globus_libc_free(layout_opt);
          }
          break;
      }
      result = globus_ftp_control_send_command(
          target->control_handle,
          "OPTS RETR %s%s" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          layout_opt ? layout_opt : "",
          parallelism_opt ? parallelism_opt : "");

      if(parallelism_opt)
      {
          globus_libc_free(parallelism_opt);
      }
      if(layout_opt)
      {
          globus_libc_free(layout_opt);
      }
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      target->state = GLOBUS_FTP_CLIENT_TARGET_REMOTE_RETR_OPTS;
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_LOCAL_RETR_OPTS:
        
        if(target->attr->parallelism.mode == target->parallelism.mode &&
            (target->parallelism.mode != GLOBUS_FTP_CONTROL_PARALLELISM_FIXED 
                || target->attr->parallelism.fixed.size ==
                  target->parallelism.fixed.size) &&
          target->attr->layout.mode == target->layout.mode &&
              (target->layout.mode !=
                  GLOBUS_FTP_CONTROL_STRIPING_BLOCKED_ROUND_ROBIN
                  || target->attr->layout.round_robin.block_size ==
                      target->layout.round_robin.block_size))
        {
            goto skip_opts_retr;
        }
        
      result = globus_ftp_control_local_parallelism(
          target->control_handle,
          &target->attr->parallelism);

      if(result)
      {
          goto result_fault;
      }
      result = globus_ftp_control_local_layout(target->control_handle,
                                     &target->attr->layout,
                                     0);
      if(result)
      {
          goto result_fault;
      }

      memcpy(&target->parallelism,
             &target->attr->parallelism,
             sizeof(globus_ftp_control_parallelism_t));

      memcpy(&target->parallelism,
             &target->attr->parallelism,
             sizeof(globus_ftp_control_parallelism_t));

      goto skip_opts_retr;

    case GLOBUS_FTP_CLIENT_TARGET_REMOTE_RETR_OPTS:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION
          ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          memcpy(&target->parallelism,
               &target->attr->parallelism,
               sizeof(globus_ftp_control_parallelism_t));
          memcpy(&target->layout,
               &target->attr->layout,
               sizeof(globus_ftp_control_layout_t));
      }
      else if((!error) && response->code / 10 == 50)
      {
          globus_i_ftp_client_feature_set(
                target->features,
                GLOBUS_FTP_CLIENT_FEATURE_PARALLELISM,
                GLOBUS_FTP_CLIENT_FALSE);

          if(target->attr->parallelism.mode
             == GLOBUS_FTP_CONTROL_PARALLELISM_NONE &&
             target->attr->layout.mode == GLOBUS_FTP_CONTROL_STRIPING_NONE)
          {
            memcpy(&target->parallelism,
                   &target->attr->parallelism,
                   sizeof(globus_ftp_control_parallelism_t));
            memcpy(&target->layout,
                   &target->attr->layout,
                   sizeof(globus_ftp_control_layout_t));
          }
          else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

            goto connection_error;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_opts_retr:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_DCAU;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_DCAU:
      target->state = GLOBUS_FTP_CLIENT_TARGET_DCAU;

      if(target->attr->dcau.mode == target->dcau.mode &&
         target->dcau.mode != GLOBUS_FTP_CONTROL_DCAU_DEFAULT)
      {
          goto skip_dcau;
      }
      if(target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT &&
         globus_i_ftp_client_feature_get(
             target->features, 
             GLOBUS_FTP_CLIENT_FEATURE_DCAU) != GLOBUS_FTP_CLIENT_TRUE)
      {
          goto skip_dcau;
      }
      if(target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT &&
         (target->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SELF ||
          target->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT))
      {
          goto finish_dcau;
      }

      /* changing DCAU forces us to trash our old data connections */
      memset(&target->cached_data_conn,
             '\0',
             sizeof(globus_i_ftp_client_data_target_t));

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "DCAU %c%s%s" CRLF,
          (char) target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT
              ? GLOBUS_FTP_CONTROL_DCAU_SELF : target->attr->dcau.mode,
          target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SUBJECT
            ? " " : "",
          target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SUBJECT
            ? target->attr->dcau.subject.subject : "");

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
            client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "DCAU %c%s%s" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          (char) target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT
              ? GLOBUS_FTP_CONTROL_DCAU_SELF : target->attr->dcau.mode,
          target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SUBJECT
            ? " " : "",
          target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SUBJECT
            ? target->attr->dcau.subject.subject : "");

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_DCAU:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {

          if(target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_SUBJECT)
          {
            char * tmp_subj;
            tmp_subj = target->dcau.subject.subject;

            target->dcau.subject.subject =
                globus_libc_strdup(target->attr->dcau.subject.subject);
            if(! target->dcau.subject.subject)
            {
                error = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();
                target->dcau.subject.subject = tmp_subj;

                goto notify_fault;
            }
            else if(tmp_subj)
            {
                globus_libc_free(tmp_subj);
            }
          }
      finish_dcau:
          if(target->attr->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_DEFAULT)
          {
              if(!globus_i_ftp_client_feature_get(
                  target->features, GLOBUS_FTP_CLIENT_FEATURE_DCAU))
            {
                target->dcau.mode = GLOBUS_FTP_CONTROL_DCAU_NONE;
            }
            else
            {
                target->dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SELF;
            }
          }
          else
          {
            target->dcau.mode = target->attr->dcau.mode;
          }

          result = globus_ftp_control_local_dcau(target->control_handle,
                                       &target->dcau,
                          target->control_handle->cc_handle.auth_info.credential_handle);
          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_dcau:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PBSZ;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_PBSZ:
      target->state = GLOBUS_FTP_CLIENT_TARGET_PBSZ;

      if(target->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_NONE)
      {
          goto skip_pbsz;
      }

      result = globus_ftp_control_get_pbsz(
                target->control_handle,
                &pbsz);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      if(target->pbsz == pbsz)
      {
          goto skip_pbsz;
      }
      
      /* changing PBSZ forces us to trash our old data connections */
      memset(&target->cached_data_conn,
             '\0',
             sizeof(globus_i_ftp_client_data_target_t));

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "PBSZ %lu" CRLF,
          pbsz);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "PBSZ %lu" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          pbsz);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_PBSZ:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          char *                      s;
            
            pbsz = 0;
            s = strstr((char *) response->response_buffer, "PBSZ=");
            if(s)
            {
                sscanf(s, "PBSZ=%lu", &pbsz);
            }
            
            if(pbsz == 0)
            {
                result = globus_ftp_control_get_pbsz(
                    target->control_handle, &pbsz);
            }
            else
            {
                result = globus_ftp_control_local_pbsz(
                    target->control_handle, pbsz);
            }
            
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            target->pbsz = pbsz;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_pbsz:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PROT;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_PROT:
      target->state = GLOBUS_FTP_CLIENT_TARGET_PROT;

      if(target->dcau.mode == GLOBUS_FTP_CONTROL_DCAU_NONE)
      {
          goto skip_prot;
      }
      if(target->attr->data_prot == target->data_prot)
      {
          goto skip_prot;
      }
      /* changing PROT forces us to trash our old data connections [true?] */
      memset(&target->cached_data_conn,
             '\0',
             sizeof(globus_i_ftp_client_data_target_t));

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "PROT %c" CRLF,
          (char) target->attr->data_prot);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          target->control_handle,
          "PROT %c" CRLF,
          globus_i_ftp_client_response_callback,
          target,
          (char) target->attr->data_prot);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_PROT:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          target->data_prot = target->attr->data_prot;

          result = globus_ftp_control_local_prot(target->control_handle,
                                       target->data_prot);
          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

    skip_prot:
      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION:
      /* for operations which don't use a data connection,
       * skip PASV/PORT */
      if(client_handle->op == GLOBUS_FTP_CLIENT_CHMOD)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CHMOD;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_DELETE)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_DELETE;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_MKDIR)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_MKDIR;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_RMDIR)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_RMDIR;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_CWD)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CWD;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_MOVE)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_RNFR;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_MDTM)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_MDTM;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_MLST)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_MLST;
      }
      else if(client_handle->op == GLOBUS_FTP_CLIENT_STAT)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_STAT;
      }
      /* Prefer PASV data connections for most operations */
      else if(client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION ||
            (client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER &&
             target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM))
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PASV;
      }
      /* In extended block mode, we MUST have RETR/LIST in PORT mode */
      else
      {
          globus_assert(client_handle->state ==
                    GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PORT;
      }

      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_OPTS_PASV_DELAYED:
        globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        if((!error) &&
            response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
        {
            target->delayed_pasv = target->attr->delayed_pasv;
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PASV;
            
            goto redo;
        }
        /* XXX need to ignore error */
        
        target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
        goto notify_fault;       

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_PASV:
        if(gridftp2_getput == GLOBUS_TRUE)
        {
            goto skip_pasv;
        }

      if(globus_i_ftp_client_can_reuse_data_conn(client_handle))
      {
          goto skip_pasv;
      }
      
        if(target->delayed_pasv != target->attr->delayed_pasv && 
            globus_i_ftp_client_feature_get(target->features, 
            GLOBUS_FTP_CLIENT_FEATURE_DELAYED_PASV) == GLOBUS_FTP_CLIENT_TRUE)
        {
          target->state = GLOBUS_FTP_CLIENT_TARGET_OPTS_PASV_DELAYED;
            
            target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_PARAMETERS;
            globus_i_ftp_client_plugin_notify_command(
                client_handle,
                target->url_string,
                target->mask,
                "OPTS PASV AllowDelayed=%c;" CRLF,
                target->attr->delayed_pasv ? '1' : '0');
                
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            globus_assert(
                client_handle->state ==
                GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
                client_handle->state ==
                GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);
            
            result =
                globus_ftp_control_send_command(
                target->control_handle,
                "OPTS PASV AllowDelayed=%c;" CRLF,
                globus_i_ftp_client_response_callback,
                target,
                target->attr->delayed_pasv ? '1' : '0');
            
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            break;
        }

      if((client_handle->op == GLOBUS_FTP_CLIENT_PUT ||
         client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER) &&
         (target->attr->layout.mode != GLOBUS_FTP_CONTROL_STRIPING_NONE ||
          target->attr->force_striped))
      {
          if(target->attr->allow_ipv6)
          {
              tmpstr = "SPAS 2";
          }
          else
          {
              tmpstr = "SPAS";
          }
      }
      else if(target->attr->allow_ipv6)
      {
          tmpstr = "EPSV";
      }
      else
      {
          tmpstr = "PASV";
      }

      target->state = GLOBUS_FTP_CLIENT_TARGET_PASV;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_DATA_ESTABLISHMENT;
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "%s" CRLF,
          tmpstr);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            target->control_handle,
            "%s" CRLF,
            globus_i_ftp_client_response_callback,
            target,
            tmpstr);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_PORT:
      if(globus_i_ftp_client_can_reuse_data_conn(client_handle))
      {
          goto skip_port;
      }
      
      /* turn off delayed pasv now that we're going to use PORT */
      target->delayed_pasv = GLOBUS_FALSE;
      
      if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER)
      {
          if(client_handle->pasv_address)
          {
              globus_free(client_handle->pasv_address);
          }
          client_handle->pasv_address =
              globus_libc_malloc(sizeof(globus_ftp_control_host_port_t));
          client_handle->num_pasv_addresses = 1;
            
          memset(client_handle->pasv_address, 0,
              sizeof(globus_ftp_control_host_port_t));

          result = globus_ftp_control_local_pasv(target->control_handle,
                                         client_handle->pasv_address);
            if(result == GLOBUS_SUCCESS && !target->attr->allow_ipv6 &&
                client_handle->pasv_address[0].hostlen == 16)
            {
                char *                  cs;
                globus_sockaddr_t       addr;
                
                /* control channel was made with ipv6, but we must have
                 * disabled ipv6 since and need an ipv4 address now.
                 * just use localhost
                 */
                GlobusLibcSockaddrSetFamily(addr, AF_INET);
                GlobusLibcSockaddrSetPort(addr,
                    client_handle->pasv_address[0].port);
                
                result = globus_libc_addr_to_contact_string(
                    &addr,
                    GLOBUS_LIBC_ADDR_LOCAL | GLOBUS_LIBC_ADDR_NUMERIC |
                        GLOBUS_LIBC_ADDR_IPV4,
                    &cs);
                if(result == GLOBUS_SUCCESS)
                {
                    globus_libc_contact_string_to_ints(
                        cs,
                        client_handle->pasv_address[0].host,
                        &client_handle->pasv_address[0].hostlen,
                        &client_handle->pasv_address[0].port);
                }
            }
            
          if(result != GLOBUS_SUCCESS)
          {
            goto result_fault;
          }
      }

        if(gridftp2_getput == GLOBUS_TRUE)
        {
            goto skip_port;
        }

      tmpstr = globus_libc_malloc(56 * client_handle->num_pasv_addresses
                           + 7 /*SPOR|PORT|EPRT\r\n\0*/);
                                   /* ' |2|<45>|<5>|' == 56 */
      if(tmpstr == GLOBUS_NULL)
      {
          error = GLOBUS_ERROR_NO_INFO;

          goto notify_fault;
      }
      else
      {
          rc = oldrc = 0;
          if(client_handle->num_pasv_addresses == 1)
          {
              if(target->attr->allow_ipv6 &&
                  client_handle->pasv_address[0].hostlen == 16)
              {
                  rc += sprintf(tmpstr, "EPRT");
              }
              else
              {
                rc += sprintf(tmpstr, "PORT");
            }
          }
          else
          {
            rc += sprintf(tmpstr, "SPOR");
          }

          if(rc == oldrc)
          {
            error = GLOBUS_ERROR_NO_INFO;

              goto notify_fault;
          }

          for(i = 0; i < client_handle->num_pasv_addresses; i++)
          {
              oldrc = rc;
              if(target->attr->allow_ipv6 &&
                  (client_handle->num_pasv_addresses > 1 ||
                  client_handle->pasv_address[0].hostlen == 16))
              {
                  char                buf[50];
                  
                  globus_ftp_control_host_port_get_host(
                        &client_handle->pasv_address[i], buf);
    
                  rc += sprintf(&tmpstr[oldrc],
                                 " |%d|%s|%d|",
                                 client_handle->pasv_address[i].hostlen == 16
                                    ? 2 : 1,
                                 buf,
                                 (int) client_handle->pasv_address[i].port);
              }
              else
              {
                    rc += sprintf(&tmpstr[oldrc],
                                 " %d,%d,%d,%d,%d,%d",
                                 client_handle->pasv_address[i].host[0],
                                 client_handle->pasv_address[i].host[1],
                                 client_handle->pasv_address[i].host[2],
                                 client_handle->pasv_address[i].host[3],
                                 (client_handle->pasv_address[i].port >> 8)
                                 & 0xff,
                                 client_handle->pasv_address[i].port & 0xff);
                }
                if(rc == oldrc)
                {
                    error = GLOBUS_ERROR_NO_INFO;

                    goto notify_fault;
                }
          }

          target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_DATA_ESTABLISHMENT;
          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "%s" CRLF,
            tmpstr);

          if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
          {
            globus_libc_free(tmpstr);
            break;
          }
          globus_assert( client_handle->state ==
                   GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
                   client_handle->state ==
                   GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

          target->state = GLOBUS_FTP_CLIENT_TARGET_PORT;

          result =
            globus_ftp_control_send_command(
                  target->control_handle,
                  "%s" CRLF,
                  globus_i_ftp_client_response_callback,
                  target,
                  tmpstr);

          globus_libc_free(tmpstr);
      }

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_PASV:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          if(target->delayed_pasv)
          {
              goto skip_pasv;     
          }
          
          globus_l_ftp_client_parse_pasv(
              handle,
              response, 
              &client_handle->pasv_address, 
              &client_handle->num_pasv_addresses);
            
          if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER)
          {
              
            if(client_handle->num_pasv_addresses == 1)
            {
                result =
                  globus_ftp_control_local_port(
                      handle,
                      client_handle->pasv_address);
            }
            else
            {
                result =
                  globus_ftp_control_local_spor(
                      handle,
                      client_handle->pasv_address,
                      client_handle->num_pasv_addresses);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
          }

          /* Store the current data connection in the cache for
           * the target associated with this transfer, if the server
           * will support it.
           */
          if(globus_l_ftp_client_can_cache_data_connection(target))
          {
                if(client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
                   client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
                   client_handle->op == GLOBUS_FTP_CLIENT_MLSD)
                {
                target->cached_data_conn.operation = GLOBUS_FTP_CLIENT_GET;
                }
                else
                {
                    target->cached_data_conn.operation = client_handle->op;
                }
                      
            target->cached_data_conn.source = client_handle->source;
            target->cached_data_conn.dest = client_handle->dest;
          }
          /* In a 3rd party transfer, we need to clear the peer's
           * data connection cache if we've called passive on the
           * destination server.
           */
          if(client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER)
          {
            memset(&client_handle->source->cached_data_conn,
                   '\0',
                   sizeof(globus_i_ftp_client_data_target_t));
          }

      skip_pasv:
            if((client_handle->op == GLOBUS_FTP_CLIENT_PUT ||
                (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER && 
                client_handle->dest == target)) && 
                target->attr->allocated_size > 0)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_ALLO;
            }
          else if(client_handle->restart_marker.type !=
             GLOBUS_FTP_CLIENT_RESTART_NONE)
          {
            if(target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_STREAM;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_EB;
            }
          }
          else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION;
          }
      }
        else if(!error)
      {
          if(target->attr->allow_ipv6)
          {
              /* lets try without ipv6 */
              target->attr->allow_ipv6 = GLOBUS_FALSE;
              globus_ftp_control_ipv6_allow(handle, GLOBUS_FALSE);
              target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PASV;
          }
          else if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER &&
             target->mode != GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK )
          {
              /* Try doing a PORT in some cases */
              target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PORT;
          }
          else
          {
              target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
              goto notify_fault;
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
          goto notify_fault;
      }

      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_PORT:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
          if(globus_l_ftp_client_can_cache_data_connection(target))
          {
                if(client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
                   client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
                   client_handle->op == GLOBUS_FTP_CLIENT_MLSD)
                {
                target->cached_data_conn.operation = GLOBUS_FTP_CLIENT_GET;
                }
                else
                {
                    target->cached_data_conn.operation = client_handle->op;
                }
                      
            target->cached_data_conn.source = client_handle->source;
            target->cached_data_conn.dest = client_handle->dest;
          }

      skip_port:
            if((client_handle->op == GLOBUS_FTP_CLIENT_PUT ||
                (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER && 
                client_handle->dest == target)) && 
                target->attr->allocated_size > 0)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_ALLO;
            }
          else if(client_handle->restart_marker.type !=
             GLOBUS_FTP_CLIENT_RESTART_NONE)
          {
            if(target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_STREAM;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_EB;
            }
          }
          else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION;
          }
      }
      else if(!error && target->attr->allow_ipv6 &&
          client_handle->op == GLOBUS_FTP_CLIENT_GET)
      {
          target->attr->allow_ipv6 = GLOBUS_FALSE;
          globus_ftp_control_ipv6_allow(handle, GLOBUS_FALSE);
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PORT;
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }
      goto redo;
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_STREAM:
      /*
       * REST must be the last thing done on the control connection
       * before sending the RETR, STOR, ERET, or ESTO command.
       */
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if(!globus_i_ftp_client_feature_get( 
          target->features, 
          GLOBUS_FTP_CLIENT_FEATURE_REST_STREAM))
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto connection_error;
      }
      target->state = GLOBUS_FTP_CLIENT_TARGET_REST;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_MODIFIERS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
            target->url_string,
          target->mask,
          "REST %" GLOBUS_OFF_T_FORMAT CRLF,
          target->type == GLOBUS_FTP_CONTROL_TYPE_ASCII
              ? client_handle->restart_marker.stream.ascii_offset
              : client_handle->restart_marker.stream.offset);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          handle,
          "REST %" GLOBUS_OFF_T_FORMAT CRLF,
          globus_i_ftp_client_response_callback,
          user_arg,
          target->type == GLOBUS_FTP_CONTROL_TYPE_ASCII
              ? client_handle->restart_marker.stream.ascii_offset
              : client_handle->restart_marker.stream.offset);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;
      
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_ALLO:
      /*
       * ALLO is sent before a STOR, REST or STOR is next.
       */
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      target->state = GLOBUS_FTP_CLIENT_TARGET_ALLO;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_MODIFIERS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
            target->url_string,
          target->mask,
          "ALLO %" GLOBUS_OFF_T_FORMAT CRLF,
          target->attr->allocated_size);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      result = globus_ftp_control_send_command(
          handle,
          "ALLO %" GLOBUS_OFF_T_FORMAT CRLF,
          globus_i_ftp_client_response_callback,
          user_arg,
          target->attr->allocated_size);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_EB:
      /*
       * REST must be the last thing done on the control connection
       * before sending the RETR, STOR, ERET, or ESTO command.
       */
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      globus_ftp_client_restart_marker_to_string(
            &client_handle->restart_marker,
            &tmpstr);

      if(tmpstr)
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_REST;
          target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_TRANSFER_MODIFIERS;

          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "REST %s" CRLF,
            tmpstr);

          if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
          {
            break;
          }

          globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

          result = globus_ftp_control_send_command(
            handle,
            "REST %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            tmpstr);

          globus_libc_free(tmpstr);
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION;
          goto redo;
      }
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_REST:
      globus_assert(
          client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_INTERMEDIATE_REPLY)
      {
          if(target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM)
          {
              globus_i_ftp_client_feature_set(
                    target->features,
                    GLOBUS_FTP_CLIENT_FEATURE_REST_STREAM,
                    GLOBUS_FTP_CLIENT_TRUE);
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
      }

      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION;
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_ALLO:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
      }
      else
      {
          /*  Don't think we really care about error response here
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

          goto notify_fault;
          */
      }
        if(client_handle->restart_marker.type !=
            GLOBUS_FTP_CLIENT_RESTART_NONE)
        {
            if(target->mode == GLOBUS_FTP_CONTROL_MODE_STREAM)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_STREAM;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_REST_EB;
            }
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION;
        }
      goto redo;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_OPERATION:
      switch(client_handle->op)
      {
        case GLOBUS_FTP_CLIENT_LIST:
        case GLOBUS_FTP_CLIENT_NLST:
        case GLOBUS_FTP_CLIENT_MLSD:
          if(target->attr->cwd_first)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_LIST_CWD;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_LIST;
            }
          goto redo;
        case GLOBUS_FTP_CLIENT_GET:
            if (gridftp2_getput == GLOBUS_TRUE)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_GETPUT_GET;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_GET;
            }
            goto redo;
        case GLOBUS_FTP_CLIENT_PUT:
            if (gridftp2_getput == GLOBUS_TRUE)
            {
                 target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_GETPUT_PUT;
            }
            else
            {
                 target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_PUT;
            }
          goto redo;
        case GLOBUS_FTP_CLIENT_TRANSFER:
          if(client_handle->state ==
             GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION)
          {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_TRANSFER_DEST;
          }
          else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_TRANSFER_SOURCE;
          }
          goto redo;
        case GLOBUS_FTP_CLIENT_IDLE:
          globus_assert(client_handle->op != GLOBUS_FTP_CLIENT_IDLE);
          goto finish;

        default:/* No other states should occur */
          globus_assert(0 && "Unexpected state");
      }

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_LIST_CWD:
      /*
       * CWD before a listing operation.
       */
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_LIST;
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
            target->url_string,
          target->mask,
          "CWD %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      result = globus_ftp_control_send_command(
          handle,
          "CWD %s" CRLF,
          globus_i_ftp_client_response_callback,
          user_arg,
          pathname);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_LIST:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

        /* if there is a response before this it is probably from a
          CWD or NOOP */
        if(response != NULL)
        {
            if((!error) &&
              response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
            {
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
    
                goto notify_fault;
            }
        }

        if(!target->delayed_pasv)
        {
            result =
                globus_ftp_control_data_connect_read(target->control_handle,
                                                     GLOBUS_NULL,
                                                     GLOBUS_NULL);
        }
        else
        {
            result = GLOBUS_SUCCESS;
        }
        
      target->state = GLOBUS_FTP_CLIENT_TARGET_LIST;

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      client_handle->state =
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_LIST;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      switch(client_handle->op)
      {
        case GLOBUS_FTP_CLIENT_LIST:
          list_str = "LIST";
          break;

        case GLOBUS_FTP_CLIENT_NLST:
          list_str = "NLST";
          break;

        case GLOBUS_FTP_CLIENT_MLSD:
          list_str = "MLSD";
          break;

          default:
            globus_assert(0 && "Unexpected list op");
            break;
      }
      
      
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "%s %s" CRLF,
          list_str,
          target->attr->cwd_first ? "" : pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_LIST);

      result =
          globus_ftp_control_send_command(
            handle,
            "%s %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            list_str,
            target->attr->cwd_first ? "" : pathname);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_MLST:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "MLST %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "MLST %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_STAT:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "STAT %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "STAT %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_CHMOD:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "SITE CHMOD %04o %s" CRLF,
          client_handle->chmod_file_mode,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "SITE CHMOD %04o %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            client_handle->chmod_file_mode,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;
      
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_DELETE:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "DELE %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "DELE %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_RNFR:

      target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_RNTO;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "RNFR %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "RNFR %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_RNTO:
    {
        globus_url_t                    dest_url;
      globus_bool_t                 rfc1738_url;
      globus_ftp_client_handleattr_t  handle_attr;
      
      handle_attr = &client_handle->attr;

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      result = globus_ftp_client_handleattr_get_rfc1738_url(&handle_attr,
                                         &rfc1738_url);
      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      
        if(rfc1738_url==GLOBUS_TRUE)
      {
          result = (globus_result_t) globus_url_parse_rfc1738(client_handle->dest_url,
                &dest_url);
      }
      else
      {
          result = (globus_result_t) globus_url_parse(client_handle->dest_url, 
              &dest_url);
      }

        if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "RNTO %s" CRLF,
          dest_url.url_path);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
            globus_url_destroy(&dest_url);
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      {
          result =
            globus_ftp_control_send_command(
                handle,
                "RNTO %s" CRLF,
                globus_i_ftp_client_response_callback,
                user_arg,
                dest_url.url_path);
      }

        globus_url_destroy(&dest_url);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;
    }
    case GLOBUS_FTP_CLIENT_TARGET_SETUP_MKDIR:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "MKD %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "MKD %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_RMDIR:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "RMD %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "RMD %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_CWD:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

/*
      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "MLST %s" CRLF,
          pathname);
*/

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "CWD %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_MDTM:

      target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      globus_i_ftp_client_plugin_notify_command(
          client_handle,
          target->url_string,
          target->mask,
          "MDTM %s" CRLF,
          pathname);

      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      result =
          globus_ftp_control_send_command(
            handle,
            "MDTM %s" CRLF,
            globus_i_ftp_client_response_callback,
            user_arg,
            pathname);

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_GET:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

        if(!target->delayed_pasv)
        {
            result =
                globus_ftp_control_data_connect_read(target->control_handle,
                                                     GLOBUS_NULL,
                                                     GLOBUS_NULL);
        }
        else
        {
            result = GLOBUS_SUCCESS;
        }

      target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      client_handle->state =
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

        if(target->attr->module_alg_str != GLOBUS_NULL)
      {
          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "ERET %s %s" CRLF,
                target->attr->module_alg_str,
            pathname);
      }
      else
      {
          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "RETR %s" CRLF,
            pathname);
      }
      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET);


        if(!0)
        {
            if(target->attr->module_alg_str != GLOBUS_NULL)
            {
                result =
                    globus_ftp_control_send_command(
                        handle,
                        "ERET %s %s" CRLF,
                        globus_i_ftp_client_response_callback,
                        user_arg,
                        target->attr->module_alg_str,
                        pathname);
            }
            else
            {
                result =
                    globus_ftp_control_send_command(
                        handle,
                        "RETR %s" CRLF,
                        globus_i_ftp_client_response_callback,
                        user_arg,
                        pathname);
            }
    
            if(result != GLOBUS_SUCCESS)
            {
                    goto result_fault;
            }
        }

        if(client_handle->attr.pipeline_callback)
        {
            globus_bool_t                   added = GLOBUS_TRUE;
                        
            while(added)
            {
                result = globus_l_ftp_client_pp_src_add(
                    client_handle,
                    handle, 
                    target,
                    &added);
                if(result != GLOBUS_SUCCESS)
                {
                    goto result_fault;
                }
            }
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_PUT:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        if(!target->delayed_pasv)       
        {
            result =
                globus_ftp_control_data_connect_write(target->control_handle,
                                                      GLOBUS_NULL,
                                                      GLOBUS_NULL);
        }
        else
        {
            result = GLOBUS_SUCCESS;
        }

      target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;

      if(result != GLOBUS_SUCCESS)
      {
          goto result_fault;
      }

      client_handle->state =
          GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

      if(target->attr->module_alg_str != GLOBUS_NULL)
      {
          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "ESTO %s %s" CRLF,
                target->attr->module_alg_str,
            pathname);
      }
      else
      {
          globus_i_ftp_client_plugin_notify_command(
            client_handle,
            target->url_string,
            target->mask,
            "%s %s" CRLF,
            target->attr->append ? "APPE" : "STOR",
            pathname);
      }
      if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
          client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
      {
          break;
      }

      globus_assert(client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO);

        if(!0)
        {
            if(target->attr->module_alg_str != GLOBUS_NULL)
            {
                result =
                    globus_ftp_control_send_command(
                            handle,
                            "ESTO %s %s" CRLF,
                            globus_i_ftp_client_response_callback,
                            user_arg,
                            target->attr->module_alg_str,
                            pathname);
            }
            else if(target->attr->append)
            {
                result =
                    globus_ftp_control_send_command(
                        handle,
                        "APPE %s" CRLF,
                        globus_i_ftp_client_response_callback,
                        user_arg,
                        pathname);
            }
            else
            {
                result =
                    globus_ftp_control_send_command(
                        handle,
                        "STOR %s" CRLF,
                        globus_i_ftp_client_response_callback,
                        user_arg,
                        pathname);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
        }

        if(client_handle->attr.pipeline_callback)
        {
            globus_bool_t                   added = GLOBUS_TRUE;
                        
            while(added)
            {
                result = globus_l_ftp_client_pp_dst_add(
                    client_handle,
                    handle,
                    target,
                    &added);
                if(result != GLOBUS_SUCCESS)
                {
                    goto result_fault;
                }
            }
        }

      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_TRANSFER_DEST:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

      /* The destination is prepared first. We send all
       * of the commands we need to, including the STOR
       * or ESTO, and then turn our attention to the
       * source.
       */
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

        if(gridftp2_getput)
        {
            result = 
                globus_l_ftp_client_send_put(target, pathname, GLOBUS_TRUE);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
               client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
               client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            
            if(globus_i_ftp_client_can_reuse_data_conn(client_handle))
            {
                /* In this case we do not expect a 127 reply.
                 */
                target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_TRANSFER;
            
                /* In this case we have to wait for the 127 reply
                 * before we can setup the transfer at the source.
                 */
                break;
            }
        }
        else
        {
            if(target->attr->module_alg_str != GLOBUS_NULL)
            {
                globus_i_ftp_client_plugin_notify_command(
                    client_handle,
                    target->url_string,
                    target->mask,
                    "ESTO %s %s" CRLF,
                    target->attr->module_alg_str,
                    pathname);
            }
            else
            {
                globus_i_ftp_client_plugin_notify_command(
                    client_handle,
                    target->url_string,
                    target->mask,
                    "STOR %s" CRLF,
                    pathname);
            }
            
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            
            globus_assert(client_handle->state ==
                GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);
            
            target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;
            
            if(target->attr->module_alg_str != GLOBUS_NULL)
            {
                result = globus_ftp_control_send_command(
                    handle,
                    "ESTO %s %s" CRLF,
                    globus_i_ftp_client_response_callback,
                    user_arg,
                    target->attr->module_alg_str,
                    pathname);
            }
            else
            {
                result = globus_ftp_control_send_command(
                    handle,
                    "STOR %s" CRLF,
                    globus_i_ftp_client_response_callback,
                    user_arg,
                    pathname);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }

            if(client_handle->attr.pipeline_callback)
            {
                int                             i;
                globus_bool_t                   added = GLOBUS_TRUE;
                globus_i_ftp_client_url_ent_t * url_ent;
    
                /* add the one we just sent to the response queue */
                url_ent = globus_malloc(sizeof(globus_i_ftp_client_url_ent_t));
                url_ent->source_url = NULL;
                url_ent->dest_url = globus_libc_strdup(target->url_string);
                globus_l_ftp_client_url_parse(
                    url_ent->dest_url,
                    &url_ent->dst_url,
                    client_handle->attr.rfc1738_url);
                globus_fifo_enqueue(
                    &client_handle->dst_response_pending_queue, url_ent);
    
                client_handle->no_callback_count++;
                client_handle->attr.pipeline_done = GLOBUS_FALSE;
                
                for(
                    i = 0; 
                    added && i < client_handle->attr.outstanding_commands;
                    i++)
                {
                    added = GLOBUS_FALSE;
                    result = globus_l_ftp_client_pp_xfer_dst_add(
                        client_handle,
                        handle,
                        target,
                        &added);
                    if(result != GLOBUS_SUCCESS)
                    {
                        goto result_fault;
                    }
                }
            }
        }
        
        if(!target->delayed_pasv)
        {
            target = client_handle->source;
    
            error =
                globus_i_ftp_client_target_activate(client_handle,
                                                    target,
                                                    &registered);
            if(registered == GLOBUS_FALSE)
            {
                if(client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                   client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_RESTART)
                {
                    break;
                }
                else
                {
                    goto connection_error;
                }
            }
        }
      break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_TRANSFER_SOURCE:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

      client_handle->state =
          GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER;

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;

        if(gridftp2_getput)
        {
            result = 
                globus_l_ftp_client_send_get(target, pathname, GLOBUS_FALSE);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
        
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
               client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
               client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            
            target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;
        }
        else
        {
            if(target->attr->module_alg_str)
            {
                globus_i_ftp_client_plugin_notify_command(
                    client_handle,
                    target->url_string,
                    target->mask,
                    "ERET %s %s" CRLF,
                    target->attr->module_alg_str,
                    pathname);
            }
            else
            {
                globus_i_ftp_client_plugin_notify_command(
                    client_handle,
                    target->url_string,
                    target->mask,
                    "RETR %s" CRLF,
                    pathname);
            }
    
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            globus_assert(client_handle->state ==
                          GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER);
    
            target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;
    
            if(target->attr->module_alg_str)
            {
                result = globus_ftp_control_send_command(
                    handle,
                    "ERET %s %s\r\n",
                    globus_i_ftp_client_response_callback,
                    user_arg,
                    target->attr->module_alg_str,
                    pathname);
            }
            else
            {
                result = globus_ftp_control_send_command(
                    handle,
                    "RETR %s" CRLF,
                    globus_i_ftp_client_response_callback,
                    user_arg,
                    pathname);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            if(client_handle->attr.pipeline_callback)
            {
                int                             i;
                globus_bool_t                   added = GLOBUS_TRUE;
                globus_i_ftp_client_url_ent_t * url_ent;
    
                /* add the one we just sent to the response queue */
                url_ent = globus_malloc(sizeof(globus_i_ftp_client_url_ent_t));
                url_ent->source_url = globus_libc_strdup(target->url_string);
                url_ent->dest_url = NULL;
                globus_l_ftp_client_url_parse(
                    url_ent->source_url,
                    &url_ent->src_url,
                    client_handle->attr.rfc1738_url);
                globus_fifo_enqueue(
                    &client_handle->src_response_pending_queue, url_ent);
    
                client_handle->no_callback_count++;
                client_handle->attr.pipeline_done = GLOBUS_FALSE;
                
                for(
                    i = 0; 
                    added && i < client_handle->attr.outstanding_commands;
                    i++)
                {
                    result = globus_l_ftp_client_pp_xfer_src_add(
                        client_handle,
                        handle,
                        target,
                        &added);
                    if(result != GLOBUS_SUCCESS)
                    {
                        goto result_fault;
                    }
                }
            }
        }
        
        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_GETPUT_GET:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION);

        client_handle->state =
             GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET;
        
        if(target->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK ||
           globus_i_ftp_client_can_reuse_data_conn(client_handle))
        {
            /* In extended block mode, we will be the passive party
             * and do not expect a 127 reply.
             *
             * If a connection was cached, we do not expect a 127 reply
             * either.
             */
            target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;

            /* Setup data connection. Since we do not expect a 127
             * reply, we need to do this before sending GET.
             */
            result =
                globus_ftp_control_data_connect_read(target->control_handle,
                                                     GLOBUS_NULL,
                                                     GLOBUS_NULL);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
        }
        else
        {
            /* We require a 127 reply and will setup the connection once
             * it has been received.
             */
            target->state = GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_GET;
        }

      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;
        if(target->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK) 
        {
            /* In extended block mode, we will be the passive
             * party. GLOBUS_FTP_CLIENT_TARGET_SETUP_PORT has already
             * filled in client_handle->pasv_address.
             */
            result = 
                globus_l_ftp_client_send_get(target, pathname, GLOBUS_FALSE);
        }
        else
        {
            /* In all other cases we prefer to be active.
             */
            result = 
                globus_l_ftp_client_send_get(target, pathname, GLOBUS_TRUE);
        }
        if(result != GLOBUS_SUCCESS)
        {
            goto result_fault;
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_SETUP_GETPUT_PUT:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);

        client_handle->state = GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO;

        if(globus_i_ftp_client_can_reuse_data_conn(client_handle))
        {
            /* In this case we do not expect a 127 reply.
             */
            target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;

            /* Create the data connection.
             */
            result =
                globus_ftp_control_data_connect_write(target->control_handle,
                                                      GLOBUS_NULL,
                                                      GLOBUS_NULL);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_PUT;
        }
 
      target->mask = GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS;
        result = globus_l_ftp_client_send_put(target, pathname, GLOBUS_TRUE);
        if(result != GLOBUS_SUCCESS)
        {
            goto result_fault;
        }           
        break;

    case GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_GET:
      if((!error) &&
         response->code == 127)
        {
            /* Setup our side of PASV.
             */
          globus_l_ftp_client_parse_pasv(
              handle,
              response, 
              &client_handle->pasv_address, 
              &client_handle->num_pasv_addresses);

            if(client_handle->num_pasv_addresses == 1)
            {
                result =
                    globus_ftp_control_local_port(
                        handle,
                        client_handle->pasv_address);
            }
            else
            {
                result =
                    globus_ftp_control_local_spor(
                        handle,
                        client_handle->pasv_address,
                        client_handle->num_pasv_addresses);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            /* Create the data connection.
             */
            result =
                globus_ftp_control_data_connect_read(target->control_handle,
                                                     GLOBUS_NULL,
                                                     GLOBUS_NULL);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;                
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
            goto notify_fault;
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_PUT:        
      if((!error) &&
         response->code == 127)
        {
            /* Setup our side of PASV.
             */
          globus_l_ftp_client_parse_pasv(
              handle,
              response, 
              &client_handle->pasv_address, 
              &client_handle->num_pasv_addresses);

            if(client_handle->num_pasv_addresses == 1)
            {
                result =
                    globus_ftp_control_local_port(
                        handle,
                        client_handle->pasv_address);
            }
            else
            {
                result =
                    globus_ftp_control_local_spor(
                        handle,
                        client_handle->pasv_address,
                        client_handle->num_pasv_addresses);
            }
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            /* Create the data connection.
             */
            result =
                globus_ftp_control_data_connect_write(target->control_handle,
                                                      GLOBUS_NULL,
                                                      GLOBUS_NULL);
            if(result != GLOBUS_SUCCESS)
            {
                goto result_fault;
            }
            
            target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
            goto notify_fault;
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_GETPUT_PASV_TRANSFER:
      if((!error) &&
         response->code == 127)
        {
          globus_l_ftp_client_parse_pasv(
              handle,
              response, 
              &client_handle->pasv_address, 
              &client_handle->num_pasv_addresses);

            /* The passive end of a 3rd party transfer is always the
             * destination.
             */
            target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;

            /* Now continue setting up the source of the transfer.
             */
            target = client_handle->source;

            error =
                globus_i_ftp_client_target_activate(client_handle,
                                                    target,
                                                    &registered);
            if(registered == GLOBUS_FALSE)
            {
                if(client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                   client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_RESTART)
                {
                    break;
                }
                else
                {
                    goto connection_error;
                }
            }
        }
        else
        {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
            goto notify_fault;
        }
        break;

    case GLOBUS_FTP_CLIENT_TARGET_LIST:
    case GLOBUS_FTP_CLIENT_TARGET_RETR:
    case GLOBUS_FTP_CLIENT_TARGET_STOR:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_LIST ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER_ONE_COMPLETE ||
          (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
           client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION) ||
          (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
           client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT) ||
          (target->delayed_pasv && client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
           client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION));

      if((!error) &&
         response->response_class == GLOBUS_FTP_POSITIVE_PRELIMINARY_REPLY)
      {
          if(response->code == 127 || response->code == 129)
            {
/* XXX START copy from GLOBUS_FTP_CLIENT_TARGET_PASV */    
                globus_l_ftp_client_parse_pasv(
                    handle,
                    response, 
                    &client_handle->pasv_address, 
                    &client_handle->num_pasv_addresses);
                
                if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER)
                {
                    
                    if(client_handle->num_pasv_addresses == 1)
                    {
                        result =
                            globus_ftp_control_local_port(
                                handle,
                                client_handle->pasv_address);
                    }
                    else
                    {
                        result =
                            globus_ftp_control_local_spor(
                                handle,
                                client_handle->pasv_address,
                                client_handle->num_pasv_addresses);
                    }
                    if(result != GLOBUS_SUCCESS)
                    {
                        goto result_fault;
                    }
                }
        
                /* Store the current data connection in the cache for
                 * the target associated with this transfer, if the server
                 * will support it.
                 */
                if(globus_l_ftp_client_can_cache_data_connection(target))
                {
                    if(client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
                       client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
                       client_handle->op == GLOBUS_FTP_CLIENT_MLSD)
                    {
                        target->cached_data_conn.operation = GLOBUS_FTP_CLIENT_GET;
                    }
                    else
                    {
                        target->cached_data_conn.operation = client_handle->op;
                    }
                          
                    target->cached_data_conn.source = client_handle->source;
                    target->cached_data_conn.dest = client_handle->dest;
                }
                /* In a 3rd party transfer, we need to clear the peer's
                 * data connection cache if we've called passive on the
                 * destination server.
                 */
                if(client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER)
                {
                    memset(&client_handle->source->cached_data_conn,
                           '\0',
                           sizeof(globus_i_ftp_client_data_target_t));
                }       
/* XXX END copy from GLOBUS_FTP_CLIENT_TARGET_PASV */    
            }

            if((target->delayed_pasv && response->code == 125) || 
                response->code == 127 || response->code == 129)
            {
                if(client_handle->op != GLOBUS_FTP_CLIENT_TRANSFER)
                {
                    if(target->state == GLOBUS_FTP_CLIENT_TARGET_RETR ||
                        target->state == GLOBUS_FTP_CLIENT_TARGET_LIST)
                    {
                        result = globus_ftp_control_data_connect_read(
                            handle,
                            GLOBUS_NULL,
                            GLOBUS_NULL);
                    }
                    else
                    {
                        result = globus_ftp_control_data_connect_write(
                            handle,
                            GLOBUS_NULL,
                            GLOBUS_NULL);
                    }
                    if(result != GLOBUS_SUCCESS)
                    {
                        goto result_fault;
                    }
                }
                else
                {
                    target = client_handle->source;
            
                    error =
                        globus_i_ftp_client_target_activate(client_handle,
                                                            target,
                                                            &registered);
                    if(registered == GLOBUS_FALSE)
                    {
                        if(client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                           client_handle->state==GLOBUS_FTP_CLIENT_HANDLE_RESTART)
                        {
                            break;
                        }
                        else
                        {
                            goto connection_error;
                        }
                    }
                } 
            } 
            
          if(response->code == 127 || response->code == 129)
            {
                break;
            }

          /*
           * this should be a "connected" or "using existing
           * data connection" response
           */
          if(client_handle->op == GLOBUS_FTP_CLIENT_LIST ||
             client_handle->op == GLOBUS_FTP_CLIENT_NLST ||
             client_handle->op == GLOBUS_FTP_CLIENT_MLSD ||
             client_handle->op == GLOBUS_FTP_CLIENT_GET  ||
             client_handle->op == GLOBUS_FTP_CLIENT_PUT)
          {
            target->state =
                GLOBUS_FTP_CLIENT_TARGET_READY_FOR_DATA;

            error =
                globus_i_ftp_client_data_dispatch_queue(client_handle);

            if(error != GLOBUS_SUCCESS)
            {
                globus_i_ftp_client_plugin_notify_fault(
                  client_handle,
                  target->url_string,
                  error);
                    
                    if(client_handle->err)
                    {
                    globus_object_free(error);
                error = NULL;
                }
                else
                {
                    client_handle->err = error;
                    error = GLOBUS_NULL;
                }

                if(client_handle->state == 
                    GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                    client_handle->state == 
                        GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                      client_handle->state == 
                          GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
                {
                  break;
                }
                globus_assert(
                  client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_LIST ||
                  client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO ||
                  client_handle->state ==
                  GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET);

                client_handle->state = GLOBUS_FTP_CLIENT_HANDLE_FAILURE;
                target->state = GLOBUS_FTP_CLIENT_TARGET_FAULT;
                globus_ftp_control_force_close(
                  target->control_handle,
                  globus_i_ftp_client_force_close_callback,
                  target);
            }
          }
          else
          {
            /* performance or restart markers are ok for 3rd party */
            if(response->code == 111)
            {
                globus_l_ftp_client_parse_restart_marker(client_handle,
                                               response);
            }
          }
      }
      else if((!error) &&
            response->response_class
            == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
      {
            if(client_handle->attr.pipeline_callback)
            {                
                globus_i_ftp_client_url_ent_t * url_ent = NULL;
                globus_bool_t                   added = GLOBUS_FALSE;
                
                client_handle->no_callback_count--;
                if(target == client_handle->source)
                {
                    result = globus_l_ftp_client_pp_xfer_src_add(
                        client_handle, handle, target, &added);

                    url_ent = globus_fifo_dequeue(
                        &client_handle->src_response_pending_queue);
                    if(target->url_string)
                    {
                        globus_free(target->url_string);
                    }
                    target->url_string = globus_libc_strdup(url_ent->source_url);
                    if(client_handle->source_url)
                    {
                        globus_free(client_handle->source_url);
                    }
                    client_handle->source_url = url_ent->source_url;
                    globus_url_destroy(&url_ent->src_url);
                    globus_free(url_ent);
            
                    target->state = GLOBUS_FTP_CLIENT_TARGET_RETR;                        
                }
                else if(target == client_handle->dest)
                {
                    result = globus_l_ftp_client_pp_xfer_dst_add(
                        client_handle, handle, target, &added);

                    url_ent = globus_fifo_dequeue(
                        &client_handle->dst_response_pending_queue);
                    if(target->url_string)
                    {
                        globus_free(target->url_string);
                    }
                    target->url_string = globus_libc_strdup(url_ent->dest_url);
                    if(client_handle->dest_url)
                    {
                        globus_free(client_handle->dest_url);
                    }
                    client_handle->dest_url = url_ent->dest_url;
                    globus_url_destroy(&url_ent->dst_url);
                    globus_free(url_ent);
            
                    target->state = GLOBUS_FTP_CLIENT_TARGET_STOR;
                }
            }
          if(client_handle->state ==
                GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER)
          {
                client_handle->state =
                    GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER_ONE_COMPLETE;
            }
          else if(client_handle->state ==
                GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER_ONE_COMPLETE)
          {
                if(client_handle->no_callback_count == 0)
                {
                    client_handle->source->state = 
                        GLOBUS_FTP_CLIENT_TARGET_COMPLETED_OPERATION;
                    client_handle->dest->state = 
                        GLOBUS_FTP_CLIENT_TARGET_COMPLETED_OPERATION;

                    globus_i_ftp_client_transfer_complete(client_handle);

                    goto do_return;
                }
                else
                {
                    goto finish;
                }
          }
          else
          {
              /* this shouldnt really be possible, but handle it */
              target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE;
              globus_i_ftp_client_data_flush(client_handle);
              memset(&target->cached_data_conn,
                    '\0', sizeof(globus_i_ftp_client_data_target_t));
                globus_ftp_control_data_force_close(
                target->control_handle,
                globus_l_ftp_client_data_force_close_callback,
                GLOBUS_NULL);
              goto redo;
          }
      }
      else
      {
          if((!client_handle->err) && (!error))
          {
            client_handle->err = 
                GLOBUS_I_FTP_CLIENT_ERROR_RESPONSE(response);

            globus_ftp_control_data_force_close(
                target->control_handle,
                globus_l_ftp_client_data_force_close_callback,
                GLOBUS_NULL);
          }
          else if(!client_handle->err)
          {
            client_handle->err = globus_object_copy(error);
          }
          globus_i_ftp_client_plugin_notify_fault(
            client_handle,
            target->url_string,
            client_handle->err);

          if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
             client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
          {
            break;
          }

          globus_assert(
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_LIST ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_SOURCE_RETR_OR_ERET ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_DEST_STOR_OR_ESTO ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER ||
            client_handle->state ==
            GLOBUS_FTP_CLIENT_HANDLE_THIRD_PARTY_TRANSFER_ONE_COMPLETE ||
            (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
             client_handle->state ==
             GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION) ||
            (client_handle->op == GLOBUS_FTP_CLIENT_TRANSFER &&
             client_handle->state ==
             GLOBUS_FTP_CLIENT_HANDLE_SOURCE_CONNECT));
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
            
            goto connection_error;
      }

      break;
    case GLOBUS_FTP_CLIENT_TARGET_READY_FOR_DATA:
    case GLOBUS_FTP_CLIENT_TARGET_NEED_EMPTY_AND_COMPLETE:
      /*
       * We've received the callback for this operation, so now we
       * just need to wait for the final data callbacks
       */
      if(error)
      {
          if(client_handle->err == GLOBUS_SUCCESS)
          {
            client_handle->err = globus_object_copy(error);
          }
          client_handle->state = GLOBUS_FTP_CLIENT_HANDLE_FAILURE;

          goto notify_fault;
      }
      else if(response->response_class ==
            GLOBUS_FTP_POSITIVE_PRELIMINARY_REPLY)
      {
          if(response->code == 111)
          {
            globus_l_ftp_client_parse_restart_marker(client_handle,
                                           response);
          }
          break;
      }
        else
        {
            if(response->response_class != GLOBUS_FTP_POSITIVE_COMPLETION_REPLY
                && client_handle->err == GLOBUS_SUCCESS)
            {
                /* any other response must be a transient error such as 
                 * 426 data timeout
                 */
                client_handle->err = 
                    GLOBUS_I_FTP_CLIENT_ERROR_RESPONSE(response);
            }
            
            if(target->state == GLOBUS_FTP_CLIENT_TARGET_NEED_EMPTY_AND_COMPLETE)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_EMPTY_QUEUE;
            }
            else
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_NEED_LAST_BLOCK;
            }
        }
      
      break;

    case GLOBUS_FTP_CLIENT_TARGET_NEED_COMPLETE:
      /* Reset the state to setup_connection, so that the url
       * caching code knows to keep this one around.
       */
      if(!error)
      {
          if(response->response_class ==
             GLOBUS_FTP_POSITIVE_PRELIMINARY_REPLY)
          {
            if(response->code == 111)
            {
                globus_l_ftp_client_parse_restart_marker(client_handle,
                                               response);
            }
            break;
          }
          else
          {
            target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;

            if(response->response_class !=
               GLOBUS_FTP_POSITIVE_COMPLETION_REPLY)
            {
                if(client_handle->err == GLOBUS_SUCCESS)
                {
                  client_handle->err =
                      GLOBUS_I_FTP_CLIENT_ERROR_RESPONSE(response);
                }
                if(client_handle->op != GLOBUS_FTP_CLIENT_MDTM &&
                   client_handle->op != GLOBUS_FTP_CLIENT_SIZE &&
                   client_handle->op != GLOBUS_FTP_CLIENT_FEAT &&
                   client_handle->op != GLOBUS_FTP_CLIENT_CKSM &&
                   client_handle->op != GLOBUS_FTP_CLIENT_MLST &&
                   client_handle->op != GLOBUS_FTP_CLIENT_CWD &&
                   client_handle->op != GLOBUS_FTP_CLIENT_STAT)
                {
                  client_handle->state =
                      GLOBUS_FTP_CLIENT_HANDLE_FAILURE;
                }
            }
            if(client_handle->op == GLOBUS_FTP_CLIENT_MDTM &&
               response->code == 213)
            {
                globus_l_ftp_client_parse_mdtm(client_handle,
                                             response);
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_SIZE &&
                  response->code == 213)
            {
                globus_libc_scan_off_t((char *) response->response_buffer+4,
                                 client_handle->size_pointer,
                                 GLOBUS_NULL);
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_CKSM &&
                  response->code == 213)
            {
                globus_l_ftp_client_parse_cksm(client_handle,
                                       response);
                                       
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_FEAT)
            {
                for(i = 0; i < GLOBUS_FTP_CLIENT_FEATURE_MAX; i++)
                    {
                        globus_i_ftp_client_feature_set(
                            client_handle->features_pointer,
                            i,
                            globus_i_ftp_client_feature_get(
                                target->features, i));
                    }
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_CWD &&
                  response->code == 250)
            {
                globus_l_ftp_client_parse_cwd(client_handle,
                                      response);
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_MLST &&
                  response->code == 250)
            {
                globus_l_ftp_client_parse_mlst(client_handle,
                                             response);
            }
            else if(client_handle->op == GLOBUS_FTP_CLIENT_STAT)
            {
                globus_l_ftp_client_parse_stat(client_handle,
                                             response);
            }
          }
      }
      else
      {
          target->state = GLOBUS_FTP_CLIENT_TARGET_SETUP_CONNECTION;
          if(client_handle->err == GLOBUS_SUCCESS)
          {
            client_handle->err = globus_object_copy(error);
          }
      }
      
      globus_i_ftp_client_transfer_complete(client_handle);
      
      goto do_return;

      break;

    case GLOBUS_FTP_CLIENT_TARGET_FAULT:
    case GLOBUS_FTP_CLIENT_TARGET_CLOSED:
      /*
       * This state only happens if this is a callback which was a
       * result of a force_close. We do nothing, and the force_close
       * callback deals with the failure.
       */
      break;
    case GLOBUS_FTP_CLIENT_TARGET_NOOP:
      globus_assert(
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_SOURCE_SETUP_CONNECTION ||
          client_handle->state ==
          GLOBUS_FTP_CLIENT_HANDLE_DEST_SETUP_CONNECTION);
        
        /* response will be NULL if the NOOP was faked */
      if((!error) && (!response ||
         response->response_class == GLOBUS_FTP_POSITIVE_COMPLETION_REPLY))
      {
          /* NOOP successful, we can re-use this target */
          target->state =
            GLOBUS_FTP_CLIENT_TARGET_SETUP_TYPE;
          goto redo;
      }
      else
      {
          globus_i_ftp_client_target_t *        new_target;
          /*
           * NOOP failed---This means that the cached target went
           * bad. We'll discard this target, and find a new
           * one.
           */
          globus_assert(client_handle->source == target ||
                    client_handle->dest == target);

          if(client_handle->source == target)
          {
            error =
                globus_i_ftp_client_target_find(client_handle,
                                        client_handle->source_url,
                                        target->attr,
                                        &new_target);
            if(error != GLOBUS_SUCCESS)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_FAULT;

                goto notify_fault;
            }
            client_handle->source = new_target;
          }
          else if(client_handle->dest == target)
          {
            error =
                globus_i_ftp_client_target_find(client_handle,
                                        client_handle->dest_url,
                                        target->attr,
                                        &new_target);

            if(error != GLOBUS_SUCCESS)
            {
                target->state = GLOBUS_FTP_CLIENT_TARGET_FAULT;

                goto notify_fault;
            }
            client_handle->dest = new_target;
          }

          /* Mark the old target for destruction... */
          target->state = GLOBUS_FTP_CLIENT_TARGET_FAULT;
          /* And release it */
          globus_i_ftp_client_target_release(client_handle,
                                     target);

          /* Start this new target off */
          error = globus_i_ftp_client_target_activate(client_handle,
                                          new_target,
                                          &registered);

          if(registered == GLOBUS_FALSE)
          {
            globus_assert(error ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                  client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE);
            /*
             * A restart or abort happened during activation, before any
             * callbacks were registered. We must deal with them here.
             */
            if(client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_ABORT ||
                client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_RESTART ||
                  client_handle->state == GLOBUS_FTP_CLIENT_HANDLE_FAILURE)
            {
                break;
            }
            else if(error != GLOBUS_SUCCESS)
            {
                globus_i_ftp_client_plugin_notify_fault(
                  client_handle,
                  target->url_string,
                  error);
                    
                goto connection_error;
            }
          }
      }
      break;
    default:
      globus_assert(0 && "Invalid state");
    }
 finish:
    globus_i_ftp_client_handle_unlock(client_handle);
 do_return:   
    
    if(error)
    {
        globus_object_free(error);
    }
    globus_i_ftp_client_debug_printf(1, (stderr, 
        "globus_i_ftp_client_response_callback() exiting\n"));
    globus_i_ftp_client_debug_states(2, client_handle);

    return;

 result_fault:
    if(error)
    {
        globus_object_free(error);
    }
    error = globus_error_get(result);
 notify_fault:
    globus_i_ftp_client_plugin_notify_fault(
      client_handle,
      target->url_string,
      error);
 connection_error:
    globus_l_ftp_client_connection_error(client_handle,
                               target,
                               error,
                               response);
    
    globus_object_free(error);
    globus_i_ftp_client_debug_printf(1, (stderr, 
        "globus_i_ftp_client_response_callback() exiting with error\n"));
    globus_i_ftp_client_debug_states(2, client_handle);

    return;
}


Generated by  Doxygen 1.6.0   Back to index