static
void
globus_l_ftp_client_restart_plugin_third_party_transfer(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				source_url,
    const globus_ftp_client_operationattr_t *	source_attr,
    const char *				dest_url,
    const globus_ftp_client_operationattr_t *	dest_attr,
    globus_bool_t 				restart)
{
    globus_l_ftp_client_restart_plugin_t *	d;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    globus_l_ftp_client_restart_plugin_genericify(d);
    d->operation = GLOBUS_FTP_CLIENT_TRANSFER;
    d->source_url = globus_libc_strdup(source_url);
    globus_ftp_client_operationattr_copy(&d->source_attr, source_attr);
    d->dest_url = globus_libc_strdup(dest_url);
    globus_ftp_client_operationattr_copy(&d->dest_attr, dest_attr);

    if(d->source_attr->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK &&
        d->dest_attr->mode == GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK)
    {
        l_begin_xfer(handle, d);
    }
}
Beispiel #2
0
static
int
globus_l_usage_stats_split_targets(
    const char *                        targets_string,
    globus_list_t **                    targets)
{
    char *                              tmpstr;
    char *                              target;
    char *                              ptr;

    if(targets_string == NULL)
    {
        return -1;
    }
    
    tmpstr = globus_libc_strdup(targets_string);

    target = tmpstr;
    while((ptr = strchr(target, ',')) != NULL ||
            (ptr = strchr(target, ' ')) != NULL)
    {
        *ptr = '\0';
        globus_list_insert(targets, globus_libc_strdup(target)); 
        target = ptr + 1;
    }
    if(ptr == NULL)
    {
        globus_list_insert(targets, globus_libc_strdup(target)); 
    }               
        
    globus_free(tmpstr);             

    return 0;
}
globus_result_t
globus_gridftp_server_control_attr_init(
    globus_gridftp_server_control_attr_t *  in_attr)
{
    globus_i_gsc_attr_t *                   attr;
    globus_result_t                         res;
    GlobusGridFTPServerName(globus_gridftp_server_control_attr_init);

    GlobusGridFTPServerDebugEnter();

    if(in_attr == NULL)
    {
        res = GlobusGridFTPServerErrorParameter("in_attr");
        goto err;
    }

    attr = (globus_i_gsc_attr_t *) globus_calloc(
                1, sizeof(globus_i_gsc_attr_t));
    if(attr == NULL)
    {
        res = GlobusGridFTPServerControlErrorSytem();
        goto err;
    }

    globus_hashtable_init(
        &attr->funcs.send_cb_table,
        GLOBUS_GRIDFTP_SERVER_HASHTABLE_SIZE,
        globus_hashtable_string_hash,
        globus_hashtable_string_keyeq);

    globus_hashtable_init(
        &attr->funcs.recv_cb_table,
        GLOBUS_GRIDFTP_SERVER_HASHTABLE_SIZE,
        globus_hashtable_string_hash,
        globus_hashtable_string_keyeq);

    attr->funcs.resource_cb = NULL;
    attr->version_ctl = GLOBUS_GRIDFTP_VERSION_CTL;
    attr->modes = globus_libc_strdup("ES");
    attr->types = globus_libc_strdup("AI");
    attr->base_dir = globus_libc_strdup("/");

    *in_attr = attr;

    GlobusGridFTPServerDebugExit();

    return GLOBUS_SUCCESS;

  err:

    GlobusGridFTPServerDebugExitWithError();

    return res;
}
globus_result_t
globus_gridftp_server_control_attr_copy(
    globus_gridftp_server_control_attr_t *  dst,
    globus_gridftp_server_control_attr_t    src)
{
    globus_result_t                         res;
    globus_i_gsc_attr_t *                   attr;
    GlobusGridFTPServerName(globus_gridftp_server_control_attr_copy);

    if(dst == NULL)
    {
        res = GlobusGridFTPServerErrorParameter("dst");
        goto err;
    }
    if(src == NULL)
    {
        res = GlobusGridFTPServerErrorParameter("src");
        goto err;
    }
    if(src->version_ctl != GLOBUS_GRIDFTP_VERSION_CTL)
    {
        res = GlobusGridFTPServerErrorParameter("in_attr");
        goto err;
    }

    attr = (globus_i_gsc_attr_t *) globus_malloc(
                sizeof(globus_i_gsc_attr_t));
    if(attr == NULL)
    {
        res = GlobusGridFTPServerControlErrorSytem();
        goto err;
    }
    attr->version_ctl = src->version_ctl;
    attr->funcs.resource_cb = src->funcs.resource_cb;
    globus_hashtable_copy(
	    &attr->funcs.send_cb_table, &src->funcs.send_cb_table, NULL);
    globus_hashtable_copy(
        &attr->funcs.recv_cb_table, &src->funcs.recv_cb_table, NULL);
    attr->modes = globus_libc_strdup(src->modes);
    attr->types = globus_libc_strdup(src->types);

    *dst = attr;

    return GLOBUS_SUCCESS;

  err:

    GlobusGridFTPServerDebugExitWithError();

    return res;
}
static
void
globus_l_ftp_client_restart_plugin_cksm(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				url,
    globus_off_t				offset,
    globus_off_t				length,
    const char *				algorithm,
    const globus_ftp_client_operationattr_t *	attr,
    globus_bool_t 				restart)
{
    globus_l_ftp_client_restart_plugin_t *	d;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    globus_l_ftp_client_restart_plugin_genericify(d);
    d->operation = GLOBUS_FTP_CLIENT_CKSM;
    d->source_url = globus_libc_strdup(url);
    d->checksum_offset=offset;
    d->checksum_length=length;
    d->checksum_alg=algorithm;
    globus_ftp_client_operationattr_copy(&d->source_attr,attr);

}
static
void
globus_l_error_ftp_copy(
    void *                              src,
    void **                             dst)
{
    globus_l_error_ftp_data_t *         copy;
    globus_l_error_ftp_data_t *         source;
    
    if(src && dst)
    {
        copy = (globus_l_error_ftp_data_t *)
            globus_malloc(sizeof(globus_l_error_ftp_data_t));
        if(copy)
        {
            source = (globus_l_error_ftp_data_t *) src;
            
            copy->code = source->code;
            copy->message = source->message 
                ? globus_libc_strdup(source->message) : NULL;
        }
        
        *dst = copy;
    }
}
globus_result_t
stat_populate(char              * Name,
              int                 Type,
              int                 LinkCount,
              uint64_t            Size,
              char              * Owner,
              char              * ModTime,
              globus_gfs_stat_t * GFSStat)
{
	GlobusGFSName(stat_populate);

	memset(GFSStat, 0, sizeof(globus_gfs_stat_t));

	GFSStat->mode  = Type | S_IRWXU;
	GFSStat->nlink = LinkCount;
// XXX Inodes not supported
	GFSStat->ino   = 0xDEADBEEF;
// XXX UIDs not supported
//	XXX GFSStat->uid   = HpssStat->st_uid;
	GFSStat->gid   = 0; // Groups not supported
	GFSStat->dev   = 0;
	GFSStat->size  = Size;
	GFSStat->name  = globus_libc_strdup(Name);

	if (!ModTime)
	{
		GFSStat->atime = 0;
		GFSStat->mtime = 0;
		GFSStat->ctime = 0;
	} else
	{
		struct tm t;
		memset(&t, 0, sizeof(t));

		int ret = sscanf(ModTime, "%d-%d-%dT%d:%d:%d.", &t.tm_year,
		                                                &t.tm_mon,
		                                                &t.tm_mday,
		                                                &t.tm_hour,
		                                                &t.tm_min,
		                                                &t.tm_sec);
		if (ret != 6)
			return GlobusGFSErrorGeneric("Invalid time string");

		t.tm_year -= 1900;
		time_t time_of_day = mktime(&t);
		GFSStat->atime = time_of_day;
		GFSStat->mtime = time_of_day;
		GFSStat->ctime = time_of_day;
	}

	return GLOBUS_SUCCESS;
}
static
void
globus_l_ftp_client_restart_plugin_move(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				source_url,
    const char *				dest_url,
    const globus_ftp_client_operationattr_t *	attr,
    globus_bool_t 				restart)
{
    globus_l_ftp_client_restart_plugin_t *	d;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    globus_l_ftp_client_restart_plugin_genericify(d);
    d->operation = GLOBUS_FTP_CLIENT_MOVE;
    d->source_url = globus_libc_strdup(source_url);
    globus_ftp_client_operationattr_copy(&d->source_attr, attr);
    d->dest_url = globus_libc_strdup(dest_url);
    globus_ftp_client_operationattr_copy(&d->dest_attr, attr);
}
int
globus_extension_register_builtin(
    const char *                        extension_name,
    globus_module_descriptor_t *        module_descriptor)
{
    globus_l_extension_builtin_t *      builtin;
    GlobusFuncName(globus_extension_register_builtin);
    
    GlobusExtensionDebugEnterSymbol(extension_name);
    
    builtin = (globus_l_extension_builtin_t *)
        globus_malloc(sizeof(globus_l_extension_builtin_t));
    if(!builtin)
    {
        goto error_alloc;
    }
    
    builtin->owner = (globus_l_extension_module_t *)
        globus_thread_getspecific(globus_l_extension_owner_key);
    builtin->module = module_descriptor;
    builtin->extension_name = globus_libc_strdup(extension_name);
    if(!builtin->extension_name)
    {
        goto error_strdup;
    }
    
    globus_rmutex_lock(&globus_l_extension_mutex);
    {
        int                             rc;
        
        rc = globus_hashtable_insert(
            &globus_l_extension_builtins, builtin->extension_name, builtin);
        if(rc != 0)
        {
            goto error_insert;
        }
    }
    globus_rmutex_unlock(&globus_l_extension_mutex);
    
    GlobusExtensionDebugExit();
    return GLOBUS_SUCCESS;

error_insert:
    globus_rmutex_unlock(&globus_l_extension_mutex);
    globus_free(builtin->extension_name);
error_strdup:
    globus_free(builtin);
error_alloc:
    GlobusExtensionDebugExitWithError();
    return GLOBUS_FAILURE;
}
globus_result_t
globus_xio_driver_list_create_ent(
    const char *                        driver_desc,
    globus_xio_driver_t                 driver_in,
    globus_bool_t                       load,
    globus_xio_driver_list_ent_t **     ent_out)
{   
    globus_xio_driver_t                 driver;
    globus_xio_driver_list_ent_t *      list_ent;
    char *                              driver_name;
    char *                              opts;
    globus_result_t                     result;

    driver_name = strdup(driver_desc);
    opts = strchr(driver_name, ':');
    if(opts != NULL)
    {
        *opts = '\0';
        opts++; 
    }

    if(load)
    {
        result = globus_xio_driver_load(driver_name, &driver);
        if(result != GLOBUS_SUCCESS)
        {
            goto error_load;
        }
    }
    else
    {
        driver = driver_in;
    }

    list_ent = (globus_xio_driver_list_ent_t *)
        globus_calloc(1, sizeof(globus_xio_driver_list_ent_t));
    list_ent->opts = globus_libc_strdup(opts);
    list_ent->driver = driver;
    list_ent->driver_name = driver_name;
    list_ent->loaded = load;

    *ent_out = list_ent;

    return GLOBUS_SUCCESS;

error_load:
    globus_free(driver_name);
    return result;
}   
/**
 * Copy the contents of an HTTP response
 * @ingroup globus_i_xio_http_response
 *
 * All values associated with the @a src response will be copied
 * to the corresponding fields of the @a dest response. If this function
 * returns a failure, then the @a dest should be considered uninitialized.
 *
 * @param dest
 *     Response to be initialized with values from src. This should
 *     not be initialized before this is called, or memory may be
 *     leaked.
 * @param src
 *     Response containing known values.
 *
 * @retval GLOBUS_SUCCESS
 *     Response successfully copied.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Response copy failed due to memory constraints.
 */
globus_result_t
globus_i_xio_http_response_copy(
    globus_i_xio_http_response_t *      dest,
    const globus_i_xio_http_response_t *src)
{
    globus_result_t                     res = GLOBUS_SUCCESS;
    GlobusXIOName(globus_i_xio_http_response_copy);

    dest->status_code = src->status_code;

    if (src->reason_phrase == NULL)
    {
        dest->reason_phrase = NULL;
    }
    else
    {
        dest->reason_phrase = globus_libc_strdup(src->reason_phrase);
        if (dest->reason_phrase == NULL)
        {
            res = GlobusXIOErrorMemory("reason_phrase");

            goto error_exit;
        }
    }

    dest->http_version = src->http_version;

    res = globus_i_xio_http_header_info_copy(
            &dest->headers,
            &src->headers);

    if (res != GLOBUS_SUCCESS)
    {
        goto free_reason_phrase_exit;
    }

    return res;

free_reason_phrase_exit:
    if (dest->reason_phrase != NULL)
    {
        globus_libc_free(dest->reason_phrase);
        dest->reason_phrase = NULL;
    }
error_exit:
    return res;
}
globus_result_t
globus_gridftp_server_control_get_data_auth(
    globus_gridftp_server_control_op_t      op,
    char **                                 subject,
    char *                                  dcau,
    char *                                  prot,
    gss_cred_id_t *                         del_cred)
{
    GlobusGridFTPServerName(globus_gridftp_server_control_get_data_auth);

    if(op == NULL)
    {
        return GlobusGridFTPServerErrorParameter("op");
    }

    globus_mutex_lock(&op->server_handle->mutex);
    {
        if(subject != NULL)
        {
            if(op->server_handle->dcau_subject != NULL)
            {
                *subject = globus_libc_strdup(op->server_handle->dcau_subject);
            }
            else
            {
                *subject = NULL;
            }
        }
        if(dcau != NULL)
        {
            *dcau = op->server_handle->dcau;
        }
        if(prot != NULL)
        {
            *prot = op->server_handle->prot;
        }
        if(del_cred != NULL)
        {
            *del_cred = op->server_handle->del_cred;
        }        
    }
    globus_mutex_unlock(&op->server_handle->mutex);

    return GLOBUS_SUCCESS;
}
/**
 * Get an string describing why a request was denied.
 * @ingroup globus_gass_transfer_request
 *
 * This function queries a request which was denied by a server to
 * determine why it was denied. The denial reason will be expressed
 * as a response string. The string must be freed by the caller.
 *
 * @param request
 *        A handle to the request to query.
 *
 * @return A string indicating why the request
 *         was denied. If the request handle is invalid or the
 *         request was not denied, then this function returns GLOBUS_NULL.
 * @see globus_gass_transfer_request_get_denial_reason()
 */
char *
globus_gass_transfer_request_get_denial_message(
    globus_gass_transfer_request_t		request)
{
    globus_gass_transfer_request_struct_t *	req;

    req =
	globus_handle_table_lookup(&globus_i_gass_transfer_request_handles,
				   request);
    if(req == GLOBUS_NULL)
    {
	return GLOBUS_NULL;
    }
    else
    {
	return globus_libc_strdup(req->denial_message);
    }
}
/**
 * Extract referral information from a request handle.
 * @ingroup globus_gass_transfer_request
 *
 * This function queries the request handle to determine any referral
 * information that it contains. This function should only be called
 * on request handles in the GLOBUS_GASS_TRANSFER_REQUEST_REFERRED
 * state. If no referral information is stored in the request handle,
 * then the referral will be initialized to an empty referral.
 * The referral must be destroyed by calling
 * globus_gass_transfer_referral_destroy() by the caller.
 *
 * @param request
 *        The request handle to query.
 * @param referral
 *        A pointer to an uninitialized referral structure. It will be
 *        populated by calling this function.
 *
 * @retval GLOBUS_SUCCESS
 *         The referral was successfully extracted from the request
 *         handle.
 * @retval GLOBUS_GASS_TRANSFER_ERROR_NULL_POINTER
 *         The referral pointer was GLOBUS_NULL;
 */
int
globus_gass_transfer_request_get_referral(
    globus_gass_transfer_request_t		request,
    globus_gass_transfer_referral_t *		referral)
{
    globus_gass_transfer_request_struct_t *	req;

    /* Sanity check of arguments */
    if(referral == GLOBUS_NULL)
    {
	return GLOBUS_GASS_TRANSFER_ERROR_NULL_POINTER;
    }
    /* Check for illegal handle */
    req =
	globus_handle_table_lookup(&globus_i_gass_transfer_request_handles,
				   request);
    if(req == GLOBUS_NULL)
    {
	return GLOBUS_GASS_TRANSFER_ERROR_INVALID_USE;
    }
    else if(req->referral_count == 0)
    {
	referral->url = GLOBUS_NULL;
	referral->count = 0;

	return GLOBUS_SUCCESS;
    }
    else
    {
	globus_size_t				i;

	referral->url =
	    globus_malloc(sizeof(char *) * req->referral_count);

	for(i = 0; i < req->referral_count; i++)
	{
	    referral->url[i] = globus_libc_strdup(req->referral_url[i]);
	}
	referral->count = req->referral_count;

	return GLOBUS_SUCCESS;
    }
}
globus_result_t
globus_gridftp_server_control_get_cwd(
    globus_gridftp_server_control_t         server,
    char **                                 cwd_string)
{
    GlobusGridFTPServerName(globus_gridftp_server_control_get_cwd);

    if(server == NULL)
    {
        return GlobusGridFTPServerErrorParameter("server");
    }

    globus_mutex_lock(&server->mutex);
    {
        *cwd_string = globus_libc_strdup(server->cwd);
    }
    globus_mutex_unlock(&server->mutex);

    return GLOBUS_SUCCESS;
}
static
void
globus_l_ftp_client_restart_plugin_put(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				url,
    const globus_ftp_client_operationattr_t *	attr,
    globus_bool_t 				restart)
{
    globus_l_ftp_client_restart_plugin_t *	d;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    globus_l_ftp_client_restart_plugin_genericify(d);
    d->operation = GLOBUS_FTP_CLIENT_PUT;
    d->dest_url = globus_libc_strdup(url);
    globus_ftp_client_operationattr_copy(&d->dest_attr, attr);

    l_begin_xfer(handle, d);
}
static
void
restart_marker_plugin_fault_cb(
    globus_ftp_client_plugin_t *                plugin,
    void *                                      plugin_specific,
    globus_ftp_client_handle_t *                handle,
    const char *                                url,
    globus_object_t *                           error)
{
    restart_marker_plugin_info_t *              ps;

    ps = (restart_marker_plugin_info_t *) plugin_specific;

    if(ps->error_url || ps->error_obj)
    {
        /* already received error (before restart attempt) */
        return;
    }

    ps->error_url = globus_libc_strdup(url);
    ps->error_obj = globus_object_copy(error);
}
static
void
globus_l_ftp_client_restart_plugin_chmod(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				url,
    int                                         mode,
    const globus_ftp_client_operationattr_t *	attr,
    globus_bool_t 				restart)
{
    globus_l_ftp_client_restart_plugin_t *	d;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    globus_l_ftp_client_restart_plugin_genericify(d);
    d->operation = GLOBUS_FTP_CLIENT_CHMOD;
    d->source_url = globus_libc_strdup(url);
    d->chmod_file_mode = mode;
    globus_ftp_client_operationattr_copy(&d->source_attr,attr);

}
/**
 * Call a callout of specified abstract type
 * @ingroup globus_callout_call
 *
 * This function looks up the callouts corresponding to the given type and
 * invokes them with the passed arguments. If a invoked callout returns an
 * error it will be chained to a error of the type
 * GLOBUS_CALLOUT_ERROR_CALLOUT_ERROR and no more callouts will be called.
 *
 * @param handle
 *        A configured callout handle
 * @param type
 *        The abstract type of the callout that is to be invoked
 * @return
 *        GLOBUS_SUCCESS
 *        A Globus error object on failure:
 *            GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED
 *            GLOBUS_CALLOUT_ERROR_CALLOUT_ERROR
 *            GLOBUS_CALLOUT_ERROR_WITH_DL
 *            GLOBUS_CALLOUT_ERROR_WITH_HASHTABLE
 *            GLOBUS_CALLOUT_ERROR_OUT_OF_MEMORY
 */
globus_result_t
globus_callout_call_type(
    globus_callout_handle_t             handle,
    char *                              type,
    ...)
{
    globus_i_callout_data_t *           current_datum;
#ifdef BUILD_STATIC_ONLY
    void *                              function;
#else
    lt_ptr                              function;
    lt_dlhandle *                       dlhandle;
#endif
    globus_result_t                     result = GLOBUS_SUCCESS;
    va_list                             ap;
    int                                 rc;
    char *                              dlerror;
    char *                              flavor_start;
    char *                              file;
    char                                library[1024];
    char **                             save_env;
    int                                 i;
    globus_i_callout_data_t *           tmp_datum;
    int                                 mandatory_callouts_remaining = 0;
    static char *                       _function_name_ =
        "globus_callout_handle_call_type";
    GLOBUS_I_CALLOUT_DEBUG_ENTER;

    current_datum = globus_hashtable_lookup(&handle->symbol_htable,
                                            type);
    if(current_datum == NULL)
    {
        GLOBUS_CALLOUT_ERROR_RESULT(
            result,
            GLOBUS_CALLOUT_ERROR_TYPE_NOT_REGISTERED,
            ("unknown type: %s\n", type));
        goto exit;
    }
    
    tmp_datum = current_datum;
    while(tmp_datum)
    {
        if(tmp_datum->mandatory)
        {
            mandatory_callouts_remaining++;
        }
        tmp_datum = tmp_datum->next;
    }
    
    do
    {
#ifdef BUILD_STATIC_ONLY
        GLOBUS_CALLOUT_ERROR_RESULT(
            result,
            GLOBUS_CALLOUT_ERROR_WITH_DL,
            ("couldn't dlopen %s: %s\n",
             current_datum->file,
             "(null)"));
        goto exit;
#else
        dlhandle = globus_hashtable_lookup(&handle->library_htable,
                                           current_datum->file);

        if(dlhandle == NULL)
        {
            dlhandle = malloc(sizeof(lt_dlhandle));
            
            if(dlhandle == NULL)
            {
                GLOBUS_CALLOUT_MALLOC_ERROR(result);
            }
            
            *dlhandle = NULL;
            rc = globus_hashtable_insert(&handle->library_htable,
                                         current_datum->file,
                                         dlhandle);
            if(rc < 0)
            {
                free(dlhandle);
                GLOBUS_CALLOUT_ERROR_RESULT(
                    result,
                    GLOBUS_CALLOUT_ERROR_WITH_HASHTABLE,
                    ("globus_hashtable_insert retuned %d", rc));
                goto exit;
            }            
        }
    
        if(*dlhandle == NULL)
        {
            /* first time a symbol is referenced in this library ->
             * need to open it
             */
            
            *dlhandle = lt_dlopenext(current_datum->file);
            if(*dlhandle == NULL)
            {
                /* older libtools dont search the extensions correctly */
                snprintf(library, 1024, "%s" MY_LIB_EXT, current_datum->file);
                library[1023] = 0;
                *dlhandle = lt_dlopenext(library);
            }
            
            if(*dlhandle == NULL)
            {
                /* try again with flavor string removed */
                flavor_start = strrchr(current_datum->file, '_');
                if (flavor_start) {
                    file = strdup(current_datum->file);
                    if(file == NULL)
                        {
                            GLOBUS_CALLOUT_MALLOC_ERROR(result);
                            goto exit;
                        }
                    file[flavor_start - current_datum->file] = '\0';
                    *dlhandle = lt_dlopenext(file);
                    if(*dlhandle == NULL)
                    {
                        /* older libtools dont search the extensions correctly */
                        snprintf(library, 1024, "%s" MY_LIB_EXT, file);
                        library[1023] = 0;
                        *dlhandle = lt_dlopenext(library);
                    }
                    free(file);
                }
            }
            if(*dlhandle == NULL)
            {
                GLOBUS_CALLOUT_ERROR_RESULT(
                    result,
                    GLOBUS_CALLOUT_ERROR_WITH_DL,
                    ("couldn't dlopen %s: %s\n",
                     library,
                     (dlerror = lt_dlerror()) ? dlerror : 
                        "unknown error, possibly file not found."));
                goto exit;
            }
        }

        function = lt_dlsym(*dlhandle, current_datum->symbol);

        if(function == NULL)
        {
            GLOBUS_CALLOUT_ERROR_RESULT(
                result,
                GLOBUS_CALLOUT_ERROR_WITH_DL,
                ("symbol %s could not be found in %s: %s\n",
                 current_datum->symbol,
                 current_datum->file,
                 (dlerror = lt_dlerror()) ? dlerror : "(null)"));
            goto exit;
        }

        if(current_datum->env_args)
        {            
            save_env = globus_calloc(
                current_datum->num_env_args*2+1, sizeof(char *));

            i = 0;
            while(current_datum->env_args[i] != NULL && 
                current_datum->env_args[i+1] != NULL)
            {
                save_env[i] = current_datum->env_args[i];
                save_env[i+1] = 
                    globus_libc_strdup(getenv(current_datum->env_args[i]));
                setenv(current_datum->env_args[i], current_datum->env_args[i+1], 1);
                i += 2;
            }
            save_env[i] = NULL;
        }

        va_start(ap,type);
    
        result = ((globus_callout_function_t) function)(ap);
        
        va_end(ap);

        if(current_datum->env_args)
        {
            i = 0;            
            while(save_env[i] != NULL)
            {
                if(save_env[i+1] == NULL)
                {
                    unsetenv(save_env[i]);
                }
                else
                {
                    setenv(save_env[i], save_env[i+1], 1);
                    globus_free(save_env[i+1]);
                }
                                
                i += 2;
            }
            globus_free(save_env);
        }

        if(result == GLOBUS_SUCCESS)
        {
            if(current_datum->mandatory)
            {
                mandatory_callouts_remaining--;
            }
            
            if(!mandatory_callouts_remaining)
            {
                goto exit;
            }
        }
        
        if(result != GLOBUS_SUCCESS)
        {
            if(current_datum->mandatory)
            {
                GLOBUS_CALLOUT_ERROR_CHAIN_RESULT(
                    result,
                    GLOBUS_CALLOUT_ERROR_CALLOUT_ERROR);
                goto exit;
            }
            else if(current_datum->next == NULL)
            {
                /* chain error with stored error */
                GLOBUS_CALLOUT_ERROR_CHAIN_RESULT(
                    result,
                    GLOBUS_CALLOUT_ERROR_CALLOUT_ERROR);
                goto exit;
            }
            else
            {
                /* store error */
                result = GLOBUS_SUCCESS;
            }
        }

        current_datum = current_datum->next;
#endif
    }
    while(current_datum);
    
 exit:
    GLOBUS_I_CALLOUT_DEBUG_EXIT;
    return result;
}/*globus_callout_call_type*/
/**
 * Read callout configuration from file.
 * @ingroup globus_callout_config
 *
 * This function read a configuration file with the following format:
 *    - Anything after a '#' is assumed to be a comment
 *    - Blanks lines are ignored
 *    - Lines specifying callouts have the format
 *      abstract type           library         symbol
 *      where "abstract type" denotes the type of callout,
 *      e.g. globus_gram_jobmanager_authz, "library" denotes the library the
 *      callout can be found in and "symbol" denotes the function name of the
 *      callout. The library argument can be specified in two forms, libfoo or
 *      libfoo_<flavor>. When using the former version the current flavor will
 *      automatically be added to the library name. 
 *
 * @param handle
 *        The handle that is to be configured
 * @param filename
 *        The file to read configuration from
 * @return
 *        GLOBUS_SUCCESS
 *        A Globus error object on failure:
 *            GLOBUS_CALLOUT_ERROR_OPENING_CONF_FILE
 *            GLOBUS_CALLOUT_ERROR_PARSING_CONF_FILE
 *            GLOBUS_CALLOUT_ERROR_WITH_HASHTABLE
 *            GLOBUS_CALLOUT_ERROR_OUT_OF_MEMORY
 */
globus_result_t
globus_callout_read_config(
    globus_callout_handle_t             handle,
    char *                              filename)
{
    FILE *                              conf_file;
    char                                buffer[GLOBUS_I_CALLOUT_LINEBUF];
    char                                type[128];
    char                                library[256];
    char                                symbol[128];
    char *                              env_argstr;
    char **                             env_args;
    int                                 numpairs = 0;
    char *                              flavor_start;
    char *                              pound;
    int                                 index;
    int                                 rc;
    globus_result_t                     result;
    globus_i_callout_data_t *           datum = NULL;
    globus_i_callout_data_t *           existing_datum;
    

    static char *                       _function_name_ =
        "globus_callout_read_config";

    GLOBUS_I_CALLOUT_DEBUG_ENTER;
    
    conf_file = fopen(filename, "r");

    if(conf_file == NULL)
    {
        GLOBUS_CALLOUT_ERRNO_ERROR_RESULT(
            result,
            GLOBUS_CALLOUT_ERROR_OPENING_CONF_FILE,
            ("filename %s", filename));
        goto error_exit;
    }
    
    while(fgets(buffer,GLOBUS_I_CALLOUT_LINEBUF,conf_file))
    {
        if(!strchr(buffer, '\n'))
        {
            GLOBUS_CALLOUT_ERROR_RESULT(
                result,
                GLOBUS_CALLOUT_ERROR_PARSING_CONF_FILE,
                ("malformed line, line too long or missing newline"));
            goto error_exit;
        }

        /* strip any comments */
        pound = strchr(buffer, '#');

        if(pound != NULL)
        { 
            *pound = '\0';
        }

        /* strip white space from start */
        
        index = 0;

        while(buffer[index] == '\t' || buffer[index] == ' ')
        {
            index++;
        }

        /* if blank line continue */
        
        if(buffer[index] == '\0' || buffer[index] == '\n')
        { 
            continue;
        }
        
        if(sscanf(&buffer[index],"%127s%255s%127s",type,library,symbol) < 3)
        {
            GLOBUS_CALLOUT_ERROR_RESULT(
                result,
                GLOBUS_CALLOUT_ERROR_PARSING_CONF_FILE,
                ("malformed line: %s", &buffer[index]));
            goto error_exit;
        }
        
        /* check for ENV vars to set */
        env_argstr = strstr(buffer, "ENV:");
        if(env_argstr && strchr(env_argstr, '='))
        {
            int                         i;
            char *                      ptr;
            char *                      start;
            
            numpairs = 0;
            ptr = strchr(env_argstr, '=');
            while(ptr)
            {
                numpairs++;
                ptr++;
                if(*ptr == '"')
                {
                    ptr = strchr(ptr + 1, '"');
                    if(!ptr)
                    {
                        GLOBUS_CALLOUT_ERROR_RESULT(
                            result,
                            GLOBUS_CALLOUT_ERROR_PARSING_CONF_FILE,
                            ("malformed line, unmatched quote: %s", buffer));
                        goto error_exit;
                    }
                }
                ptr = strchr(ptr + 1, '=');
            }
            
            if(numpairs > 0)
            {
                env_args = globus_calloc(numpairs*2+1, sizeof(char *));
                
                start = env_argstr + 4;
                
                i = 0;
                while(start)
                {                    
                    /* skip initial space */
                    while(isspace(*start))
                    {
                        start++;
                    }
                    
                    /* find var name */
                    ptr = strchr(start, '=');
                    *ptr = '\0';
                    
                    if(strcspn(start, " \"=") != strlen(start))
                    {
                        GLOBUS_CALLOUT_ERROR_RESULT(
                            result,
                            GLOBUS_CALLOUT_ERROR_PARSING_CONF_FILE,
                            ("malformed line, invalid character in ENV var: %s", start));
                        goto error_exit;
                    }

                    env_args[i] = globus_libc_strdup(start);
                    
                    /* find value in quotes or before a space or end of line */
                    start = ++ptr;
                    
                    if(*start == '"')
                    {
                        start++;
                        ptr = strchr(start, '"');
                        *ptr = '\0';
                    }
                    else
                    {
                        ptr = strchr(start, ' ');
                        if(!ptr)
                        {
                            ptr = strchr(start, '\n');
                        }
                        *ptr = '\0';                        
                    }
                    env_args[i+1] = globus_libc_strdup(start);

                    ptr++;
                    while(*ptr && isspace(*ptr))
                    {
                        ptr++;
                    }
                    if(*ptr && strchr(ptr, '='))
                    {
                        start = ptr;
                    }
                    else
                    {
                        start = NULL;
                    }
                    
                    i += 2; 
                }
                env_args[i] = NULL;
            }
        }
        else
        {
            env_args = NULL;
        }
        
        /* push values into hash */
        datum = malloc(sizeof(globus_i_callout_data_t));

        if(datum == NULL)
        {
            GLOBUS_CALLOUT_MALLOC_ERROR(result);
            goto error_exit;
        }

        memset(datum,'\0',sizeof(globus_i_callout_data_t));

        /* check if library is flavored already */

        if((flavor_start = strrchr(library,'_')) &&
           (strstr(flavor_start, "32") || strstr(flavor_start, "64")))
        {
            datum->file = strdup(library);
            
            if(datum->file == NULL)
            {
                GLOBUS_CALLOUT_MALLOC_ERROR(result);
                goto error_exit;
            }
        }
        else
        { 
            datum->file = malloc(strlen(library) + 2 + strlen(flavor));
            if(datum->file == NULL)
            {
                GLOBUS_CALLOUT_MALLOC_ERROR(result);
                goto error_exit;
            }
            datum->file[0] = '\0';
            strcat(datum->file, library);
            strcat(datum->file, "_");
            strcat(datum->file, flavor);
        }
        
        datum->symbol = strdup(symbol);

        if(datum->symbol == NULL)
        {
            GLOBUS_CALLOUT_MALLOC_ERROR(result);
            goto error_exit;
        }
        
        if(*type == '|')
        {
            datum->mandatory = GLOBUS_FALSE;
            datum->type = strdup(type + 1);
        }
        else
        {
            datum->mandatory = GLOBUS_TRUE;
            datum->type = strdup(type);
        }

        if(datum->type == NULL)
        {
            GLOBUS_CALLOUT_MALLOC_ERROR(result);
            goto error_exit;
        }

        datum->env_args = env_args;
        datum->num_env_args = numpairs;

        if((rc = globus_hashtable_insert(&handle->symbol_htable,
                                         datum->type,
                                         datum)) == -1)
        {
            existing_datum = globus_hashtable_lookup(&handle->symbol_htable,
                                                     datum->type);
            while(existing_datum->next)
            {
                existing_datum = existing_datum->next;
            }
            existing_datum->next = datum;
        }
        else if(rc < 0)
        {
            GLOBUS_CALLOUT_ERROR_RESULT(
                result,
                GLOBUS_CALLOUT_ERROR_WITH_HASHTABLE,
                ("globus_hashtable_insert retuned %d", rc));
            goto error_exit;
        }
    }

    fclose(conf_file);
    
    GLOBUS_I_CALLOUT_DEBUG_EXIT;

    return GLOBUS_SUCCESS;

 error_exit:

    if(datum != NULL)
    {
        globus_l_callout_data_free(datum);
    }

    if(conf_file != NULL)
    {
        fclose(conf_file);
    }

    return result;
}/*globus_callout_read_config*/
static
globus_result_t
globus_l_extension_dlopen(
    const char *                        name,
    lt_dlhandle *                       handle)
{
    char                                library[1024];
    lt_dlhandle                         dlhandle;
    char *                              path;
    char *                              basename;
    char *                              search_path = NULL;
    char *                              save_path = NULL;
    globus_result_t                     result = GLOBUS_SUCCESS;
    GlobusFuncName(globus_l_extension_dlopen);
    
    path = globus_libc_strdup(name);
    if(path && (basename = strrchr(path, '/')))
    {
        *basename = 0;
        if(basename == path)
        {
            /* ignore root dir */
            name = path + 1;
        }
        else if(*(basename + 1) == 0)
        {
            /* ignore trailing slashes */
            name = path;
        }
        else
        {
            name = basename + 1;
            if(globus_l_globus_location)
            {
                /* if globus_location is not set, then it's likely I won't
                 * find the library
                 */
                search_path = globus_common_create_string(
                    "%s/%s", globus_l_globus_location, path);
            }
        }
    }
    
    globus_l_libtool_mutex_lock();
    
    if(search_path || globus_l_globus_location)
    {
        if((save_path = (char *) lt_dlgetsearchpath()))
        {
            /* libtool frees this pointer before setting the next one */
            save_path = globus_libc_strdup(save_path);
        }
    
        lt_dlsetsearchpath(
            search_path ? search_path : globus_l_globus_location);
    }
    
    snprintf(library, 1024, "lib%s", name);
    library[1023] = 0;
    dlhandle = lt_dlopenext(library);
    if(!dlhandle)
    {
        /* older libtools dont search the extensions correctly */
        snprintf(library, 1024, "lib%s" MY_LIB_EXT, name);
        library[1023] = 0;
        dlhandle = lt_dlopenext(library);
    }

#if USE_SYMBOL_LABELS
    if (!dlhandle)
    {
        snprintf(library, 1024, "lib%s_%s",
            name,
            (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr");
        library[1023] = 0;
        dlhandle = lt_dlopenext(library);

        if(!dlhandle)
        {
            /* older libtools dont search the extensions correctly */
            snprintf(library, 1024, "lib%s_%s" MY_LIB_EXT, name,
                (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr");
            library[1023] = 0;
            dlhandle = lt_dlopenext(library);
        }
    }
#endif

    if(!dlhandle)
    {
        const char *                error;
        
        error = lt_dlerror();
        
        GlobusExtensionDebugPrintf(
            GLOBUS_L_EXTENSION_DEBUG_DLL,
            (_GCSL("[%s] Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n"),
             _globus_func_name, library,
             search_path ? search_path : globus_l_globus_location 
                ? globus_l_globus_location : "(default)",
             error ? error : "(null)"));
        result = globus_error_put(
            globus_error_construct_error(
                GLOBUS_EXTENSION_MODULE,
                NULL,
                GLOBUS_EXTENSION_ERROR_OPEN_FAILED,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n",
                library,
                (search_path ? search_path : 
                               (globus_l_globus_location ? 
                                    globus_l_globus_location : 
                                "(default)")),
                error ? error : "(null)"));
    }
    
    if(search_path || globus_l_globus_location)
    {
        lt_dlsetsearchpath(save_path);
        if(save_path)
        {
            globus_free(save_path);
        }
    }
    globus_l_libtool_mutex_unlock();
    
    if(search_path)
    {
        globus_free(search_path);
    }
    
    if(path)
    {
        globus_free(path);
    }
    
    *handle = dlhandle;
    return result;
}
/* driver list stuff */
globus_result_t
globus_xio_driver_list_from_string(
    char *                              driver_string,
    globus_list_t **                    driver_list,
    globus_hashtable_t *                safe_table)
{
    globus_result_t                     result;
    globus_bool_t                       done = GLOBUS_FALSE;
    globus_bool_t                       loaded;
    char *                              opts;
    char *                              ptr;
    char *                              driver_str;
    char *                              driver_name;
    char *                              tmp_str;
    globus_xio_driver_t                 driver;
    globus_list_t *                     list = NULL;
    globus_xio_driver_list_ent_t *      list_ent;
    GlobusXIOName(globus_xio_driver_list_from_string);

    *driver_list = NULL;

    if(driver_string == NULL) 
    {
        result = GlobusXIOErrorParameter("driver_string");
        goto error_param;
    }

    driver_str = globus_libc_strdup(driver_string);
    tmp_str = driver_str;
    while(!done)
    {
        loaded = GLOBUS_FALSE;
        driver_name = tmp_str;
        ptr = strchr(driver_name, ',');
        if(ptr != NULL)
        {
            *ptr = '\0';
            tmp_str = ptr+1;
        }
        else
        {
            done = GLOBUS_TRUE;
        }
        opts = strchr(driver_name, ':');
        if(opts != NULL)
        {
            *opts = '\0';
            opts++;

            /* decode the string */
            globus_url_string_hex_decode(opts);
        }

        /* check against the safe list */
        if(safe_table != NULL)
        {
            char *                      err_str;

            list_ent = (globus_xio_driver_list_ent_t *)
                globus_hashtable_lookup(safe_table, driver_name);

            if(list_ent == NULL)
            {
                err_str = globus_common_create_string(
                    "%s driver not whitelisted", driver_name);
                result = GlobusXIOErrorParameter(err_str);
                globus_free(err_str);
                goto error_load;
            }
            driver = list_ent->driver;
        }
        else
        {
            result = globus_xio_driver_load(driver_name, &driver);
            if(result != GLOBUS_SUCCESS)
            {
                goto error_load;
            }

            loaded = GLOBUS_TRUE;
        }

        list_ent = (globus_xio_driver_list_ent_t *)
            globus_calloc(1, sizeof(globus_xio_driver_list_ent_t));
        list_ent->opts = globus_libc_strdup(opts);
        list_ent->driver = driver;
        list_ent->driver_name = globus_libc_strdup(driver_name);
        list_ent->loaded = loaded;

        globus_list_insert(&list, list_ent);
    }

    globus_free(driver_str);

    /* reverse list */
    while(!globus_list_empty(list))
    {
        globus_list_insert(driver_list, globus_list_first(list));
        globus_list_remove(&list, list);
    }

    return GLOBUS_SUCCESS;

error_load:
    globus_free(driver_str);
    while(!globus_list_empty(list))
    {
        list_ent = (globus_xio_driver_list_ent_t *)
            globus_list_remove(&list, list);

        if(list_ent->loaded)
        {
            globus_xio_driver_unload(list_ent->driver);
        }
        globus_free(list_ent->driver_name);
        if(list_ent->opts != NULL)
        {
            globus_free(list_ent->opts);
        }
        globus_free(list_ent);
    }
error_param:
    return result;
}
int main(
    int                                 argc,
    char *                              argv[])
{
    int					rc;
    char *				server_callback_contact;
    globus_byte_t *			msg;
    globus_size_t			msgsize;
    monitor_t 				monitor;

    rc = globus_module_activate(GLOBUS_GRAM_PROTOCOL_MODULE);
    if(rc != GLOBUS_SUCCESS)
    {
	return rc;
    }

    globus_mutex_init(&monitor.mutex, GLOBUS_NULL);
    globus_mutex_lock(&monitor.mutex);
    globus_cond_init(&monitor.cond, GLOBUS_NULL);
    monitor.done = GLOBUS_FALSE;
    monitor.status_request[0] = "status";
    monitor.status_request[1] = NULL;
    monitor.job_status[1] = GLOBUS_GRAM_PROTOCOL_JOB_STATE_ACTIVE;
    monitor.failure_code[1] = 0;
    monitor.job_failure_code[1] = 0;
    monitor.error = 0;

    rc = globus_gram_protocol_allow_attach(
	    &server_callback_contact,
	    server_callback,
	    &monitor);

    if(rc != GLOBUS_SUCCESS)
    {
	goto unlock_error;
    }

    rc = globus_gram_protocol_pack_status_request(
	    monitor.status_request[0],
	    &msg,
	    &msgsize);

    if(rc != GLOBUS_SUCCESS)
    {
	goto disallow_error;
    }

    if (argc > 1 && !strcmp(argv[1], "invalid_host"))
    {
        globus_free(server_callback_contact);
        server_callback_contact = globus_libc_strdup(
                "https://bogushost.globus.org:7777/7777");
    }

    rc = globus_gram_protocol_post(server_callback_contact,
	                           GLOBUS_NULL,
				   GLOBUS_NULL,
				   msg,
				   msgsize,
				   client_callback,
				   &monitor);
    if(rc != GLOBUS_SUCCESS)
    {
	goto free_msg_error;
    }

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

    globus_libc_free(msg);
    globus_mutex_unlock(&monitor.mutex);
    globus_mutex_destroy(&monitor.mutex);
    globus_cond_destroy(&monitor.cond);

    if(monitor.job_status[0] != monitor.job_status[1] ||
       monitor.failure_code[0] != monitor.failure_code[1] ||
       monitor.job_failure_code[0] != monitor.job_failure_code[1] ||
       strcmp(monitor.status_request[0], monitor.status_request[1]) != 0)
    {
	fprintf(stderr, "transmission error.\n");

	monitor.error++;
    }
    globus_libc_free(monitor.status_request[1]);
    globus_gram_protocol_callback_disallow(server_callback_contact);
    globus_module_deactivate(GLOBUS_GRAM_PROTOCOL_MODULE);

    return monitor.error;

free_msg_error:
    globus_libc_free(msg);
disallow_error:
    globus_gram_protocol_callback_disallow(server_callback_contact);
unlock_error:
    globus_mutex_unlock(&monitor.mutex);
    globus_mutex_destroy(&monitor.mutex);
    globus_cond_destroy(&monitor.cond);
    globus_module_deactivate(GLOBUS_GRAM_PROTOCOL_MODULE);
    return rc;
}
/**
 * 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;
}
/**
 * Initialize a gass_transfer request handle.
 *
 * This function creates a #globus_gass_transfer_request_struct_t and
 * associates it with a #gass_transfer_request_t handle. The structure
 * is initialized with the information passed as the arguments to the
 * function.
 *
 * @note This function must be called with the request handle mutex lock.
 *
 * @param request
 *        The request handle to initialize. If this function is successful, 
 *        the value pointed to by this will be initialized to the new
 *        handle id; otherwise, the it will be set to 
 *        GLOBUS_NULL_HANDLE.
 * @param attr
 *        The request attributes to use to create the handle. If non-NULL,
 *        they are copied into the request structure.
 * @param url
 *        An URL string containing the location of the file to access. A
 *        copy of this is stored in the request handle.
 * @param type
 *        The type of file transfer that this request will be used for.
 * @param callback
 *        The callback function to be called once the request is in the
 *        ready state.
 * @param user_arg
 *        User-supplied argument to the callback function.
 *
 * @retval void
 */
void
globus_i_gass_transfer_request_init(
    globus_gass_transfer_request_t *            request,
    globus_gass_transfer_requestattr_t *        attr,
    char *                                      url,
    globus_gass_transfer_request_type_t         type,
    globus_gass_transfer_callback_t             callback,
    void *                                      user_arg)
{
    globus_gass_transfer_request_struct_t *	req;

    req = globus_malloc(sizeof(globus_gass_transfer_request_struct_t));
    if(req == GLOBUS_NULL)
    {
	goto error_exit;
    }

    if(url)
    {
	req->url = globus_libc_strdup(url);
        if(req->url == GLOBUS_NULL)
        {
	    goto free_req;
        }
    }
    else
    {
	req->url = GLOBUS_NULL;
    }
    req->type			= type;
    req->status			= GLOBUS_GASS_TRANSFER_REQUEST_STARTING;
    req->referral_url		= GLOBUS_NULL;
    req->referral_count		= 0;
    req->callback		= callback;
    req->callback_arg		= user_arg;
    req->proto			= GLOBUS_NULL;
    req->subject		= GLOBUS_NULL;
    req->denial_reason		= 0;
    req->denial_message		= GLOBUS_NULL;
    req->handled_length		= 0;
    req->posted_length		= 0;
    req->fail_callback		= GLOBUS_NULL;
    req->client_side		= GLOBUS_FALSE;
    req->user_pointer		= GLOBUS_NULL;

    globus_fifo_init(&req->pending_data);
    if(attr)
    {
	if(*attr)
	{
	    req->attr = globus_object_copy(*attr);
	    if(req->attr == GLOBUS_NULL)
	    {
	        goto free_fifo;
	    }
	}
	else
	{
	    req->attr = GLOBUS_NULL;
	}
    }
    else
    {
	req->attr = GLOBUS_NULL;
    }

    *request = globus_handle_table_insert(&globus_i_gass_transfer_request_handles,
					  (void *) req,
					  2);
    globus_list_insert(&globus_i_gass_transfer_requests,
		       (void *) (intptr_t) (*request));
    
    return;

  free_fifo:
    globus_fifo_destroy(&req->pending_data);
    globus_free(req->url);
  free_req:
    globus_free(req);
  error_exit:
    *request = GLOBUS_NULL_HANDLE;
    return;
}
globus_object_t *
globus_i_ftp_client_wrap_ftp_error(
    globus_module_descriptor_t *        base_source,
    int                                 code,
    const char *                        message,
    int                                 error_type,
    const char *                        source_file,
    const char *                        source_func,
    int                                 source_line,
    const char *                        format,
    ...)
{
    va_list                             ap;
    globus_object_t *                   error;
    globus_object_t *                   causal_error;
    globus_l_error_ftp_data_t *         data;

    causal_error = globus_object_construct(GLOBUS_ERROR_TYPE_FTP);
    if(!causal_error)
    {
        goto error_object;
    }
    
    data = (globus_l_error_ftp_data_t *)
        globus_malloc(sizeof(globus_l_error_ftp_data_t));
    if(!data)
    {
        goto error_data;
    }
    
    data->code = code;
    data->message = globus_libc_strdup(message);
    globus_object_set_local_instance_data(causal_error, data);
    globus_error_initialize_base(causal_error, base_source, NULL);

    va_start(ap, format);

    error = globus_error_v_construct_error(
        base_source,
        causal_error,
        error_type,
        source_file,
        source_func,
        source_line,
        format,
        ap);

    va_end(ap);

    if(!error)
    {
        goto error_construct;
    }

    return error;

error_construct:
error_data:
    globus_object_free(causal_error);

error_object:
    return NULL;
}
static globus_result_t
session_copy_session_info(globus_gfs_session_info_t * Source,
                          globus_gfs_session_info_t * Destination)
{
	globus_result_t result = GLOBUS_SUCCESS;

	GlobusGFSName(__func__);
	GlobusGFSHpssDebugEnter();

	memset(Destination, 0, sizeof(globus_gfs_session_info_t));

	Destination->del_cred  = Source->del_cred;
	Destination->free_cred = Source->free_cred;
	Destination->map_user  = Source->map_user;

	if (Source->username != NULL)
	{
		Destination->username = globus_libc_strdup(Source->username);
		if (Destination->username == NULL)
		{
			result = GlobusGFSErrorMemory("session info");
			goto cleanup;
		}
	}

	if (Source->password != NULL)
	{
		Destination->password = globus_libc_strdup(Source->password);
		if (Destination->password == NULL)
		{
			result = GlobusGFSErrorMemory("session info");
			goto cleanup;
		}
	}

	if (Source->subject != NULL)
	{
		Destination->subject = globus_libc_strdup(Source->subject);
		if (Destination->subject == NULL)
		{
			result = GlobusGFSErrorMemory("session info");
			goto cleanup;
		}
	}

	if (Source->cookie != NULL)
	{
		Destination->cookie = globus_libc_strdup(Source->cookie);
		if (Destination->cookie == NULL)
		{
			result = GlobusGFSErrorMemory("session info");
			goto cleanup;
		}
	}

	if (Source->host_id != NULL)
	{
		Destination->host_id = globus_libc_strdup(Source->host_id);
		if (Destination->host_id == NULL)
		{
			result = GlobusGFSErrorMemory("session info");
			goto cleanup;
		}
	}

cleanup:
	if (result != GLOBUS_SUCCESS)
	{
		session_destroy_session_info(Destination);
		GlobusGFSHpssDebugExitWithError();
		return result;
	}

	GlobusGFSHpssDebugExit();
	return GLOBUS_SUCCESS;
}
/**
 * Modify the state of an HTTP handle
 * @ingroup globus_i_xio_http_handle
 *
 * Modify the state of an HTTP handle. This is called by the XIO driver via
 * globus_xio_handle_cntl().
 *
 * @param handle
 *     Void pointer to a #globus_i_xio_http_handle_t structure containing
 *     information an HTTP request/response transaction.
 * @param cmd
 *     Integer value indicating what command will be executed on the handle.
 *     Valid command values are in the set defined by
 *     #globus_xio_http_handle_cmd_t.
 * @param ap
 *     Variable-length argument list containing any cmd-specific parameters.
 *
 * @retval GLOBUS_SUCCESS
 *     The command was sucessfully executed.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     The command failed due to memory constraints.
 * @retval GLOBUS_XIO_ERROR_PARAMETER
 *     Invalid @a cmd parameter or invlaid value of cmd-specific parameters 
 *     in @a ap
 */
globus_result_t
globus_i_xio_http_handle_cntl(
    void *                              handle,
    int                                 cmd,
    va_list                             ap)
{
    char *                              in_header_name;
    char *                              in_header_value;
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_i_xio_http_handle_t *        http_handle = handle;
    char *                              in_str;
    char *                              in_str2;
    char *                              save_str;
    int                                 in_int;
    GlobusXIOName(globus_i_xio_http_handle_cntl);

    globus_mutex_lock(&http_handle->mutex);

    switch (cmd)
    {
        case GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER:
            if (http_handle->target_info.is_client)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }

            if (http_handle->send_state != GLOBUS_XIO_HTTP_STATUS_LINE)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }
            in_str = va_arg(ap, char *);
            in_str2 = va_arg(ap, char *);

            result = globus_i_xio_http_header_info_set_header(
                    &http_handle->response_info.headers,
                    in_str,
                    in_str2);

            break;

        case GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE:
            if (http_handle->target_info.is_client)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }

            if (http_handle->send_state != GLOBUS_XIO_HTTP_STATUS_LINE)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }
            in_int = va_arg(ap, int);

            if (in_int < 100 || in_int > 599)
            {
                result = GlobusXIOErrorParameter("status_code");
                break;
            }

            http_handle->response_info.status_code = in_int;

            break;

        case GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_REASON_PHRASE:
            if (http_handle->target_info.is_client)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }

            if (http_handle->send_state != GLOBUS_XIO_HTTP_STATUS_LINE)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }
            in_str = va_arg(ap, char *);

            if (in_str == NULL)
            {
                result = GlobusXIOErrorParameter("reason_phrase");
            }
            save_str = http_handle->response_info.reason_phrase;

            http_handle->response_info.reason_phrase =
                    globus_libc_strdup(in_str);

            if (http_handle->response_info.reason_phrase == NULL)
            {
                result = GlobusXIOErrorMemory("reason_phrase");
                break;
            }

            if (save_str)
            {
                globus_libc_free(save_str);
            }
            break;
        case GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HTTP_VERSION:
            if (http_handle->target_info.is_client)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }

            if (http_handle->send_state != GLOBUS_XIO_HTTP_STATUS_LINE)
            {
                result = GlobusXIOErrorParameter("handle");
                break;
            }

            http_handle->response_info.http_version =
                    va_arg(ap, globus_xio_http_version_t);
            break;
        case GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY:
            result = globus_i_xio_http_set_end_of_entity(http_handle);

            break;

        case GLOBUS_XIO_HTTP_HANDLE_SET_REQUEST_HEADER:
            in_header_name = va_arg(ap, char *);
            if (in_header_name == NULL)
            {
                result = GlobusXIOErrorParameter("name");
                break;
            }

            in_header_value = va_arg(ap, char *);
            if (in_header_value == NULL)
            {
                result = GlobusXIOErrorParameter("value");
                break;
            }

            result = globus_i_xio_http_header_info_set_header(
                    &http_handle->request_info.headers,
                    in_header_name,
                    in_header_value);
            break;

        default:
            result = GlobusXIOErrorParameter("cmd");
            break;
    }
    globus_mutex_unlock(&http_handle->mutex);
    return result;
}
/**
 * Modify the state of an HTTP attribute
 * @ingroup globus_i_xio_http_attr
 *
 * Modify the state of an attribute. This is called by the XIO driver via
 * globus_xio_attr_cntl().
 *
 * @param driver_attr
 *     Void pointer to a #globus_i_xio_http_attr_t structure containing
 *     the attribute's values.
 * @param cmd
 *     Integer value indicating which attribute will be changed. Valid
 *     commands values are in the set defined by  #globus_xio_http_attr_cmd_t
 * @param ap
 *     Variable-length argument list containing any cmd-specific parameters.
 *
 * @retval GLOBUS_SUCCESS
 *     Attribute successfully modified.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Attribute control failed due to memory constraints.
 * @retval GLOBUS_XIO_ERROR_PARAMETER
 *     Invalid @a cmd parameter or invalid value for cmd-specific parameters
 *     in @a ap.
 */
globus_result_t
globus_i_xio_http_attr_cntl(
    void *                              driver_attr,
    int                                 cmd,
    va_list                             ap)
{
    globus_result_t                     res = GLOBUS_SUCCESS;
    globus_i_xio_http_attr_t *          attr = driver_attr;
    char *                              in_string;
    char *                              save_string;
    globus_xio_http_version_t           in_http_version;
    char *                              in_header_name;
    char *                              in_header_value;
    char **                             out_method;
    char **                             out_uri;
    globus_xio_http_version_t *         out_http_version;
    globus_hashtable_t *                out_headers;
    int *                               out_status_code;
    char **                             out_reason_phrase;

    GlobusXIOName(globus_i_xio_http_attr_cntl);

    switch (cmd)
    {
        case GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_METHOD:
            save_string = attr->request.method;

            in_string = va_arg(ap, char *);

            if (in_string == NULL)
            {
                res = GlobusXIOErrorParameter("method");
                break;
            }

            attr->request.method = globus_libc_strdup(in_string);
            if (attr->request.method == NULL)
            {
                attr->request.method = save_string;
                res = GlobusXIOErrorMemory("method");
                break;
            }

            if (save_string != NULL)
            {
                globus_libc_free(save_string);
            }
            break;

        case GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HTTP_VERSION:
            in_http_version = va_arg(ap, globus_xio_http_version_t);

            if (in_http_version != GLOBUS_XIO_HTTP_VERSION_1_0 &&
                    in_http_version != GLOBUS_XIO_HTTP_VERSION_1_1)
            {
                res = GlobusXIOErrorParameter("version");
                break;
            }
            attr->request.http_version = in_http_version;
            break;

        case GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER:
            in_header_name = va_arg(ap, char *);
            if (in_header_name == NULL)
            {
                res = GlobusXIOErrorParameter("name");
                break;
            }

            in_header_value = va_arg(ap, char *);
            if (in_header_value == NULL)
            {
                res = GlobusXIOErrorParameter("value");
                break;
            }

            res = globus_i_xio_http_header_info_set_header(
                    &attr->request.headers,
                    in_header_name,
                    in_header_value,
                    GLOBUS_FALSE);
            break;

        case GLOBUS_XIO_HTTP_ATTR_DELAY_WRITE_HEADER:
            attr->delay_write_header = 1;
            break;

        case GLOBUS_XIO_HTTP_GET_REQUEST:
            out_method = va_arg(ap, char **);
            out_uri = va_arg(ap, char **);
            out_http_version = va_arg(ap, globus_xio_http_version_t *);
            out_headers = va_arg(ap, globus_hashtable_t *);

            if (out_method != NULL)
            {
                *out_method = attr->request.method;
            }
            if (out_uri != NULL)
            {
                *out_uri = attr->request.uri;
            }
            if (out_http_version != NULL)
            {
                *out_http_version = attr->request.http_version;
            }
            if (out_headers != NULL)
            {
                *out_headers = attr->request.headers.headers;
            }
            break;
        case GLOBUS_XIO_HTTP_GET_RESPONSE:
            out_status_code = va_arg(ap, int *);
            out_reason_phrase = va_arg(ap, char **);
            out_http_version = va_arg(ap, globus_xio_http_version_t *);
            out_headers = va_arg(ap, globus_hashtable_t *);

            if (out_status_code != NULL)
            {
                *out_status_code = attr->response.status_code;
            }
            if (out_reason_phrase != NULL)
            {
                *out_reason_phrase = attr->response.reason_phrase;
            }
            if (out_http_version != NULL)
            {
                *out_http_version = attr->response.http_version;
            }
            if (out_headers != NULL)
            {
                *out_headers = attr->response.headers.headers;
            }
            break;
        default:
            res = GlobusXIOErrorParameter("cmd");
    }

    return res;
}
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;
}