/**
 * Create a copy of a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function copies the contents of marker to new_marker.
 *
 * @param new_marker
 *        A pointer to a new restart marker.
 * @param marker
 *        The marker to copy.
 *
 * @see globus_ftp_client_restart_marker_init(),
 * globus_ftp_client_restart_marker_destroy()
 */
globus_result_t
globus_ftp_client_restart_marker_copy(
    globus_ftp_client_restart_marker_t *	new_marker,
    globus_ftp_client_restart_marker_t *	marker)
{
    globus_fifo_t * tmp;
    GlobusFuncName(globus_ftp_client_restart_marker_copy);

    if(new_marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("new_marker"));
    }
    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }

    globus_ftp_client_restart_marker_init(new_marker);

    new_marker->type = marker->type;

    switch(new_marker->type)
    {
    case GLOBUS_FTP_CLIENT_RESTART_NONE:
	break;
    case GLOBUS_FTP_CLIENT_RESTART_STREAM:
	new_marker->stream.offset = marker->stream.offset;
	break;
    case GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK:

	globus_fifo_init(&new_marker->extended_block.ranges);

	if(globus_fifo_empty(&marker->extended_block.ranges))
	{
	    break;
	}
	tmp = globus_fifo_copy(&marker->extended_block.ranges);

	while(!globus_fifo_empty(tmp))
	{
	    globus_i_ftp_client_range_t *	range;

	    range = (globus_i_ftp_client_range_t *) globus_fifo_dequeue(tmp);

	    globus_ftp_client_restart_marker_insert_range(new_marker,
							  range->offset,
							  range->end_offset);
	}
	
	globus_fifo_destroy(tmp);
	globus_free(tmp);
	break;
    }
    return GLOBUS_SUCCESS;
}
/**
 * Get total bytes accounted for in restart marker
 * @ingroup globus_ftp_client_restart_marker
 *
 * This funtion will return the sum of all bytes accounted for in
 * a restart marker.  If this restart marker contains a stream offset
 * then this value is the same as the offset (not the ascii offset)
 * that it was set with.  If it is a range list, it a sum of all the
 * bytes in the ranges.
 *
 * @param marker
 *        A previously initialized or copied restart marker
 *
 * @param total_bytes
 *        pointer to storage for total bytes in marker
 *
 * @return
 *        - Error on NULL marker or total bytes
 *        - <possible return>
 */
globus_result_t
globus_ftp_client_restart_marker_get_total(
    globus_ftp_client_restart_marker_t *	marker,
    globus_off_t *				total_bytes)
{
    GlobusFuncName(globus_ftp_client_restart_marker_get_total);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }

    if(total_bytes == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("total_bytes"));
    }

    *total_bytes = 0;

    if(marker->type == GLOBUS_FTP_CLIENT_RESTART_STREAM)
    {
        *total_bytes = marker->stream.offset;
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK &&
            !globus_fifo_empty(&marker->extended_block.ranges))
    {
        globus_fifo_t *			        tmp;
        globus_off_t			        total;
        globus_i_ftp_client_range_t *           range;

        tmp = globus_fifo_copy(&marker->extended_block.ranges);
        total = 0;

        while((!globus_fifo_empty(tmp)))
        {
	    range = (globus_i_ftp_client_range_t *) globus_fifo_dequeue(tmp);

            total += range->end_offset - range->offset;
        }

        *total_bytes = total;
        globus_fifo_destroy(tmp);
        globus_libc_free(tmp);
    }

    return GLOBUS_SUCCESS;

}
globus_result_t
globus_ftp_client_restart_marker_get_first_block(
    globus_ftp_client_restart_marker_t *        marker,
    globus_off_t *                              start_offset,
    globus_off_t *                              end_offset)
{
    GlobusFuncName(globus_ftp_client_restart_marker_get_first_block);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
                GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }

    if(start_offset == GLOBUS_NULL)
    {
        return globus_error_put(
                GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("start_offset"));
    }

    if(end_offset == GLOBUS_NULL)
    {
        return globus_error_put(
                GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("end_offset"));
    }

    *start_offset = 0;
    *end_offset = 0;
    
    if(marker->type == GLOBUS_FTP_CLIENT_RESTART_STREAM)
    {
        *end_offset = marker->stream.offset;
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK &&
            !globus_fifo_empty(&marker->extended_block.ranges))
    {
        globus_i_ftp_client_range_t *           range;

        range = (globus_i_ftp_client_range_t *) 
            globus_fifo_peek(&marker->extended_block.ranges);
        
        *start_offset = range->offset;
        *end_offset = range->end_offset;
    }

    return GLOBUS_SUCCESS;

}
static
globus_result_t
globus_l_net_manager_python_handle_exception(
    const char                         *func_name)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    PyObject                           *exception = NULL,
                                       *exception_string = NULL;
    const char                         *exception_cstr = NULL;

    exception = PyErr_Occurred();
    if (exception != NULL)
    {
        result = GLOBUS_FAILURE;

        exception_string = PyObject_Str(exception);
        if (exception_string)
        {
            exception_cstr = PyString_AsString(exception_string);
            if (exception_cstr)
            {
                result = globus_error_put(
                        globus_error_construct_string(
                            &globus_net_manager_python_module,
                            NULL,
                            "Python Exception in %s: %s",
                            func_name,
                            exception_cstr));
            }
            Py_DECREF(exception_string);
        }
    }
    return result;
}
/**
 * Destroy a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * @param marker
 *        Restart marker. This marker must be initialized by either
 *        calling globus_ftp_client_restart_marker_init() or
 *        globus_ftp_client_restart_marker_copy()
 *
 * @see globus_ftp_client_restart_marker_t,
 * globus_ftp_client_restart_marker_init(),
 * globus_ftp_client_restart_marker_copy()
 */
globus_result_t
globus_ftp_client_restart_marker_destroy(
    globus_ftp_client_restart_marker_t *	marker)
{
    GlobusFuncName(globus_ftp_client_restart_marker_destroy);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }

    switch(marker->type)
    {
    case GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK:
	while(!globus_fifo_empty(&marker->extended_block.ranges))
	{
	    globus_i_ftp_client_range_t *	range;

	    range = (globus_i_ftp_client_range_t *)
		globus_fifo_dequeue(&marker->extended_block.ranges);

	    globus_libc_free(range);
	}
	globus_fifo_destroy(&marker->extended_block.ranges);
    /* FALLSTHROUGH */
    case GLOBUS_FTP_CLIENT_RESTART_NONE:
    case GLOBUS_FTP_CLIENT_RESTART_STREAM:
	memset(marker, '\0', sizeof(globus_ftp_client_restart_marker_t));
	marker->type = GLOBUS_FTP_CLIENT_RESTART_NONE;

	break;
    }
    return GLOBUS_SUCCESS;
}
static
void
globus_l_xio_win32_socket_kickout(
    void *                              user_arg)
{
    globus_i_xio_system_op_info_t *     op_info;
    SOCKET                              fd;
    GlobusXIOName(globus_l_xio_win32_socket_kickout);

    op_info = (globus_i_xio_system_op_info_t *) user_arg;
    fd = op_info->handle->socket;
    
    GlobusXIOSystemDebugEnterFD(fd);

    if(op_info->op)
    {
        globus_xio_operation_disable_cancel(op_info->op);
    }
    
    switch(op_info->type)
    {
      case GLOBUS_I_XIO_SYSTEM_OP_CONNECT:
      case GLOBUS_I_XIO_SYSTEM_OP_ACCEPT:
        op_info->sop.non_data.callback(
            op_info->error ? globus_error_put(op_info->error) : GLOBUS_SUCCESS,
            op_info->user_arg);
        break;

      default:
        op_info->sop.data.callback(
            op_info->error ? globus_error_put(op_info->error) : GLOBUS_SUCCESS,
            op_info->nbytes,
            op_info->user_arg);
            
        GlobusIXIOSystemFreeIovec(
            op_info->sop.data.start_iovc,
            op_info->sop.data.start_iov);
        break;
    }
    
    GlobusIXIOSystemFreeOperation(op_info);
    GlobusXIOSystemDebugExitFD(fd);
}
globus_result_t
globus_i_gsi_cred_error_join_chains_result(
    globus_result_t                     outter_error,
    globus_result_t                     inner_error)
{
    globus_result_t                     result;
    globus_object_t *                   result_error_obj = NULL;
    globus_object_t *                   outter_error_obj = NULL;
    globus_object_t *                   inner_error_obj = NULL;
    globus_object_t *                   temp_error_obj = NULL;
    static char *                       _function_name_ =
        "globus_i_gsi_cred_error_join_chains";
    GLOBUS_I_GSI_CRED_DEBUG_ENTER;

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

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

    result = globus_error_put(result_error_obj);

    GLOBUS_I_GSI_CRED_DEBUG_EXIT;
    return result;
}
/**
 * This function initializes a globus_gsi_callback_data_t.
 * @ingroup globus_gsi_callback_data
 *
 * @param callback_data
 *        Reference to the structure to be initialized
 *
 * @return
 *        GLOBUS_SUCCESS unless an error occurred, in which case, 
 *        a globus error object ID is returned
 */
globus_result_t
globus_gsi_callback_data_init(
    globus_gsi_callback_data_t *        callback_data)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    static char *                       _function_name_ =
        "globus_gsi_callback_data_init";

    GLOBUS_I_GSI_CALLBACK_DEBUG_ENTER;

    if(callback_data == NULL)
    {
        GLOBUS_GSI_CALLBACK_ERROR_RESULT(
            result,
            GLOBUS_GSI_CALLBACK_ERROR_CALLBACK_DATA,
            (_CLS("NULL pointer to callback_data passed to function: %s"),
             _function_name_));
        goto exit;
    }

    *callback_data = malloc(sizeof(globus_i_gsi_callback_data_t));
    if(*callback_data == NULL)
    {
        result = globus_error_put(
            globus_error_wrap_errno_error(
                GLOBUS_GSI_CALLBACK_MODULE,
                errno,
                GLOBUS_GSI_CALLBACK_ERROR_ERRNO,
                __FILE__,
                _function_name_,
                __LINE__,
                "Error allocating space (malloc) for callback data"));
        goto exit;
    }

    memset(*callback_data, 0, sizeof(globus_i_gsi_callback_data_t));

    (*callback_data)->max_proxy_depth = -1;
    
    (*callback_data)->cert_type = GLOBUS_GSI_CERT_UTILS_TYPE_EEC;

    (*callback_data)->cert_chain = sk_X509_new_null();

    (*callback_data)->error = GLOBUS_SUCCESS;

    (*callback_data)->check_self_signed_policy = GLOBUS_FALSE;

 exit:
    GLOBUS_I_GSI_CALLBACK_DEBUG_EXIT;
    return result;
}
/**
 * Initialize a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * @param marker
 *        New restart marker.
 * @see globus_ftp_client_restart_marker_t,
 * globus_ftp_client_restart_marker_destroy()
 */
globus_result_t
globus_ftp_client_restart_marker_init(
    globus_ftp_client_restart_marker_t *	marker)
{
    GlobusFuncName(globus_ftp_client_restart_marker_init);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }

    memset(marker, '\0', sizeof(globus_ftp_client_restart_marker_t));
    marker->type = GLOBUS_FTP_CLIENT_RESTART_NONE;

    return GLOBUS_SUCCESS;
}
예제 #10
0
static
void
gfork_l_child_read_close_cb(
    globus_xio_handle_t                 xio_handle,
    globus_result_t                     result,
    void *                              user_arg)
{
    gfork_i_lib_handle_t *              handle;
    globus_result_t                     user_res;

    handle = (gfork_i_lib_handle_t *) user_arg;

    user_res = globus_error_put(handle->error_obj);
    handle->error_cb(handle, handle->user_arg, user_res);

    globus_mutex_destroy(&handle->mutex);
    globus_free(handle);
}
globus_result_t
globus_ftp_client_restart_marker_plugin_destroy(
    globus_ftp_client_plugin_t *                    plugin)
{
    globus_result_t                                 result;
    restart_marker_plugin_info_t *                  ps;
    GlobusFuncName(globus_ftp_client_restart_marker_plugin_destroy);

    if(plugin == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] NULL plugin at %s\n",
            GLOBUS_FTP_CLIENT_MODULE->module_name,
            _globus_func_name));
    }

    result = globus_ftp_client_plugin_get_plugin_specific(
        plugin,
        (void **) (void *) &ps);

    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    if(ps->error_obj)
    {
        globus_object_free(ps->error_obj);
        ps->error_obj = GLOBUS_NULL;
    }

    if(ps->error_url)
    {
        globus_libc_free(ps->error_url);
        ps->error_url = GLOBUS_NULL;
    }

    globus_mutex_destroy(&ps->lock);
    globus_free(ps);

    return globus_ftp_client_plugin_destroy(plugin);
}
예제 #12
0
globus_result_t
globus_i_gsi_gssapi_error_chain_result(
    globus_result_t                     chain_result,
    int                                 error_type,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_result_t                     result;
    globus_object_t *                   error_object;
    
    static char *                       _function_name_ =
        "globus_i_gsi_gssapi_error_chain_result";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

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

    result = globus_error_put(error_object);

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

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

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_CERT_UTILS_DEBUG_EXIT;

    return result;
}
/**
 * Set the offset for a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function modifies a restart marker to contain a stream offset,
 * suitable for using to restart a steam mode transfer.
 *
 * The marker must first be initialized by calling
 * globus_ftp_client_restart_marker_init() or
 * globus_ftp_client_restart_marker_copy().
 *
 * A marker can only hold a range list or a stream offset. Calling
 * this function after calling
 * globus_ftp_client_restart_marker_insert_range() will delete the
 * ranges associated with the marker, and replace it with a marker
 * suitable only for use restarting a stream mode transfer.
 *
 * When restarting an ASCII type transfer, the offset must take into
 * account the additional carriage return characters added to the data
 * stream.
 *
 * @param marker
 *        A restart marker
 * @param offset
 *        The stream offset
 *
 * @see globus_ftp_client_restart_marker_insert_range(),
 * globus_ftp_client_operationattr_set_mode(),
 * globus_ftp_client_operationattr_set_type()
 */
globus_result_t
globus_ftp_client_restart_marker_set_offset(
    globus_ftp_client_restart_marker_t *	marker,
    globus_off_t				offset)
{
    GlobusFuncName(globus_ftp_client_restart_marker_set_offset);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }
    if(marker->type != GLOBUS_FTP_CLIENT_RESTART_STREAM)
    {
        globus_ftp_client_restart_marker_destroy(marker);
	marker->type = GLOBUS_FTP_CLIENT_RESTART_STREAM;
    }
    marker->stream.offset = marker->stream.ascii_offset = offset;

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

    static char *                       _function_name_ =
        "globus_i_gsi_cred_error_result";

    GLOBUS_I_GSI_CRED_DEBUG_ENTER;

    error_object = globus_error_construct_error(
        GLOBUS_GSI_CREDENTIAL_MODULE,
        NULL,
        error_type,
        filename,
        function_name,
        line_number, 
        "%s%s%s",
        _GCRSL(globus_l_gsi_cred_error_strings[error_type]),
        short_desc ? ": " : "",
        short_desc ? short_desc : "");

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_CRED_DEBUG_EXIT;

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

    static char *                       _function_name_ =
        "globus_i_gsi_sysconfig_openssl_error_result";
    
    GLOBUS_I_GSI_SYSCONFIG_DEBUG_ENTER;

    error_object = 
        globus_error_wrap_openssl_error(
            GLOBUS_GSI_SYSCONFIG_MODULE,
            error_type,
            filename,
            function_name,
            line_number,
            "%s%s%s",
            _GSSL(globus_l_gsi_sysconfig_error_strings[error_type]),
            short_desc ? ": " : "",
            short_desc ? short_desc : "");    

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

    result = globus_error_put(error_object);
    
    GLOBUS_I_GSI_SYSCONFIG_DEBUG_EXIT;

    return result;
}
예제 #17
0
globus_result_t
globus_i_gsi_gssapi_error_result(
    const OM_uint32                     minor_status,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_object_t *                   error_object;
    globus_result_t                     result;

    static char *                       _function_name_ =
        "globus_i_gsi_gssapi_error_result";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    error_object =
        globus_error_construct_error(
            GLOBUS_GSI_GSSAPI_MODULE,
            NULL,
            GLOBUS_GSI_GSSAPI_ERROR_MINOR_STATUS(minor_status),
            filename,
            function_name,
            line_number, 
            "%s%s%s",
            globus_l_gsi_gssapi_error_strings[minor_status],
            short_desc ? ": " : "",
            short_desc ? short_desc : "");

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_GSSAPI_INTERNAL_DEBUG_EXIT;
    return result;
}
예제 #18
0
/**
 * Retrieve the minor status from a gssapi error object.
 * @ingroup globus_gssapi_error_accessor  
 *
 * @param error
 *        The error from which to retrieve the minor status
 * @return
 *        The minor status stored in the object
 */
OM_uint32
globus_error_gssapi_get_minor_status(
    globus_object_t *                   error)
{
    globus_l_gssapi_error_data_t *      data;
    
    data = (globus_l_gssapi_error_data_t *)
        globus_object_get_local_instance_data(error);
    if(data)
    {
        if(data->is_globus_gsi)
        {
            return (OM_uint32) globus_error_put(
                globus_object_copy(globus_error_get_cause(error)));
        }
        else
        {
            return data->minor_status;
        }
    }
    
    return 0;
}
static
globus_result_t
globus_l_xio_win32_socket_register_write(
    globus_l_xio_win32_socket_t *       handle,
    globus_i_xio_system_op_info_t *     write_info)
{
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_win32_socket_register_write);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);
    
    /* I have to do this outside the lock because of lock inversion issues */
    if(write_info->op && globus_xio_operation_enable_cancel(
        write_info->op, globus_l_xio_win32_socket_cancel_cb, write_info))
    {
        result = GlobusXIOErrorCanceled();
        goto error_cancel_enable;
    }

    win32_mutex_lock(&handle->lock);
    {
        if(write_info->state == GLOBUS_I_XIO_SYSTEM_OP_CANCELED)
        {
            result = globus_error_put(write_info->error);
            goto error_canceled;
        }

        if(handle->write_info)
        {
            result = GlobusXIOErrorAlreadyRegistered();
            goto error_already_registered;
        }
        
        write_info->state = GLOBUS_I_XIO_SYSTEM_OP_PENDING;
        /* if select() functionality requested, only handle after we receive
         * write event
         * 
         * also dont call for connect operations.  waitforbytes == 0 in this
         * case and handle->ready_events should not yet have a write event
         */
        if(write_info->waitforbytes > 0 || handle->ready_events & FD_WRITE)
        {
            globus_l_xio_win32_socket_handle_write(handle, write_info);
        }
        
        if(write_info->state != GLOBUS_I_XIO_SYSTEM_OP_COMPLETE)
        {
            /* make sure we're set up to be notified of events */
            long needevents;
            
            if(write_info->type == GLOBUS_I_XIO_SYSTEM_OP_CONNECT)
            {
                needevents = FD_CONNECT|FD_CLOSE;
            }
            else
            {
                needevents = FD_WRITE|FD_CLOSE;
            }
            
            if((handle->eventselect & needevents) != needevents)
            {
                if(WSAEventSelect(
                    handle->socket, handle->event,
                    handle->eventselect|needevents) == SOCKET_ERROR)
                {
                    write_info->error = GlobusXIOErrorObjSystemError(
                        "WSAEventSelect", WSAGetLastError());
                }
                else
                {
                    handle->eventselect |= needevents;
                }
            }
            
            if(!write_info->error)
            {
                handle->write_info = write_info;
                write_info = 0;
            }
        }
    }
    win32_mutex_unlock(&handle->lock);
    
    /* do this outside the lock to avoid unnecessary contention */
    if(write_info)
    {
        globus_l_xio_win32_socket_complete(write_info, GLOBUS_FALSE);
    }

    GlobusXIOSystemDebugExitFD(handle->socket);
    return GLOBUS_SUCCESS;

error_already_registered:
error_canceled:
    write_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE;
    win32_mutex_unlock(&handle->lock);
    if(write_info->op)
    {
        globus_xio_operation_disable_cancel(write_info->op);
    }
error_cancel_enable:
    GlobusXIOSystemDebugExitWithErrorFD(handle->socket);
    return result;
}
globus_result_t
globus_xio_system_socket_write(
    globus_xio_system_socket_handle_t   handle,
    const globus_xio_iovec_t *          iov,
    int                                 iovc,
    globus_size_t                       waitforbytes,
    int                                 flags,
    globus_sockaddr_t *                 to,
    globus_size_t *                     nbytes)
{
    globus_result_t                     result;
    globus_l_xio_win32_blocking_info_t * blocking_info;
    GlobusXIOName(globus_xio_system_socket_write);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);
    GlobusXIOSystemDebugPrintf(
        GLOBUS_I_XIO_SYSTEM_DEBUG_DATA,
        ("[%s] Waiting for %ld bytes\n", _xio_name, (long) waitforbytes));
    
    win32_mutex_lock(&handle->lock);
    {
        result = globus_i_xio_system_socket_try_write(
            handle->socket,
            iov,
            iovc,
            flags,
            to,
            nbytes);
    }
    win32_mutex_unlock(&handle->lock);
    
    if(result == GLOBUS_SUCCESS && *nbytes < waitforbytes)
    {
        result = globus_l_xio_win32_blocking_init(&blocking_info);
        if(result != GLOBUS_SUCCESS)
        {
            result = GlobusXIOErrorWrapFailed(
                "globus_l_xio_win32_blocking_init", result);
            goto error_init;
        }
        
        result = globus_l_xio_system_socket_register_write(
            0,
            handle,
            iov,
            iovc,
            waitforbytes,
            *nbytes,
            flags,
            to,
            globus_l_xio_win32_blocking_cb,
            blocking_info);
        if(result != GLOBUS_SUCCESS)
        {
            result = GlobusXIOErrorWrapFailed(
                "globus_l_xio_system_socket_register_write", result);
            goto error_register;
        }
        
        while(WaitForSingleObject(
            blocking_info->event, INFINITE) != WAIT_OBJECT_0) {}
        
        if(blocking_info->error)
        {
            result = globus_error_put(blocking_info->error);
        }
        *nbytes = blocking_info->nbytes;
        
        globus_l_xio_win32_blocking_destroy(blocking_info);
    }

    GlobusXIOSystemDebugExitFD(handle->socket);
    return result;

error_register:
    globus_l_xio_win32_blocking_destroy(blocking_info);
error_init:
    GlobusXIOSystemDebugExitWithErrorFD(handle->socket);
    return result;
}
예제 #21
0
static
globus_result_t
globus_l_extension_get_module(
    lt_dlhandle                         dlhandle,
    const char *                        module_name,
    globus_module_descriptor_t **       module_desc)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_module_descriptor_t *        module;
    GlobusFuncName(globus_l_extension_get_module);
    
    module = (globus_module_descriptor_t *)
        lt_dlsym(dlhandle, "globus_extension_module");

    if(!module)
    {
        char * module_descriptor_name = malloc(strlen(module_name) + 8);
        const char * p = module_name;
        const char * last_slash = module_name;

        if (module_descriptor_name == NULL)
        {
            result = GLOBUS_FAILURE;
        }

        while (*p != '\0')
        {
            if (*p == '/')
            {
                last_slash = p+1;
            }
            p++;
        }


        sprintf(module_descriptor_name, "%s_module", last_slash);

        module = (globus_module_descriptor_t *)
            lt_dlsym(dlhandle, module_descriptor_name);

        free(module_descriptor_name);
    }

    if (!module)
    {
        const char *                    error;
        
        error = lt_dlerror();
        
        GlobusExtensionDebugPrintf(
            GLOBUS_L_EXTENSION_DEBUG_DLL,
            (_GCSL("[%s] Couldn't find module descriptor : %s\n"),
                _globus_func_name, error ? error : "(null)"));
        result = globus_error_put(
            globus_error_construct_error(
                GLOBUS_EXTENSION_MODULE,
                NULL,
                GLOBUS_EXTENSION_ERROR_LOOKUP_FAILED,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Couldn't find module descriptor : %s\n",
                error ? error : "(null)"));
    }
    
    *module_desc = module;
    return result;
}
예제 #22
0
/**
 * @brief Wrap
 * @ingroup globus_gsi_gss_assist
 *
 * @param minor_status
 *        GSSAPI return code.  If the call was successful, the minor 
 *        status is equal to GLOBUS_SUCCESS.  Otherwise, it is an
 *        error object ID for which  
 *        globus_error_get() and globus_object_free()
 *        can be used to get and destroy it.
 * @param context_handle
 *        the context. 
 * @param data
 *        pointer to application data to wrap and send
 * @param length
 *        length of the @a data array
 * @param token_status
 *        assist routine get/send token status 
 * @param gss_assist_send_token
 *        a send_token routine 
 * @param gss_assist_send_context
 *        first arg for the send_token
 * @param fperr
 *        file handle to write error message to.
 *
 * @return
 *        GSS_S_COMPLETE on success
 *        Other GSSAPI errors on failure.  
 *
 * @see gss_wrap()
 */
OM_uint32
globus_gss_assist_wrap_send(
    OM_uint32 *                         minor_status,
    const gss_ctx_id_t                  context_handle,
    char *			        data,
    size_t			        length,
    int *			        token_status,
    int (*gss_assist_send_token)(void *, void *, size_t),
    void *                              gss_assist_send_context,
    FILE *                              fperr)
{
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    globus_result_t                     local_result = GLOBUS_SUCCESS;
    gss_buffer_desc                     input_token_desc  = GSS_C_EMPTY_BUFFER;
    gss_buffer_t                        input_token       = &input_token_desc;
    gss_buffer_desc                     output_token_desc = GSS_C_EMPTY_BUFFER;
    gss_buffer_t                        output_token      = &output_token_desc;
    static char *                       _function_name_ =
        "globus_gss_assist_wrap_send";
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;

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

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

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

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

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

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

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

    goto exit;

 release_output_token:

    gss_release_buffer(&local_minor_status,
                       output_token);

 exit:
    
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
    return major_status;
}
예제 #23
0
int
globus_extension_activate(
    const char *                        extension_name)
{
    globus_l_extension_module_t *       extension;
    globus_l_extension_module_t *       last_extension;
    globus_l_extension_builtin_t *      builtin;
    int                                 rc;
    globus_result_t                     result = GLOBUS_FAILURE;
    GlobusFuncName(globus_extension_activate);
    
    GlobusExtensionDebugEnterSymbol(extension_name);
    
    if(!extension_name)
    {
        goto error_param;
    }
    
    globus_rmutex_lock(&globus_l_extension_mutex);
    {
        extension = (globus_l_extension_module_t *)
            globus_hashtable_lookup(
                &globus_l_extension_loaded, (void *) extension_name);
        if(!extension)
        {
            extension = (globus_l_extension_module_t *)
                globus_malloc(sizeof(globus_l_extension_module_t));
            if(!extension)
            {
                goto error_alloc;
            }
            
            extension->module_ref = 1;
            extension->ref = 1;
            extension->name = globus_libc_strdup(extension_name);
            if(!extension->name)
            {
                goto error_strdup;
            }
            
            builtin = (globus_l_extension_builtin_t *)
                globus_hashtable_lookup(
                    &globus_l_extension_builtins, (void *) extension_name);
            if(builtin && (!builtin->owner || builtin->owner->module_ref > 0))
            {
#               if !defined(BUILD_STATIC_ONLY)
                {

                    extension->dlhandle = NULL;
                }
#               endif
                extension->module = builtin->module;
                extension->owner = builtin->owner;
                if(extension->owner)
                {
                    extension->owner->ref++;
                }
            }
            else
            {
                extension->owner = NULL;

#               if !defined(BUILD_STATIC_ONLY)
                {

                    result =   
                        globus_l_extension_dlopen(
                            extension->name,
                            &extension->dlhandle);
                    if(result != GLOBUS_SUCCESS)
                    {
                        goto error_dll;
                    }
                    
                    result =
                       globus_l_extension_get_module(
                           extension->dlhandle,
                           extension_name,
                           &extension->module);

                }
#               else
                {
                    globus_assert(BUILD_STATIC_ONLY == 0);
                    result = globus_error_put(
                        globus_error_construct_error(
                            GLOBUS_EXTENSION_MODULE,
                            NULL,
                            GLOBUS_EXTENSION_ERROR_OPEN_FAILED,
                            __FILE__,
                            _globus_func_name,
                            __LINE__,
                            "No support for dynamically loading %s\n",
                            extension->name));
                }
#               endif /* !defined(BUILD_STATIC_ONLY) */

                if(result != GLOBUS_SUCCESS)
                {
                    goto error_module;
                }
            }
            
            globus_hashtable_insert(
                &globus_l_extension_loaded,
                extension->name,
                extension);
                
            last_extension = (globus_l_extension_module_t *)
                globus_thread_getspecific(globus_l_extension_owner_key);
            globus_thread_setspecific(globus_l_extension_owner_key, extension);
            
#if USE_SYMBOL_LABELS
            {
                int pre_warned = WARNING_USING_MIXED_THREAD_MODELS;
#endif
            rc = globus_module_activate_proxy(
                extension->module,
                globus_l_extension_deactivate_proxy,
                extension);
#if USE_SYMBOL_LABELS
                if ((!pre_warned) && WARNING_USING_MIXED_THREAD_MODELS)
                {
                    GlobusExtensionDebugPrintf(
                        GLOBUS_L_EXTENSION_DEBUG_VERBOSE,
                        (_GCSL("[%s] Warning: extension %s was compiled with pthreads for GT 5.0.x and may not work correctly\n"),
                            _globus_func_name,
                            extension->name));

                }
            }
#endif
            
            globus_thread_setspecific(
                globus_l_extension_owner_key, last_extension);
            if(rc != GLOBUS_SUCCESS)
            {
                goto error_activate;
            }
        }
        else
        {
            extension->module_ref++;
            extension->ref++;
        }
    }
    globus_rmutex_unlock(&globus_l_extension_mutex);
    
    GlobusExtensionDebugExit();
    return GLOBUS_SUCCESS;

error_activate:
    globus_hashtable_remove(
        &globus_l_extension_loaded, extension->name);
    if(builtin && builtin->owner)
    {
        builtin->owner->ref--;
    }
error_module:
#ifndef BUILD_STATIC_ONLY
    if(extension->dlhandle)
    {
        lt_dlclose(extension->dlhandle);
    }
error_dll:
#endif /* !BUILD_STATIC_ONLY */
    globus_free(extension->name);
error_strdup:
    globus_free(extension);
error_alloc:
    globus_rmutex_unlock(&globus_l_extension_mutex);
error_param:
    GlobusExtensionDebugExitWithError();
    return result;
}
/**
 * Insert a range into a restart marker
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function updates a restart marker with a new byte range,
 * suitable for using to restart an extended block mode transfer.
 * Adjacent ranges within the marker will be combined into a single
 * entry in the marker.
 *
 * The marker must first be initialized by calling
 * globus_ftp_client_restart_marker_init() or
 * globus_ftp_client_restart_marker_copy().
 *
 * A marker can only hold a range list or a stream offset. Calling
 * this function after calling
 * globus_ftp_client_restart_marker_set_offset() will result in a marker
 * suitable only for use restarting an extended block mode transfer.
 *
 * @param marker
 *        A restart marker
 * @param offset
 *        The starting offset of the range.
 * @param end_offset
 *        The ending offset of the range.
 *
 * @see globus_ftp_client_restart_marker_set_offset()
 * globus_ftp_client_operationattr_set_mode()
 */
globus_result_t
globus_ftp_client_restart_marker_insert_range(
    globus_ftp_client_restart_marker_t *	marker,
    globus_off_t				offset,
    globus_off_t				end_offset)
{
    globus_fifo_t				tmp;
    globus_i_ftp_client_range_t *		range;
    globus_i_ftp_client_range_t *		newrange;
    globus_object_t *				err = GLOBUS_SUCCESS;
    GlobusFuncName(globus_ftp_client_insert_range);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }
    if(marker->type != GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK)
    {
	memset(marker,
	       '\0',
	       sizeof(globus_ftp_client_restart_extended_block_t));

	marker->type = GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK;
	globus_fifo_init(&marker->extended_block.ranges);
    }
    globus_fifo_move(&tmp, &marker->extended_block.ranges);

    while(!globus_fifo_empty(&tmp))
    {
	range = globus_fifo_dequeue(&tmp);
	if(offset <= range->offset)
	{
	    if(end_offset+1 < range->offset)
	    {
		newrange = globus_malloc(sizeof(globus_i_ftp_client_range_t));
		if(newrange == NULL)
		{
		    err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();
		    if(!err)
			err = GLOBUS_ERROR_NO_INFO;

		    goto copy_rest;
		}
		newrange->offset = offset;
		newrange->end_offset = end_offset;

		globus_fifo_enqueue(&marker->extended_block.ranges, newrange);
		globus_fifo_enqueue(&marker->extended_block.ranges, range);
		goto copy_rest;
	    }
	    else if(end_offset+1 == range->offset)
	    {
		end_offset = range->end_offset;
		globus_libc_free(range);
	    }
	    else
	    {
		/* weird.... overlapping data */
		if(end_offset < range->end_offset)
		{
		    end_offset = range->end_offset;
		}
		globus_libc_free(range);
	    }
	}
	else
	{
	    if(range->end_offset < offset - 1)
	    {
		globus_fifo_enqueue(&marker->extended_block.ranges, range);
	    }
	    else if(range->end_offset >= offset - 1)
	    {
		offset = range->offset;
		if(end_offset < range->end_offset)
		{
		    end_offset = range->end_offset;
		}
		globus_libc_free(range);
	    }
	    else
	    {
		globus_fifo_enqueue(&marker->extended_block.ranges, range);
	    }
	}
    }

    newrange = globus_malloc(sizeof(globus_i_ftp_client_range_t));
    if(newrange == GLOBUS_NULL)
    {
	err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();
	if(!err)
	    err = GLOBUS_ERROR_NO_INFO;

	goto copy_rest;
    }
    newrange->offset = offset;
    newrange->end_offset = end_offset;
    globus_fifo_enqueue(&marker->extended_block.ranges, newrange);
copy_rest:
    while(! globus_fifo_empty(&tmp))
    {
	globus_fifo_enqueue(&marker->extended_block.ranges,
			    globus_fifo_dequeue(&tmp));
    }
    globus_fifo_destroy(&tmp);
    
    return err ? globus_error_put(err) : GLOBUS_SUCCESS;
}
/**
 * Initialize an instance of the GridFTP restart plugin
 * @ingroup globus_ftp_client_restart_plugin
 *
 * This function will initialize the plugin-specific instance data
 * for this plugin, and will make the plugin usable for ftp
 * client handle attribute and handle creation.
 *
 * @param plugin
 *        A pointer to an uninitialized plugin. The plugin will be
 *        configured as a restart plugin.
 * @param max_retries
 *        The maximum number of times to retry the operation before giving
 *        up on the transfer. If this value is less than or equal to 0,
 *        then the restart plugin will keep trying to restart the operation
 *        until it completes or the deadline is reached with an unsuccessful
 *        operation.
 * @param interval
 *        The interval to wait after a failures before retrying the transfer.
 *        If the interval is 0 seconds or GLOBUS_NULL, then an exponential 
 *        backoff will be used.
 * @param deadline
 *        An absolute timeout.  If the deadline is GLOBUS_NULL then the retry
 *        will never timeout.
 *
 * @return This function returns an error if
 * - plugin is null
 *
 * @see globus_ftp_client_restart_plugin_destroy(),
 *      globus_ftp_client_handleattr_add_plugin(),
 *      globus_ftp_client_handleattr_remove_plugin(),
 *      globus_ftp_client_handle_init()
 */
globus_result_t
globus_ftp_client_restart_plugin_init(
    globus_ftp_client_plugin_t *		plugin,
    int						max_retries,
    globus_reltime_t *				interval,
    globus_abstime_t *				deadline)
{
    char *                              env_str;
    globus_l_ftp_client_restart_plugin_t *	d;
    globus_result_t				result;
    GlobusFuncName(globus_ftp_client_restart_plugin_init);

    if(plugin == GLOBUS_NULL)
    {
	return globus_error_put(globus_error_construct_string(
		GLOBUS_FTP_CLIENT_MODULE,
		GLOBUS_NULL,
		"[%s] NULL plugin at %s\n",
		GLOBUS_FTP_CLIENT_MODULE->module_name,
		_globus_func_name));
    }
        
    d =
	globus_libc_calloc(1, sizeof(globus_l_ftp_client_restart_plugin_t));

    if(! d)
    {
	return globus_error_put(globus_error_construct_string(
		                GLOBUS_FTP_CLIENT_MODULE,
				GLOBUS_NULL,
				"[%s] Out of memory at %s\n",
				 GLOBUS_FTP_CLIENT_MODULE->module_name,
				 _globus_func_name));
    }

    result = globus_ftp_client_plugin_init(plugin,
				  GLOBUS_L_FTP_CLIENT_RESTART_PLUGIN_NAME,
				  GLOBUS_FTP_CLIENT_CMD_MASK_ALL,
				  d);
    if(result != GLOBUS_SUCCESS)
    {
	globus_libc_free(d);

	return result;
    }

    d->max_retries = max_retries > 0 ? max_retries : -1;

    if(interval)
    {
	GlobusTimeReltimeCopy(d->interval, *interval);
    }
    if((!interval) || (interval->tv_sec == 0 && interval->tv_usec == 0))
    {
	d->backoff = GLOBUS_TRUE;
	d->interval.tv_sec = 1;
	d->interval.tv_usec = 0;
    }
    else
    {
        d->backoff = GLOBUS_FALSE;
    }

    if(deadline)
    {
	GlobusTimeAbstimeCopy(d->deadline, *deadline);
    }
    else
    {
	GlobusTimeAbstimeCopy(d->deadline, globus_i_abstime_infinity);
    }

    d->dest_url = GLOBUS_NULL;
    d->source_url = GLOBUS_NULL;

    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, copy);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, destroy);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, chmod);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, cksm);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, delete);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, modification_time);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, size);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, feat);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, mkdir);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, rmdir);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, move);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, verbose_list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, machine_list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, mlst);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, stat);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, get);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, put);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, third_party_transfer);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, fault);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, abort);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, complete);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, data);

    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin,
        response);

    env_str = globus_libc_getenv("GUC_STALL_TIMEOUT");
    if(env_str != NULL)
    {
        int                             sc;
        int                             to_secs;

        sc = sscanf(env_str, "%d", &to_secs);
        if(sc == 1)
        {
            globus_ftp_client_restart_plugin_set_stall_timeout(
                plugin, to_secs);
        }
    }

    return GLOBUS_SUCCESS;

result_exit:
    globus_ftp_client_plugin_destroy(plugin);
    return result;
}
globus_result_t
globus_ftp_client_restart_marker_plugin_init(
    globus_ftp_client_plugin_t *                            plugin,
    globus_ftp_client_restart_marker_plugin_begin_cb_t      begin_cb,
    globus_ftp_client_restart_marker_plugin_marker_cb_t     marker_cb,
    globus_ftp_client_restart_marker_plugin_complete_cb_t   complete_cb,
    void *                                                  user_arg)
{
    restart_marker_plugin_info_t *                  ps;
    globus_result_t                                 result;
    GlobusFuncName(globus_ftp_client_restart_marker_plugin_init);

    if(plugin == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] NULL plugin at %s\n",
            GLOBUS_FTP_CLIENT_MODULE->module_name,
            _globus_func_name));
    }

    ps = (restart_marker_plugin_info_t *)
        globus_malloc(sizeof(restart_marker_plugin_info_t));

    if(ps == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] Out of memory at %s\n",
             GLOBUS_FTP_CLIENT_MODULE->module_name,
             _globus_func_name));
    }

    /*
     *  initialize plugin specific structure.
     */
    ps->user_arg       = user_arg;
    ps->begin_cb       = begin_cb;
    ps->marker_cb      = marker_cb;
    ps->complete_cb    = complete_cb;

    ps->error_url      = GLOBUS_NULL;
    ps->error_obj      = GLOBUS_NULL;

    globus_mutex_init(&ps->lock, GLOBUS_NULL);

    result = globus_ftp_client_plugin_init(
              plugin,
              GLOBUS_L_FTP_CLIENT_RESTART_MARKER_PLUGIN_NAME,
              GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS,
              ps);

    if(result != GLOBUS_SUCCESS)
    {
        globus_mutex_destroy(&ps->lock);
        globus_free(ps);

        return result;
    }

    globus_ftp_client_plugin_set_destroy_func(plugin,
        restart_marker_plugin_destroy_cb);
    globus_ftp_client_plugin_set_copy_func(plugin,
        restart_marker_plugin_copy_cb);
    globus_ftp_client_plugin_set_get_func(plugin,
        restart_marker_plugin_get_cb);
    globus_ftp_client_plugin_set_data_func(plugin,
        restart_marker_plugin_data_cb);
    globus_ftp_client_plugin_set_put_func(plugin,
        restart_marker_plugin_put_cb);
    globus_ftp_client_plugin_set_third_party_transfer_func(plugin,
        restart_marker_plugin_transfer_cb);
    globus_ftp_client_plugin_set_response_func(plugin,
        restart_marker_plugin_response_cb);
    globus_ftp_client_plugin_set_complete_func(plugin,
        restart_marker_plugin_complete_cb);
    globus_ftp_client_plugin_set_fault_func(plugin,
        restart_marker_plugin_fault_cb);
    globus_ftp_client_plugin_set_abort_func(plugin,
        restart_marker_plugin_abort_cb);

    return GLOBUS_SUCCESS;
}
예제 #27
0
/* STRING PARSING ATTR SETTING */
globus_result_t
globus_i_xio_string_cntl_parser(
    const char *                        env_str,
    globus_xio_string_cntl_table_t *    table,
    void *                              attr,
    globus_xio_driver_attr_cntl_t       cntl_func)
{
    int                                 i;
    char *                              key;
    char *                              val;
    char *                              tmp_s;
    globus_list_t *                     list;
    globus_object_t *                   error = NULL;
    globus_result_t                     res = GLOBUS_SUCCESS;
    GlobusXIOName(globus_i_xio_string_cntl_parser);
    
    list = globus_list_from_string(env_str, ';', NULL);

    while(!globus_list_empty(list))
    {
        key = (char *) globus_list_remove(&list, list);

        tmp_s = strchr(key, '=');
        if(tmp_s != NULL)
        {
            *tmp_s = '\0';
            val = tmp_s + 1;

            for(i = 0; table[i].key != NULL; i++)
            {
                /* if we have a match */
                if(strcmp(table[i].key, key) == 0)
                {
                    res = table[i].parse_func(
                        attr, key, val, table[i].cmd, cntl_func);
                    if(res != GLOBUS_SUCCESS)
                    {
                        /* restore '=' */
                        *tmp_s = '=';
                        res = GlobusXIOErrorWrapFailedWithMessage(
                            res, "String cntl '%s' failed", key);
                    }
                    
                    break;
                }
            }
            
            if(!table[i].key)
            {
                res = GlobusXIOErrorParameter(key);
            }
        }
        else
        {
            res = GlobusXIOErrorParameter(key);
        }
        
        if(res != GLOBUS_SUCCESS)
        {
            if(!error)
            {
                error = globus_error_construct_multiple(
                    GLOBUS_XIO_MODULE,
                    GLOBUS_XIO_ERROR_PARAMETER,
                    "One or more of the string cntls failed");
            }
            
            globus_error_mutliple_add_chain(
                error, globus_error_get(res), NULL);
        }
        
        globus_free(key);
    }
    
    return globus_error_put(error);
}
static
void
globus_l_popen_waitpid(
    xio_l_popen_handle_t *              handle,
    int                                 opts)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    int                                 status;
    int                                 rc;
    globus_reltime_t                    delay;
    GlobusXIOName(globus_l_popen_waitpid);

#ifdef WIN32
    result = GlobusXIOErrorSystemResource("not available for windows");
#else
    rc = waitpid(handle->pid, &status, opts);
    if(rc > 0)
    {
        /* if program exited normally, but with a nonzero code OR
         * program exited by signal, and we didn't signal it */
        if(((WIFEXITED(status) && WEXITSTATUS(status) != 0) || 
            (WIFSIGNALED(status) && handle->kill_state != GLOBUS_L_XIO_POPEN_NONE))
            && !handle->ignore_program_errors)
        {
            /* read programs stderr and dump it to an error result */
            globus_size_t                   nbytes = 0;
            globus_xio_iovec_t              iovec;
            char                            buf[8192];

            iovec.iov_base = buf;
            iovec.iov_len = sizeof(buf) - 1;
            
            result = globus_xio_system_file_read(
                handle->err_system, 0, &iovec, 1, 0, &nbytes);
            
            buf[nbytes] = 0;

            if(WIFEXITED(status))
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program exited with an error "
                               "(exit code: %d):\n%s"),
                        WEXITSTATUS(status), 
                        buf));
            }
            else
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program was terminated by a signal"
                               "(sig: %d)"),
                        WTERMSIG(status)));
            }
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else if(rc < 0 || opts == 0)
    {
        /* If the errno is ECHILD, either some other thread or part of the
         * program called wait and got this pid's exit status, or sigaction
         * with SA_NOCLDWAIT prevented the process from becoming a zombie. Not
         * really an error case.
         */
        if (errno != ECHILD)
        {
            result = GlobusXIOErrorSystemError("waitpid", errno);
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else
    {
        
        handle->wait_count++;
        
        if(handle->canceled)
        {
            switch(handle->kill_state)
            {
                case GLOBUS_L_XIO_POPEN_NONE:
                    if(handle->wait_count > 5000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_TERM;
                        kill(handle->pid, SIGTERM);
                    }
                    break;
                case GLOBUS_L_XIO_POPEN_TERM:
                    if(handle->wait_count > 15000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_KILL;
                        kill(handle->pid, SIGKILL);
                    }
                    break;
                default:
                    break;
            } 
        }
        
        GlobusTimeReltimeSet(delay, 0, GLOBUS_L_XIO_POPEN_WAITPID_DELAY);
        globus_callback_register_oneshot(
            NULL,
            &delay,
            globus_l_xio_popen_close_oneshot,
            handle);         
    }

#endif
    GlobusXIOPOpenDebugExit();
}
/**
 * Create a string representation of a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function sets the @a marker_string parameter to point to
 * a freshly allocated string suitable for sending as an argument to
 * the FTP REST command, or for a later call to
 * globus_ftp_client_restart_marker_from_string().
 *
 * The string pointed to by marker_string must be freed by the caller.
 *
 * @param marker
 *        An initialized FTP client restart marker.
 * @param marker_string
 *        A pointer to a char * to be set to a freshly allocated marker
 *        string.
 *
 * @see globus_ftp_client_restart_marker
 */
globus_result_t
globus_ftp_client_restart_marker_to_string(
    globus_ftp_client_restart_marker_t *	marker,
    char **					marker_string)
{
    int					length = 0, mylen;
    char *				buf = GLOBUS_NULL;
    char *				tbuf;
    globus_i_ftp_client_range_t *	range;
    globus_fifo_t *			tmp;
    globus_off_t			offset;
    globus_size_t			digits;
    globus_object_t *			err;
    GlobusFuncName(globus_ftp_client_restart_marker_to_string);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }
    else if(marker_string == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker_string"));
    }

    (*marker_string) = GLOBUS_NULL;

    if(marker->type == GLOBUS_FTP_CLIENT_RESTART_NONE)
    {
	return GLOBUS_SUCCESS;
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_STREAM)
    {
        if(marker->stream.ascii_offset > marker->stream.offset)
	{
	    offset = marker->stream.ascii_offset;
	}
	else
	{
	    offset = marker->stream.offset;
	}
        digits = globus_i_ftp_client_count_digits(offset);

	(*marker_string) = globus_libc_malloc(digits+1);

	if(!(*marker_string))
	{
	    err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();

	    if(!err)
	    {
	        err = GLOBUS_ERROR_NO_INFO;
	    }

	    goto error_exit;
	}

	globus_libc_sprintf((*marker_string),
	                    "%lu",
			    (unsigned long) offset);
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK &&
            !globus_fifo_empty(&marker->extended_block.ranges))
    {
        tmp = globus_fifo_copy(&marker->extended_block.ranges);

        while((! globus_fifo_empty(tmp)))
        {
	    range = (globus_i_ftp_client_range_t *) globus_fifo_dequeue(tmp);

	    mylen = globus_i_ftp_client_count_digits(range->offset);
	    mylen++;
	    mylen += globus_i_ftp_client_count_digits(range->end_offset);
	    mylen++;
            
            if(buf)
            {
	        tbuf = realloc(buf, length + mylen + 1);
            }
            else
            {
                tbuf = malloc(length + mylen + 1);
            }
            
	    if(!tbuf)
	    {
		err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();

	        if(!err)
	        {
	            err = GLOBUS_ERROR_NO_INFO;
	        }
		goto buf_err;
	    }
	    else
	    {
	        buf = tbuf;
	    }
	    length += globus_libc_sprintf(
	        buf + length,
	        "%"GLOBUS_OFF_T_FORMAT"-%"GLOBUS_OFF_T_FORMAT",",
	        range->offset,
	        range->end_offset);
        }
        buf[strlen(buf)-1] = '\0';
	(*marker_string) = buf;
	
	globus_fifo_destroy(tmp);
        globus_libc_free(tmp);
    }

    return GLOBUS_SUCCESS;

  buf_err:
	globus_fifo_destroy(tmp);
    globus_libc_free(buf);
  error_exit:
    return globus_error_put(err);
}
/**
 * Initialize a restart marker from a string.
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function initializes a new restart, @a marker, based on the
 * @a marker_string parameter. The string may be either a single offset
 * for a stream-mode restart marker, or a comma-separated list of start-end
 * ranges.
 *
 * @param marker
 *        The restart marker to be unitialized.
 * @param marker_string
 *        The string containing a textual representation of a restart marker.
 * @see globus_ftp_client_restart_marker
 */
globus_result_t
globus_ftp_client_restart_marker_from_string(
    globus_ftp_client_restart_marker_t *	marker,
    const char *				marker_string)
{
    globus_off_t				offset;
    globus_off_t				end;
    int						consumed;
    globus_object_t *				err;
    globus_result_t				res;
    const char *				p;
    GlobusFuncName(globus_ftp_client_restart_marker_from_string);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
	    GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }
    else if(marker_string == GLOBUS_NULL)
    {
        return globus_error_put(
	    GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker_string"));
    }

    res = globus_ftp_client_restart_marker_init(marker);
    if(res != GLOBUS_SUCCESS)
    {
        goto res_exit;
    }

    if(strchr(marker_string, '-') != GLOBUS_NULL)
    {
        /* Looks like an extended block mode restart marker */
	if(marker->type == GLOBUS_FTP_CLIENT_RESTART_NONE)
	{
	    marker->type = GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK;
	}
	if(marker->type != GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK)
	{
	    err = GLOBUS_I_FTP_CLIENT_ERROR_INVALID_PARAMETER("marker");

	    goto error_exit;
	}

        p = marker_string;
	while( sscanf(p, "%"GLOBUS_OFF_T_FORMAT"-%"GLOBUS_OFF_T_FORMAT"%n",
	              &offset,
		      &end,
		      &consumed) >= 2)
	{
	    res = globus_ftp_client_restart_marker_insert_range(marker,
	                                                        offset,
								end);
	    if(res != GLOBUS_SUCCESS)
	    {
	        goto res_exit;
	    }

	    p += consumed;
	    if(*p == ',')
	    {
	        p++;
	    }
	    else
	    {
	        break;
	    }
	}
    }
    else /* assume stream mode */
    {
        if(marker->type == GLOBUS_FTP_CLIENT_RESTART_NONE)
	{
	    marker->type = GLOBUS_FTP_CLIENT_RESTART_STREAM;
	}
	if(marker->type != GLOBUS_FTP_CLIENT_RESTART_STREAM)
	{
	    err = GLOBUS_I_FTP_CLIENT_ERROR_INVALID_PARAMETER("marker");

	    goto error_exit;
	}
	if(sscanf(marker_string, "%"GLOBUS_OFF_T_FORMAT, &offset) != 1)
	{
	    err = GLOBUS_I_FTP_CLIENT_ERROR_INVALID_PARAMETER("marker_string");

	    goto error_exit;
	}
	else
	{
	    marker->stream.ascii_offset = marker->stream.offset = offset;
	}
    }

    return GLOBUS_SUCCESS;

  error_exit:
    res = globus_error_put(err);
  res_exit:
    return res;
}