globus_result_t
globus_xio_string_cntl_string_list(
    void *                              attr,
    const char *                        key,
    const char *                        val,
    int                                 cmd,
    globus_xio_driver_attr_cntl_t       cntl_func)
{
    int                                 i = 0;
    globus_list_t *                     val_list;
    globus_list_t *                     list;
    char **                             argv;
    int                                 argc;
    globus_result_t                     result;
    int                                 del;

    /* delimitor is the first character */
    if(val == NULL)
    {
        return GLOBUS_SUCCESS;
    }

    del = (int)*val;
    val++;

    val_list = globus_list_from_string(val, del, NULL);
    list = val_list;

    argc = globus_list_size(list);
    argv = (char **) calloc(argc+1, sizeof(char *));
    i = argc - 1;
    while(!globus_list_empty(list))
    {
        argv[i] = (char *)globus_list_first(list);
        list = globus_list_rest(list);
        i--;
    }

    result = globus_xio_string_cntl_bouncer(cntl_func, attr, cmd, argv);

    globus_list_destroy_all(val_list, globus_libc_free);
    globus_free(argv);
    
    return result;
}
void
globus_fifo_destroy_all(
    globus_fifo_t *                     fifo,
    void                                (*datum_free)(void *))
{
    struct globus_fifo_s *              s_fifo;
    
    if (fifo == GLOBUS_NULL) 
    {
        return;
    }
    
    s_fifo = *fifo;
    globus_list_destroy_all(s_fifo->head, datum_free);
    s_fifo->head = GLOBUS_NULL;
    s_fifo->tail = GLOBUS_NULL;
    s_fifo->size = 0;
    
    globus_free(s_fifo);
}
void
globus_usage_stats_handle_destroy(
    globus_usage_stats_handle_t         vhandle)
{
#ifndef TARGET_ARCH_ARM
    globus_i_usage_stats_handle_t *     handle =
    (globus_i_usage_stats_handle_t *) vhandle;

    if(handle)
    {
        if(handle->targets)
        {
            globus_list_destroy_all(handle->targets, globus_libc_free);
        }
    
        if(handle->xio_desc_list)
        {
            globus_xio_data_descriptor_t *  dd;
            
            while (!globus_list_empty (handle->xio_desc_list)) 
            {
                if((dd = globus_list_remove(
                    &handle->xio_desc_list, handle->xio_desc_list)) != NULL)
                {
                    globus_xio_data_descriptor_destroy(*dd);
                    globus_free(dd);
                }
            }
        }
        if(handle->xio_handle)
        {
            globus_xio_close(handle->xio_handle, NULL);
        }
        
        globus_mutex_destroy(&handle->mutex);

        globus_free(handle);
    }
#endif
}
/**
 * Free all memory allocated when the globus_gram_job_manager_config_init() was called.
 *
 * @param config
 *     Configuration structure destroy.
 */
void
globus_gram_job_manager_config_destroy(
    globus_gram_job_manager_config_t *  config)
{
    if (config->globus_location)
    {
        free(config->globus_location);
    }
    if (config->target_globus_location)
    {
        free(config->target_globus_location);
    }
    if (config->jobmanager_type)
    {
        free(config->jobmanager_type);
    }
    if (config->job_history_dir)
    {
        free(config->job_history_dir);
    }
    if (config->cache_location)
    {
        free(config->cache_location);
    }
    if (config->scratch_dir_base)
    {
        free(config->scratch_dir_base);
    }
    if (config->condor_arch)
    {
        free(config->condor_arch);
    }
    if (config->condor_os)
    {
        free(config->condor_os);
    }
    if (config->globus_gatekeeper_host)
    {
        free(config->globus_gatekeeper_host);
    }
    if (config->globus_gatekeeper_port)
    {
        free(config->globus_gatekeeper_port);
    }
    if (config->globus_gatekeeper_subject)
    {
        free(config->globus_gatekeeper_subject);
    }
    if (config->globus_host_manufacturer)
    {
        free(config->globus_host_manufacturer);
    }
    if (config->globus_host_cputype)
    {
        free(config->globus_host_cputype);
    }
    if (config->globus_host_osname)
    {
        free(config->globus_host_osname);
    }
    if (config->globus_host_osversion)
    {
        free(config->globus_host_osversion);
    }
    if (config->tcp_port_range)
    {
        free(config->tcp_port_range);
    }
    if (config->tcp_source_range)
    {
        free(config->tcp_source_range);
    }
    if (config->job_state_file_dir)
    {
        free(config->job_state_file_dir);
    }
    if (config->x509_cert_dir)
    {
        free(config->x509_cert_dir);
    }
    if (config->extra_envvars)
    {
        globus_list_destroy_all(config->extra_envvars, free);
    }
    if (config->seg_module)
    {
        free(config->seg_module);
    }
    if (config->auditing_dir)
    {
        free(config->auditing_dir);
    }
    if (config->globus_version)
    {
        free(config->globus_version);
    }
    if (config->usage_targets)
    {
        free(config->usage_targets);
    }
    /*
    if (config->log_pattern)
    {
        free(config->log_pattern);
    }
    */
    if (config->subject)
    {
        free(config->subject);
    }
    if (config->home)
    {
        free(config->home);
    }
    if (config->logname)
    {
        free(config->logname);
    }
    if (config->hostname)
    {
        free(config->hostname);
    }
    if (config->short_hostname)
    {
        free(config->short_hostname);
    }
    if (config->service_tag)
    {
        free(config->service_tag);
    }
    if (config->job_dir_home)
    {
        free(config->job_dir_home);
    }
}
static
globus_result_t
globus_l_xio_net_manager_attr_set_string_options(
    globus_l_xio_net_manager_attr_t    *attr,
    const char                         *options_string)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_list_t                      *options = NULL;
    globus_list_t                      *rev_options;
    int                                 num_options;
    globus_net_manager_attr_t          *new_attrs;
    globus_net_manager_context_t        new_context = NULL;
    char                               *scope = NULL;
    char                               *new_task_id = NULL;
    size_t                              attrnum = 0;

    rev_options = globus_list_from_string(options_string, ';', NULL);
    /* dislike that this func produces a reversed list */
    while (!globus_list_empty(rev_options))
    {
        globus_list_insert(
            &options, globus_list_remove(&rev_options, rev_options));
    }

    num_options = globus_list_size(options);

    if (num_options == 0)
    {
        goto no_options;
    }
    new_attrs = calloc(num_options+1, sizeof(globus_net_manager_attr_t));
    if (!new_attrs)
    {
        result = GlobusNetManagerErrorMemory("attr_array");
        goto new_attrs_calloc_fail;
    }
    while (!globus_list_empty(options))
    {
        char                           *opt, *val;

        opt = globus_list_remove(&options, options);
        if (*opt == '\0')
        {
            free(opt);
            continue;
        }
        val = strchr(opt, '=');
        if (!val)
        {
            result = GlobusNetManagerErrorParameter("Invalid option string.");
            free(opt);
            goto no_equals;
        }
        *val++ = '\0';

        if (strcmp(opt, "manager") == 0)
        {
            result = globus_net_manager_attr_init(
                    &new_attrs[attrnum++],
                    "net_manager",
                    opt,
                    val);
            if (result)
            {
                free(opt);
                new_attrs[attrnum-1] = globus_net_manager_null_attr;
                goto new_attr_init_fail;
            }
            free(scope);
            scope = strdup(val);
            if (!scope)
            {
                result = GlobusNetManagerErrorMemory("scope");
                free(opt);
                new_attrs[attrnum++] = globus_net_manager_null_attr;
                goto strdup_scope_fail;
            }
        }
        else if (strcmp(opt, "task-id") == 0)
        {
            free(new_task_id);
            new_task_id = strdup(val);
            if (!new_task_id)
            {
                result = GlobusNetManagerErrorMemory("task-id");
                free(opt);
                new_attrs[attrnum++] = globus_net_manager_null_attr;
                goto strdup_task_id_fail;
            }
        }
        else
        {
            result = globus_net_manager_attr_init(
                    &new_attrs[attrnum++],
                    scope ? scope : "global",
                    opt,
                    val);
            if (result)
            {
                free(opt);
                new_attrs[attrnum-1] = globus_net_manager_null_attr;
                goto new_attr_init_fail;
            }
        }
        free(opt);
    }
    new_attrs[attrnum++] = globus_net_manager_null_attr;
    if (new_attrs)
    {
        result = globus_net_manager_context_init(
            &new_context,
            new_attrs);
        if (result)
        {
            goto new_context_fail;
        }
        globus_net_manager_context_destroy(attr->context);
        attr->context = new_context;
    }

    if (new_task_id)
    {
        free(attr->task_id);
        attr->task_id = new_task_id;
        new_task_id = NULL;
    }
    if (new_attrs)
    {
        globus_net_manager_attr_array_delete(attr->attr_array);
        attr->attr_array = new_attrs;
        new_attrs = NULL;
    }

new_context_fail:
new_attr_init_fail:
strdup_task_id_fail:
strdup_scope_fail:
no_equals:
    free(new_task_id);
    free(scope);
    globus_net_manager_attr_array_delete(new_attrs);
new_attrs_calloc_fail:
    globus_list_destroy_all(options, free);
no_options:
    return result;
}