/** * 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 */
/** * 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, ¶llelism); 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); } }
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; }