/**
 * Return a copy of the short description from the instance data
 * @ingroup globus_errno_error_object 
 * 
 * @param error
 *        The error object to retrieve the data from.
 * @return
 *        String containing the short description if it exists, NULL
 *        otherwise.
 */
static
char *
globus_l_error_errno_printable(
    globus_object_t *                   error)
{
    globus_module_descriptor_t *        base_source;
    char *                              sys_failed =
        _GCSL("A system call failed:");
    char *                              sys_error = NULL;
    int                                 length = 10 + strlen(sys_failed);
    char *                              printable;

#ifndef WIN32
    sys_error = globus_libc_system_error_string(
        *((int *) globus_object_get_local_instance_data(error)));
    length += sys_error ? strlen(sys_error) : 0;
#else
    length += FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 
        NULL,
        *((int *) globus_object_get_local_instance_data(error)), 
        0, 
        (LPTSTR)&sys_error,
        0,
        NULL);
#endif
    
    base_source = globus_error_get_source(error);

    if(base_source && base_source->module_name)
    {
        length += strlen(base_source->module_name);
        printable = globus_libc_malloc(length);
        globus_libc_snprintf(printable,length,"%s: %s %s",
                             base_source->module_name,
                             sys_failed,
                             sys_error ? sys_error : "(null)");
        
    }
    else
    {
        printable = globus_libc_malloc(length);
        globus_libc_snprintf(printable,length,"%s %s",
                             sys_failed,
                             sys_error ? sys_error : "(null)");
    }

#ifdef WIN32
    if(sys_error)
    {
        LocalFree(sys_error);
    }
#endif

    return printable;
    
}/* globus_l_error_errno_printable */
示例#2
0
/**
 * debug malloc
 */
void *
ngiDebugMalloc(size_t size)
{
    size_t realSize;
    void *realAddr, *returnAddr, *ckBufAddr;
    void **realAddrPtr;
    size_t *sizePtr;

    realSize = NGCLL_CHECK_BUFFER_SIZE * 2 + sizeof(size_t) +
                 sizeof(void *) + size;
    realAddr = globus_libc_malloc(realSize);
    if (realAddr == NULL) {
        return NULL;
    }

    returnAddr = (char *)realAddr + NGCLL_CHECK_BUFFER_SIZE +
        sizeof(size_t) + sizeof(void *);

    ckBufAddr = realAddr;
    nglDebugMallocCheckAreaSet(ckBufAddr);

    ckBufAddr = (char *)realAddr + NGCLL_CHECK_BUFFER_SIZE + sizeof(size_t)
               + sizeof(void *) + size;
    nglDebugMallocCheckAreaSet(ckBufAddr);

    realAddrPtr = (void **)returnAddr - 1;
    *realAddrPtr = realAddr;

    sizePtr = (size_t *)((void **)returnAddr - 2);
    *sizePtr = size;
 
    return returnAddr;
}
/*
 * Function: globus_handle_table_init()
 *
 * Description: Initialize a handle table
 *
 * Parameters:
 *
 * Returns:
 */
int
globus_handle_table_init(
    globus_handle_table_t *             e_handle_table,
    globus_handle_destructor_t          destructor)
{
    globus_l_handle_table_t *		handle_table;

    if(!e_handle_table)
    {
        return GLOBUS_FAILURE;
    }

    handle_table = (globus_l_handle_table_t *)
	 globus_libc_malloc(sizeof(globus_l_handle_table_t));
    if(handle_table == NULL)
    {
        return GLOBUS_FAILURE;
    }

    handle_table->table = (globus_l_handle_entry_t **)
        globus_libc_malloc(GLOBUS_L_HANDLE_TABLE_BLOCK_SIZE * 
            sizeof(globus_l_handle_entry_t *));
    if(!handle_table->table)
    {
        globus_libc_free(handle_table);

        return GLOBUS_FAILURE;
    }

    *e_handle_table = handle_table;

    handle_table->next_slot = GLOBUS_NULL_HANDLE + 1;
    handle_table->table_size = GLOBUS_L_HANDLE_TABLE_BLOCK_SIZE;
    handle_table->inactive = GLOBUS_NULL;
    handle_table->destructor = destructor;
    
    return GLOBUS_SUCCESS;
}
/** Copy an HTTP attribute
 * @ingroup globus_i_xio_http_attr
 *
 * Copies all values associated with the @a src http attribute to
 * a newly allocated attribute in @a dst. If this function returns a
 * failure, then the @a dst should be considered uninitiailized.  This is
 * called by the XIO driver via globus_xio_attr_copy().
 *
 * @param dst
 *     Void ** which will be set to point to a newly allocated attribute
 *     with equivalent values to those in @a src.
 * @param src
 *     Void * pointing to a #globus_i_xio_http_attr_t which contains the
 *     attributes we want to copy.
 *
 * @return
 *     This function returns GLOBUS_SUCCESS or GLOBUS_XIO_ERROR_MEMORY itself.
 *     Other errors generated by globus_i_xio_http_request_copy() may be
 *     returned as well.
 *
 * @retval GLOBUS_SUCCESS
 *     Attribute successfully copied.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Attribute copy failed due to memory constraints.
 */
globus_result_t
globus_i_xio_http_attr_copy(
    void **                             dst,
    void *                              src)
{
    globus_result_t                     result;
    globus_i_xio_http_attr_t *          http_dst;
    globus_i_xio_http_attr_t *          http_src = src;
    GlobusXIOName(globus_i_xio_http_attr_copy);

    /*
     * Don't use globus_i_xio_http_request_init() here or the call to
     * globus_i_xio_http_request_copy() below will leak.
     */
    http_dst = globus_libc_malloc(sizeof(globus_i_xio_http_attr_t));
    if (http_dst == NULL)
    {
        result = GlobusXIOErrorMemory(dst);
        goto error_exit;
    }

    /* Copy request attrs */
    result = globus_i_xio_http_request_copy(
            &http_dst->request,
            &http_src->request);
    if (result != GLOBUS_SUCCESS)
    {
        goto free_http_dst_exit;
    }

    /* Copy response attrs */
    result = globus_i_xio_http_response_copy(
            &http_dst->response,
            &http_src->response);
    if (result != GLOBUS_SUCCESS)
    {
        goto free_http_dst_request_exit;
    }
    http_dst->delay_write_header = http_src->delay_write_header;

    *dst = http_dst;

    return GLOBUS_SUCCESS;
free_http_dst_request_exit:
    globus_i_xio_http_request_destroy(&http_dst->request);
free_http_dst_exit:
    globus_libc_free(http_dst);
error_exit:
    return result;
}
/**
 * Send an arbitrary SEG notification.
 * @ingroup seg_api
 *
 * @param format
 *     Printf-style format of the SEG notification message
 * @param ...
 *     Varargs which will be interpreted as per format.
 *
 * @retval GLOBUS_SUCCESS
 *     Scheduler message sent or queued.
 * @retval GLOBUS_SEG_ERROR_NULL
 *     Null format.
 * @retval GLOBUS_SEG_ERROR_INVALID_FORMAT
 *     Unable to determine length of formatted string.
 */
static
globus_result_t
globus_l_stdout_scheduler_event(
    const char *                        format,
    ...)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    char *                              buf;
    va_list                             ap;
    int                                 length;

    if (format == NULL)
    {
        result = GLOBUS_SEG_ERROR_NULL;

        goto error;
    }

    va_start(ap, format);
    length = globus_libc_vprintf_length(format, ap);
    va_end(ap);

    if (length <= 0)
    {
        result = GLOBUS_SEG_ERROR_INVALID_FORMAT(format);

        goto error;
    }

    buf = globus_libc_malloc(length+1);
    if (buf == NULL)
    {
        result = GLOBUS_SEG_ERROR_OUT_OF_MEMORY;

        goto error;
    }

    va_start(ap, format);
    vsprintf(buf, format, ap);
    va_end(ap);

    globus_mutex_lock(&globus_l_seg_mutex);
    result = globus_l_seg_register_write(buf);
    globus_mutex_unlock(&globus_l_seg_mutex);

error:
    return result;
}
static
globus_result_t
globus_l_xio_test_read_buffer(
    globus_xio_handle_t                 handle,
    globus_byte_t *                     msg,
    globus_size_t                       msg_size)
{
    globus_size_t                       nbytes;
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_byte_t *			temp;
    int					i;
    GlobusXIOName(globus_l_xio_test_read_buffer);
   
    temp = globus_libc_malloc(msg_size+1);
    for (i=0; i<=msg_size; i++)
	temp[i] = '\0';
    result = globus_xio_read(
	    handle,
	    temp,
	    msg_size,
	    msg_size,
	    &nbytes,
	    NULL);

    if (result != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "Error reading from http: %s\n",
                globus_object_printable_to_string(globus_error_peek(result)));
    }

    result = globus_xio_read(
	    handle,
	    msg,
	    msg_size,
	    1,
	    &nbytes,
	    NULL);
    
    if (http_is_eof(result))
    {
        result = GLOBUS_SUCCESS;
    }

    return result;
}
static
globus_ftp_client_plugin_t *
globus_l_ftp_client_restart_plugin_copy(
    globus_ftp_client_plugin_t *		plugin_template,
    void *					plugin_specific)
{
    globus_ftp_client_plugin_t *		newguy;
    globus_l_ftp_client_restart_plugin_t *	d;
    globus_l_ftp_client_restart_plugin_t *	newd;
    globus_result_t				result;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    newguy = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
    if(newguy == GLOBUS_NULL)
    {
	goto error_exit;
    }
    result = globus_ftp_client_restart_plugin_init(newguy,
	    d->max_retries,
	    &d->interval,
	    &d->deadline);

    if(result != GLOBUS_SUCCESS)
    {
	goto free_exit;
    }
    result = globus_ftp_client_plugin_get_plugin_specific(newguy,
	                                                  (void **) &newd);
    if(result != GLOBUS_SUCCESS)
    {
	goto destroy_exit;
    }
    newd->backoff = d->backoff;
    newd->stall_timeout = d->stall_timeout;

    return newguy;

destroy_exit:
    globus_ftp_client_restart_plugin_destroy(newguy);
free_exit:
    globus_libc_free(newguy);
error_exit:
    return GLOBUS_NULL;
}
/**
 * Allocate and initialize an HTTP attribute
 * @ingroup globus_i_xio_http_attr
 *
 * Creates a new attribute with default values. This is called by the XIO
 * driver via globus_xio_attr_init().
 *
 * @param out_attr
 *     Pointer value will be set to point to a 
 *     newly allocated and initilized #globus_i_xio_http_attr_t
 *     structure.
 *
 * @retval GLOBUS_SUCCESS
 *     Attribute successfully initialized.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Initialization failed due to memory constraints.
 *
 * @see globus_i_xio_http_attr_destroy()
 */
globus_result_t
globus_i_xio_http_attr_init(
    void **                             out_attr)
{
    globus_result_t                     res;
    globus_i_xio_http_attr_t *          attr;
    GlobusXIOName(globus_i_xio_http_attr_init);

    attr = globus_libc_malloc(sizeof(globus_i_xio_http_attr_t));
    if (attr == NULL)
    {
        res = GlobusXIOErrorMemory("attr");

        goto error_exit;
    }

    res = globus_i_xio_http_request_init(&attr->request);

    if (res != GLOBUS_SUCCESS)
    {
        goto free_attr_exit;
    }
    res = globus_i_xio_http_response_init(&attr->response);

    if (res != GLOBUS_SUCCESS)
    {
        goto free_request_exit;
    }
    attr->delay_write_header = GLOBUS_FALSE;

    *out_attr = attr;
    return GLOBUS_SUCCESS;

free_request_exit:
    globus_i_xio_http_request_destroy(&attr->request);
free_attr_exit:
    globus_libc_free(attr);
error_exit:
    return res;
}
/**
 * Set the value of a header in a hashtable
 * @ingroup globus_i_xio_http_header
 *
 * Adds a new header to a header info structure, or updates the value of an
 * existing header. Copies of the name and value will be stored in a
 * #globus_xio_http_header_t in a hashtable in the header info structure.
 *
 * @param headers
 *     Pointer to the header info structure.
 * @param header_name
 *     Name of the header.
 * @param header_value
 *     Value of the header.
 *
 * @retval GLOBUS_SUCCESS
 *     Header successfully added to the hashtable.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Unable to add header due to memory constraints.
 */
globus_result_t
globus_i_xio_http_header_info_set_header(
    globus_i_xio_http_header_info_t *   headers,
    const char *                        header_name,
    const char *                        header_value)
{
    char *                              save_header;
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_xio_http_header_t *          header;
    int                                 rc;
    unsigned long                       length;
    GlobusXIOName(globus_l_xio_http_header_set);

    /* Special cases for entity-body handling headers */
    if (strcmp(header_name, "Content-Length") == 0)
    {
        rc = sscanf(header_value, "%lu", &length);

        if (rc < 1)
        {
            result = GlobusXIOHttpErrorInvalidHeader(header_name, header_value);

            goto error_exit;
        }
        headers->content_length = length;
        headers->flags |= GLOBUS_I_XIO_HTTP_HEADER_CONTENT_LENGTH_SET;
    }
    else if (strcmp(header_name, "Transfer-Encoding") == 0)
    {
        if (strcmp(header_value, "identity") == 0)
        {
            headers->transfer_encoding =
                GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY;
        }
        else if (strcmp(header_value, "chunked") == 0)
        {
            headers->transfer_encoding =
                GLOBUS_XIO_HTTP_TRANSFER_ENCODING_CHUNKED;
        }
        else
        {
            result = GlobusXIOHttpErrorInvalidHeader(header_name, header_value);

            goto error_exit;
        }
    }
    else if (strcmp(header_name, "Connection") == 0)
    {
        if (strcmp(header_value, "close") == 0)
        {
            headers->flags |= GLOBUS_I_XIO_HTTP_HEADER_CONNECTION_CLOSE;
        }
        else if (strcmp(header_value, "keep-alive") == 0)
        {
            headers->flags &= ~GLOBUS_I_XIO_HTTP_HEADER_CONNECTION_CLOSE;
        }
        else
        {
            result = GlobusXIOHttpErrorInvalidHeader(header_name, header_value);

            goto error_exit;
        }
    }
    else
    {
        /*
         * Either modify the header's value in the hashtable, if it's a
         * duplicate, or create a new entry in the hashtable
         */
        header = globus_hashtable_lookup(
                &headers->headers,
                (void *) header_name);

        if (header != NULL)
        {
            /* Replace current header's value */
            save_header = header->value;

            header->value = globus_libc_strdup(header_value);

            if (header->value == NULL)
            {
                header->value = save_header;

                result = GlobusXIOErrorMemory("header");

                goto error_exit;
            }
            globus_libc_free(save_header);
        }
        else
        {
            header = globus_libc_malloc(sizeof(globus_xio_http_header_t));

            if (header == NULL)
            {
                result = GlobusXIOErrorMemory("header");

                goto error_exit;
            }
            header->name = globus_libc_strdup(header_name);

            if (header->name == NULL)
            {
                result = GlobusXIOErrorMemory("header");
                goto free_header_exit;
            }

            header->value = globus_libc_strdup(header_value);

            if (header->value == NULL)
            {
                result = GlobusXIOErrorMemory("header");
                goto free_header_name_exit;
            }

            rc = globus_hashtable_insert(
                    &headers->headers,
                    header->name,
                    header);

            if (rc != GLOBUS_SUCCESS)
            {
                result = GlobusXIOErrorMemory("header");

                goto free_header_value_exit;
            }
        }
    }
    return result;

free_header_value_exit:
    globus_libc_free(header->value);
free_header_name_exit:
    globus_libc_free(header->name);
free_header_exit:
    globus_libc_free(header);
error_exit:
    return result;
}
int main(int argc,
	 char *argv[])
{
    globus_ftp_client_handle_t			handle;
    globus_ftp_client_operationattr_t		attr;
    globus_byte_t *				buffer;
    globus_size_t				buffer_length;
    globus_result_t				result;
    char *					src;
    char *					dst;
    globus_ftp_client_handleattr_t		handle_attr;
    globus_ftp_control_mode_t			mode;
    int						i;
    globus_ftp_control_parallelism_t		parallelism;

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

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

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

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

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

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

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

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

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

    if(test_abort_count && error)
    {
	return 0;
    }
    return error;
}
/**
 * Parse an HTTP request
 * @ingroup globus_i_xio_http_server
 *
 * Parses the HTTP request line and then uses globus_i_xio_http_header_parse()
 * to parse the header bock .If the entire request header section is reqad, the
 * boolean pointed to by @a done will be modified to be GLOBUS_TRUE
 *
 * Called with mutex locked.
 *
 * @param http_handle
 * @param done
 *
 * @return
 *     This function returns GLOBUS_SUCCESS, GLOBUS_XIO_HTTP_ERROR_PARSE,  or
 *     GLOBUS_XIO_ERROR_MEMORY. Other errors may be generated from
 *     globus_i_xio_http_header_parse()
 *
 * @retval GLOBUS_SUCCESS
 *     No parsing errors occurred while parsing the status line or headers.
 *     Parsing may still be incomplete, depending on the final value of @a
 *     done.
 * @retval <driver>::GLOBUS_XIO_HTTP_ERROR_PARSE
 *     Parse error reading the HTTP request line
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Parsing failed because of memory constraints.
 */
static
globus_result_t
globus_l_xio_http_server_parse_request(
    globus_i_xio_http_handle_t *        http_handle,
    globus_bool_t *                     done)
{
    globus_result_t                     result;
    char *                              eol;
    char *                              current_offset;
    int                                 parsed;
    int                                 rc;
    int                                 http_major;
    int                                 http_minor;
    GlobusXIOName(globus_l_xio_http_server_parse_request);

    if (http_handle->parse_state == GLOBUS_XIO_HTTP_REQUEST_LINE)
    {
        /*
         * Make sure any old request info has been freed so we don't leak here
         * when reusing a handle (or have old headers around)
         */
        globus_i_xio_http_request_destroy(&http_handle->request_info);
        result = globus_i_xio_http_request_init(&http_handle->request_info);

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

        /* Parse the request line:
         *
         * Method SP Request-URI SP HTTP-Version CRLF
         */
        current_offset = ((char *) (http_handle->read_buffer.iov_base))
                + http_handle->read_buffer_offset;

        eol = globus_i_xio_http_find_eol(
                current_offset,
                http_handle->read_buffer_valid);
        if (eol == NULL)
        {
            *done = GLOBUS_FALSE;

            return GLOBUS_SUCCESS;
        }
        *eol = '\0';

        rc = sscanf(current_offset, "%*s %n", &parsed);

        if (rc < 0)
        {
            result = GlobusXIOHttpErrorParse("Method", current_offset);

            goto error_exit;
        }

        http_handle->request_info.method = globus_libc_malloc(parsed+1);
        if (http_handle->request_info.method == NULL)
        {
            result = GlobusXIOErrorMemory("method");

            goto error_exit;
        }

        rc = sscanf(current_offset, "%s ", http_handle->request_info.method);
        globus_assert(rc == 1);

        current_offset += parsed;
        
        rc = sscanf(current_offset, "%*s %n", &parsed);
        if (rc < 0)
        {
            result = GlobusXIOHttpErrorParse("Request-URI", current_offset);

            goto error_exit;
        }

        http_handle->request_info.uri = globus_libc_malloc(parsed+1);
        if (http_handle->request_info.uri == NULL)
        {
            result = GlobusXIOErrorMemory("uri");

            goto error_exit;
        }
        rc = sscanf(current_offset, "%s ", http_handle->request_info.uri);
        globus_assert(rc == 1);

        current_offset += parsed;

        rc = sscanf(current_offset, "HTTP/%d.%d", &http_major, &http_minor);

        if (rc < 2)
        {
            result = GlobusXIOHttpErrorParse("Http-Version", current_offset);

            goto error_exit;
        }

        http_handle->request_info.http_version =
            globus_i_xio_http_guess_version(http_major, http_minor);

        /* Set current offset to end of CRLF at the end of this line */
        current_offset = eol+2;

        parsed = current_offset - ((char *) http_handle->read_buffer.iov_base
                + http_handle->read_buffer_offset);
        http_handle->read_buffer_valid -= parsed;
        http_handle->read_buffer_offset += parsed;
        http_handle->parse_state = GLOBUS_XIO_HTTP_HEADERS;
    }
    return globus_i_xio_http_header_parse(http_handle, done);

error_exit:
    parsed = current_offset - ((char *) http_handle->read_buffer.iov_base
                + http_handle->read_buffer_offset);

    /* Chop of what we managed to parse from the buffer */
    http_handle->read_buffer_valid -= parsed;
    http_handle->read_buffer_offset += parsed;

error_exit_init:
    return result;
}
/**
 * Write the response to an HTTP request
 * @ingroup globus_i_xio_http_server
 *
 * Generates an HTTP response line from a handle, and passes it to the
 * transport. The globus_l_xio_http_server_write_response_callback() will
 * be called once the transport has sent the response.
 *
 * This call may be triggered by either the first write on a server handle,
 * or by calling the #GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY handle
 * control function.
 *
 * Called with my mutex lock.
 *
 * @param http_handle
 *     Handle associated with this HTTP stream.
 * @param iovec
 *     Array of globus_xio_iovec_t structs associated with the user's write.
 * @param iovec_count
 *     Length of the @a iovec array. If this is zero, we assume that the
 *     response is being generated by the
 *     #GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY control.
 * @param op
 *     Operation associated with the write. If this is NULL (in the case
 *     of the GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY control), one
 *     will be created in this function.
 *
 * This function returns GLOBUS_SUCCESS, GLOBUS_XIO_ERROR_MEMORY, or an
 * error result from globus_xio_driver_operation_create(), or
 * globus_xio_driver_pass_write().
 *
 * @retval GLOBUS_SUCCESS
 *     Response was passed to the transport for writing. If this was generated
 *     by a user writing data, then the write will occur after the 
 *     globus_l_xio_http_server_write_response_callback() has been called.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Unable to compose the response due to memory constraints.
 */
globus_result_t
globus_i_xio_http_server_write_response(
    globus_i_xio_http_handle_t *        http_handle,
    const globus_xio_iovec_t *          iovec,
    int                                 iovec_count,
    globus_xio_operation_t              op)
{
    globus_result_t                     result;
    globus_fifo_t                       iovecs;
    const char *                        str;
    char                                code_str[5];
    globus_xio_iovec_t *                iov;
    int                                 rc;
    int                                 i;
    int                                 send_size;
    char *                              size_buffer = NULL;
    globus_bool_t                       free_op = GLOBUS_FALSE;
    globus_xio_http_header_t *          current_header;
    GlobusXIOName(globus_i_xio_server_write_response);

    globus_assert(http_handle->send_state == GLOBUS_XIO_HTTP_STATUS_LINE);
    rc = globus_fifo_init(&iovecs);

    if (rc != GLOBUS_SUCCESS)
    {
        result = GlobusXIOErrorMemory("iovecs");

        goto error_exit;
    }

    /* Compose HTTP Response:
     * HTTP-Version SP Status-Code SP Reason-Phrase CRLF
     */
    if (http_handle->response_info.http_version == GLOBUS_XIO_HTTP_VERSION_1_0)
    {
        str = "HTTP/1.0 ";
    }
    else
    {
        http_handle->response_info.http_version = GLOBUS_XIO_HTTP_VERSION_1_1;
        str = "HTTP/1.1 ";
    }
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, str, 9, free_iovecs_error);

    sprintf(code_str, "%d ", http_handle->response_info.status_code);
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, code_str, 4, free_iovecs_error);

    if (http_handle->response_info.reason_phrase != NULL)
    {
        str = http_handle->response_info.reason_phrase;
    }
    else
    {
        str = globus_i_xio_http_lookup_reason(
                http_handle->response_info.status_code);
    }

    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, str, strlen(str), free_iovecs_error);
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, "\r\n", 2, free_iovecs_error);

    current_header = globus_hashtable_first(
            &http_handle->response_info.headers.headers);

    while (current_header)
    {
        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                current_header->name,
                strlen(current_header->name),
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                ": ",
                2,
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                current_header->value,
                strlen(current_header->value),
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                "\r\n",
                2,
                free_iovecs_error);
        current_header = globus_hashtable_next(
                &http_handle->response_info.headers.headers);
    }

    /*
     * Special headers we generate.
     */
    if (GLOBUS_I_XIO_HTTP_HEADER_IS_CONNECTION_CLOSE(
                &http_handle->response_info.headers) ||
            (http_handle->request_info.http_version ==
                GLOBUS_XIO_HTTP_VERSION_1_0) ||
            (http_handle->response_info.headers.transfer_encoding
                == GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY &&
             GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                &http_handle->response_info.headers)))
    {
        http_handle->response_info.headers.flags |= 
                GLOBUS_I_XIO_HTTP_HEADER_CONNECTION_CLOSE;

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                "Connection: close\r\n",
                19,
                free_iovecs_error);
    }
    if (iovec_count > 0)
    {
        /*
         * We are sending a body, so we'll set the appropriate entity-related
         * headers
         */
        if (http_handle->request_info.http_version
                == GLOBUS_XIO_HTTP_VERSION_1_0 ||
            (http_handle->response_info.headers.transfer_encoding
                == GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY &&
             GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                     &http_handle->response_info.headers)))
        {
            http_handle->response_info.headers.transfer_encoding
                = GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY;
            /* Transfer-Encoding mustn't be sent to a HTTP/1.0 client */
            if (http_handle->request_info.http_version
                != GLOBUS_XIO_HTTP_VERSION_1_0)
            {
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        "Transfer-Encoding: identity\r\n",
                        29,
                        free_iovecs_error);
            }
            /*
             * When we know the content-length beforehand we can set it here,
             * otherwise, we will use the connection: close header
             */
            if (GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                    &http_handle->response_info.headers))
            {
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        "Content-Length: ",
                        16,
                        free_iovecs_error);

                size_buffer = globus_common_create_string(
                        "%lu\r\n",
                        (unsigned long)
                            http_handle->response_info.headers.content_length);

                if (size_buffer == NULL)
                {
                    result = GlobusXIOErrorMemory("iovec.iov_base");

                    goto free_iovecs_error;
                }
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        size_buffer,
                        strlen(size_buffer),
                        free_iovecs_error);

                free(size_buffer);

                size_buffer = NULL;
            }
        }
        else
        {
            http_handle->response_info.headers.transfer_encoding
                = GLOBUS_XIO_HTTP_TRANSFER_ENCODING_CHUNKED;
            GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                    "Transfer-Encoding: chunked\r\n",
                    28,
                    free_iovecs_error);
        }
    }
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, "\r\n", 2, free_iovecs_error);

    http_handle->header_iovcnt = globus_fifo_size(&iovecs);
    http_handle->header_iovec = globus_libc_malloc(
            http_handle->header_iovcnt * sizeof(globus_xio_iovec_t));
    if (http_handle->header_iovec == NULL)
    {
        goto free_iovecs_error;
    }

    /* Convert fifo to iovec array, counting up size for wait_for_nbytes
     * parameter to globus_xio_driver_pass_write.
     */
    for (i = 0, send_size = 0; i < http_handle->header_iovcnt; i++)
    {
        iov = globus_fifo_dequeue(&iovecs);

        globus_assert(iov != NULL);

        http_handle->header_iovec[i].iov_base = iov->iov_base;
        http_handle->header_iovec[i].iov_len = iov->iov_len;

        send_size += iov->iov_len;

        globus_libc_free(iov);
    }

    if (op == NULL)
    {
        result = globus_xio_driver_operation_create(
                &op,
                http_handle->handle);

        free_op = GLOBUS_TRUE;
        if (result != GLOBUS_SUCCESS)
        {
            goto free_headers_exit;
        }
    }

    /* Stash user buffer info until we've sent response headers */
    http_handle->write_operation.operation = op;
    http_handle->write_operation.iov = (globus_xio_iovec_t *) iovec;
    http_handle->write_operation.iovcnt = iovec_count;
    http_handle->write_operation.wait_for = 0;

    result = globus_xio_driver_pass_write(
            http_handle->write_operation.operation,
            http_handle->header_iovec,
            http_handle->header_iovcnt,
            send_size,
            globus_l_xio_http_server_write_response_callback,
            http_handle);
    if (result != GLOBUS_SUCCESS)
    {
        goto free_operation_exit;
    }
    globus_fifo_destroy(&iovecs);

    if (iovec_count == 0)
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_EOF;
    }
    else if (http_handle->response_info.headers.transfer_encoding ==
            GLOBUS_XIO_HTTP_TRANSFER_ENCODING_CHUNKED)
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_CHUNK_BODY;
    }
    else
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_IDENTITY_BODY;
    }

    return GLOBUS_SUCCESS;

free_operation_exit:
    if (free_op)
    {
        globus_xio_driver_operation_destroy(
                http_handle->write_operation.operation);
    }
free_headers_exit:
    http_handle->write_operation.operation = NULL;
    http_handle->write_operation.driver_handle = NULL;
    http_handle->write_operation.iov = NULL;
    http_handle->write_operation.iovcnt = 0;
    http_handle->write_operation.wait_for = 0;

    for (i = 0; i < http_handle->header_iovcnt; i++)
    {
        globus_libc_free(http_handle->header_iovec[i].iov_base);
    }
    globus_libc_free(http_handle->header_iovec);

    http_handle->header_iovec = NULL;
    http_handle->header_iovcnt = 0;

free_iovecs_error:
    while (!globus_fifo_empty(&iovecs))
    {
        iov = globus_fifo_dequeue(&iovecs);

        globus_libc_free(iov->iov_base);
        globus_libc_free(iov);
    }
    globus_fifo_destroy(&iovecs);
    if (size_buffer != NULL)
    {
        free(size_buffer);
    }

error_exit:
    return result;
}
/**
 * @brief Create a HTTP-framed copy of a GRAM request
 * @ingroup globus_gram_protocol_framing
 *
 * @details
 * The globus_gram_protocol_frame_request() function adds HTTP 1.1
 * framing around the input message. The framed message includes HTTP headers 
 * relating the the destination URL and the length of the message content.
 * The framed message is returned by modifying @a framedmsg to point to a
 * newly allocated string. The integer pointed to by the @a framedsize
 * parameter is set to the length of this message.
 *
 * @param url
 *        The URL of the GRAM resource to contact. This is parsed and used
 *        to generate the HTTP POST operation destination and the Host
 *        HTTP header.
 * @param msg
 *        A string containing the message content to be framed.
 * @param msgsize
 *        The length of the string pointed to by @a msg
 * @param framedmsg
 *        An output parameter which will be set to a copy of the @a msg string
 *        with an HTTP frame around it.
 * @param framedsize
 *        An output parameter which will be set to the length of the 
 *        framed message.
 *
 * @return
 *     Upon success, globus_gram_protocol_frame_request() will return
 *     GLOBUS_SUCCESS and the @a framedmsg and @a framedsize parameters will be
 *     modified to point to the new framed message string and its length
 *     respectively. When this occurs, the caller is responsible for freeing
 *     the string pointed to by @a framedmsg. If an error occurs, its value
 *     will returned and the @a framedmsg and @a framedsize parameters will 
 *     be uninitialized.
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 * @retval GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT
 *     Invalid job contact
 */
int
globus_gram_protocol_frame_request(
    const char *			url,
    const globus_byte_t *		msg,
    globus_size_t			msgsize,
    globus_byte_t **			framedmsg,
    globus_size_t *			framedsize)
{
    char *				buf;
    globus_size_t			digits = 0;
    globus_size_t			tmp;
    globus_size_t			framedlen;
    globus_url_t			parsed;
    int					rc;

    rc = globus_url_parse(url, &parsed);

    if(rc != GLOBUS_SUCCESS)
    {
	rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT;

        goto out;
    }

    if (parsed.url_path == NULL)
    {
	rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT;

        goto destroy_out;
    }

    /*
     * HTTP request message framing:
     *    POST <uri> HTTP/1.1<CR><LF>
     *    Host: <hostname><CR><LF>
     *    Content-Type: application/x-globus-gram<CR><LF>
     *    Content-Length: <msgsize><CR><LF>
     *    <CR><LF>
     *    <msg>
     */
    tmp = msgsize;

    do
    {
	tmp /= 10;
	digits++;
    }
    while(tmp > 0);

    framedlen  = strlen(GLOBUS_GRAM_HTTP_REQUEST_LINE);
    framedlen += strlen((char *) parsed.url_path);
    framedlen += strlen(GLOBUS_GRAM_HTTP_HOST_LINE);
    framedlen += strlen((char *) parsed.host);
    framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
    framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE);
    framedlen += digits;
    framedlen += 2;
    framedlen += msgsize;

    buf = (char *) globus_libc_malloc(framedlen + 1 /*null terminator*/);

    tmp  = 0;
    tmp += globus_libc_sprintf(buf + tmp,
			      GLOBUS_GRAM_HTTP_REQUEST_LINE,
			      parsed.url_path);
    tmp += globus_libc_sprintf(buf + tmp,
			      GLOBUS_GRAM_HTTP_HOST_LINE,
			      parsed.host);
    tmp += globus_libc_sprintf(buf + tmp,
			       GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
    tmp += globus_libc_sprintf(buf + tmp,
			       GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE,
			       (long) msgsize);
    tmp += globus_libc_sprintf(buf + tmp,
			       CRLF);

    if (msgsize > 0)    /* allow for empty message body (msg==NULL) */
    {
	memcpy(buf + tmp,
	       msg,
	       msgsize);
    }

    *framedmsg = (globus_byte_t *) buf;
    *framedsize = tmp + msgsize;

destroy_out:
    globus_url_destroy(&parsed);
out:
    return rc;
}
/**
 * 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);
}
void
test_parse_args(int argc,
		char **argv,
		globus_ftp_client_handleattr_t * handle_attr,
		globus_ftp_client_operationattr_t * operation_attr,
		char **src,
		char **dst)
{
    int c;
    extern char * optarg;
    extern int opterr;
    globus_reltime_t timeout;
    globus_ftp_client_plugin_t *plugin;
    globus_ftp_control_dcau_t dcau;
    globus_abstime_t deadline_time;
    globus_reltime_t interval_time;
    int max_retries;
    long interval;
    long deadline;
    char * subject;

    *src = GLOBUS_NULL;
    *dst = GLOBUS_NULL;

    setvbuf(stdout, 0, _IONBF, 0);
    
#ifdef WIN32
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
    _setmode(_fileno(stderr), _O_BINARY);
#endif

    opterr = 0;
    while((c = getopt(argc, argv, "-f:a:ps:d:r:zMTc:t:i")) != -1)
    {
	switch(c)
	{
	case 'a':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_ABORT_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_abort_plugin_init(plugin);


	    if(atoi(optarg) >= FTP_ABORT_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Abort plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    globus_ftp_client_test_abort_plugin_set_abort_point(plugin,
							        atoi(optarg));

	    globus_ftp_client_test_abort_plugin_set_abort_counter(
		plugin,
		&test_abort_count);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'p':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_DEBUG_PLUGIN_MODULE);
	    globus_ftp_client_debug_plugin_init(plugin, stderr, "[Debug Plugin]");

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'M':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PERF_PLUGIN_MODULE);
	    globus_ftp_client_test_perf_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'T':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_THROUGHPUT_PLUGIN_MODULE);
	    globus_ftp_client_test_throughput_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;

	case 'z':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PAUSE_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_pause_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'r':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_RESTART_PLUGIN_MODULE);
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_restart_plugin_init(plugin);
	    if(atoi(optarg) >= FTP_RESTART_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Restart plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    else
	    {
		char *p;
		p = strchr(optarg, ',');
		if(p)
		{
		    GlobusTimeReltimeSet(timeout, atoi(p+1),0);
		}
		else
		{
		    GlobusTimeReltimeSet(timeout, 0, 0);
		}
		globus_ftp_client_test_restart_plugin_set_restart_point(
		    plugin,
		    atoi(optarg),
		    &timeout);
		globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    }

	    break;
	case 's':
	    *src = optarg;
	    break;
	case 'd':
	    *dst = optarg;
	    break;
	case 'c':
	    if(!strcmp(optarg, "none"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_NONE;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else if(!strcmp(optarg, "self"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SELF;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SUBJECT;
		dcau.subject.subject = optarg;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    break;
	case 't':
	    if(!strcmp(optarg, "clear"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_CLEAR);
	    }
	    else if(!strcmp(optarg, "safe"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    }
	    else if(!strcmp(optarg, "private"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_PRIVATE);
	    }
	    break;
	case 'f':
	    globus_module_activate(GLOBUS_FTP_CLIENT_RESTART_PLUGIN_MODULE);
	    sscanf(optarg, "%d,%ld,%ld", &max_retries, &interval, &deadline);

	    if(interval < 0.1)
	    {
		GlobusTimeReltimeSet(interval_time, 0, 0);
	    }
	    else
	    {
		GlobusTimeReltimeSet(interval_time, interval, 0);
	    }
	    deadline_time.tv_sec = deadline;
	    deadline_time.tv_nsec = 0;

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_restart_plugin_init(plugin,
		                                  max_retries,
		                                  &interval_time,
						  &deadline_time);
	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    break;

	case 'i':
	    globus_ftp_client_operationattr_set_control_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    break;
	case '?':
        /*  globus_module_deactivate_all();
	    exit(0); 
	*/
	    break;
	}
    }
    
    subject = globus_libc_getenv("GLOBUS_FTP_CLIENT_TEST_SUBJECT");
    if(subject)
    {
        globus_ftp_client_operationattr_set_authorization(
            operation_attr,
            GSS_C_NO_CREDENTIAL,
            ":globus-mapping:",
            "",
            GLOBUS_NULL,
            subject);
    }
}
示例#16
0
int MPID_Type_struct(
    int					count,
    int					blocklens[],
    MPI_Aint				indices[],
    MPI_Datatype			oldtypes[],
    MPI_Datatype			newtype)
{
    int					rc;
    int					i;
    struct MPIR_DATATYPE *		newtype_ptr;
    globus_byte_t *			old_vmpi_types;
    
    DEBUG_FN_ENTRY(DEBUG_MODULE_TYPES);
    DEBUG_PRINTF(DEBUG_MODULE_TYPES, DEBUG_INFO_ARGS,
		 ("newtype=%d\n", newtype));

    rc = MPI_SUCCESS;

    old_vmpi_types = (globus_byte_t *)
	globus_libc_malloc(count * VENDOR_MPI_DATATYPE_SIZE);
    if (old_vmpi_types == NULL)
    {
	rc = MPI_ERR_EXHAUSTED;
	goto fn_exit;
    }

    newtype_ptr = MPIR_GET_DTYPE_PTR(newtype);
    MPID_Type_validate(newtype_ptr);

    for (i = 0; i < count; i++)
    {
	struct MPIR_DATATYPE *		dtype_ptr;
	
	dtype_ptr = MPIR_GET_DTYPE_PTR(oldtypes[i]);
	MPID_Type_validate(dtype_ptr);
	MPID_Type_validate_vmpi(dtype_ptr);

	memcpy(old_vmpi_types + i * VENDOR_MPI_DATATYPE_SIZE,
	       dtype_ptr->vmpi_type,
	       VENDOR_MPI_DATATYPE_SIZE);
    }

    rc = vmpi_error_to_mpich_error(
	mp_type_struct(count,
		       blocklens,
		       indices,
		       old_vmpi_types,
		       newtype_ptr->vmpi_type));

    globus_libc_free(old_vmpi_types);
    
    if (rc == MPI_SUCCESS)
    {
	newtype_ptr->vmpi_cookie = MPID_DATATYPE_COOKIE;
    }
    
  fn_exit:
    DEBUG_PRINTF(DEBUG_MODULE_TYPES, DEBUG_INFO_RC,
		 ("rc=%d\n", rc));
    DEBUG_FN_EXIT(DEBUG_MODULE_TYPES);
    return rc;
}
/*
 * Function: globus_handle_table_insert()
 *
 * Description: Insert a value into the handle table, and
 *              return a unique handle.
 *
 * Parameters:  handle_table - the table of unique handles
 *                  we want to use
 *              value - the value to insert into the table
 *              initial_refs - the initial reference count
 *                  of this value in the table.
 *
 * Returns:  A unique handle.
 */
globus_handle_t
globus_handle_table_insert(
    globus_handle_table_t *             e_handle_table,
    void *                              value,
    int                                 initial_refs)
{
    globus_l_handle_entry_t *           entry;
    globus_l_handle_table_t *		handle_table;

    if(!e_handle_table)
    {
        return GLOBUS_NULL_HANDLE;
    }

    handle_table = *e_handle_table;

    if(!handle_table)
    {
        return GLOBUS_NULL_HANDLE;
    }

    /* see if we have an inactive handle, if so, take it */
    if(handle_table->inactive)
    {
        entry = handle_table->inactive;
        handle_table->inactive = entry->pnext;
    }
    /* otherwise allocate a new entry */
    else
    {
        /* if table is full, make bigger */
        if(handle_table->next_slot == handle_table->table_size)
        {
            globus_l_handle_entry_t ** new_table;

            new_table = (globus_l_handle_entry_t **)
                globus_libc_realloc(
                    handle_table->table,
                    (handle_table->table_size + 
                        GLOBUS_L_HANDLE_TABLE_BLOCK_SIZE) *
                        sizeof(globus_l_handle_entry_t *));

            if(!new_table)
            {
                return GLOBUS_NULL_HANDLE;
            }

            handle_table->table = new_table;
            handle_table->table_size += GLOBUS_L_HANDLE_TABLE_BLOCK_SIZE;
        }

        entry = (globus_l_handle_entry_t *)
            globus_libc_malloc(sizeof(globus_l_handle_entry_t));
        if(!entry)
        {
            return GLOBUS_NULL_HANDLE;
        }

        entry->index = handle_table->next_slot++;
    }

    /* now bind this entry to table */
    handle_table->table[entry->index] = entry;

    entry->value = value;
    entry->ref = initial_refs;

    return entry->index;
}