globus_result_t
globus_i_gsi_cred_error_join_chains_result(
    globus_result_t                     outter_error,
    globus_result_t                     inner_error)
{
    globus_result_t                     result;
    globus_object_t *                   result_error_obj = NULL;
    globus_object_t *                   outter_error_obj = NULL;
    globus_object_t *                   inner_error_obj = NULL;
    globus_object_t *                   temp_error_obj = NULL;
    static char *                       _function_name_ =
        "globus_i_gsi_cred_error_join_chains";
    GLOBUS_I_GSI_CRED_DEBUG_ENTER;

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

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

    result = globus_error_put(result_error_obj);

    GLOBUS_I_GSI_CRED_DEBUG_EXIT;
    return result;
}
コード例 #2
0
globus_result_t
globus_i_gsi_gssapi_error_chain_result(
    globus_result_t                     chain_result,
    int                                 error_type,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_result_t                     result;
    globus_object_t *                   error_object;
    
    static char *                       _function_name_ =
        "globus_i_gsi_gssapi_error_chain_result";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_GSSAPI_INTERNAL_DEBUG_EXIT;
    return result;
}
コード例 #3
0
globus_result_t
globus_i_gsi_cert_utils_error_chain_result(
    globus_result_t                     chain_result,
    int                                 error_type,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_object_t *                   error_object;
    globus_result_t                     result;

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

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_CERT_UTILS_DEBUG_EXIT;

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

    static char *                       _function_name_ =
        "globus_i_gsi_sysconfig_error_result";

    GLOBUS_I_GSI_SYSCONFIG_DEBUG_ENTER;

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

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_SYSCONFIG_DEBUG_EXIT;

    return result;
}
コード例 #5
0
globus_result_t
globus_i_gsi_gssapi_error_result(
    const OM_uint32                     minor_status,
    const char *                        filename,
    const char *                        function_name,
    int                                 line_number,
    const char *                        short_desc,
    const char *                        long_desc)
{
    globus_object_t *                   error_object;
    globus_result_t                     result;

    static char *                       _function_name_ =
        "globus_i_gsi_gssapi_error_result";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

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

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

    result = globus_error_put(error_object);

    GLOBUS_I_GSI_GSSAPI_INTERNAL_DEBUG_EXIT;
    return result;
}
コード例 #6
0
static
void
globus_l_popen_waitpid(
    xio_l_popen_handle_t *              handle,
    int                                 opts)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    int                                 status;
    int                                 rc;
    globus_reltime_t                    delay;
    GlobusXIOName(globus_l_popen_waitpid);

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

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

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

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

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

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

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

#endif
    GlobusXIOPOpenDebugExit();
}
コード例 #7
0
int
globus_extension_activate(
    const char *                        extension_name)
{
    globus_l_extension_module_t *       extension;
    globus_l_extension_module_t *       last_extension;
    globus_l_extension_builtin_t *      builtin;
    int                                 rc;
    globus_result_t                     result = GLOBUS_FAILURE;
    GlobusFuncName(globus_extension_activate);
    
    GlobusExtensionDebugEnterSymbol(extension_name);
    
    if(!extension_name)
    {
        goto error_param;
    }
    
    globus_rmutex_lock(&globus_l_extension_mutex);
    {
        extension = (globus_l_extension_module_t *)
            globus_hashtable_lookup(
                &globus_l_extension_loaded, (void *) extension_name);
        if(!extension)
        {
            extension = (globus_l_extension_module_t *)
                globus_malloc(sizeof(globus_l_extension_module_t));
            if(!extension)
            {
                goto error_alloc;
            }
            
            extension->module_ref = 1;
            extension->ref = 1;
            extension->name = globus_libc_strdup(extension_name);
            if(!extension->name)
            {
                goto error_strdup;
            }
            
            builtin = (globus_l_extension_builtin_t *)
                globus_hashtable_lookup(
                    &globus_l_extension_builtins, (void *) extension_name);
            if(builtin && (!builtin->owner || builtin->owner->module_ref > 0))
            {
#               if !defined(BUILD_STATIC_ONLY)
                {

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

#               if !defined(BUILD_STATIC_ONLY)
                {

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

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

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

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

error_activate:
    globus_hashtable_remove(
        &globus_l_extension_loaded, extension->name);
    if(builtin && builtin->owner)
    {
        builtin->owner->ref--;
    }
error_module:
#ifndef BUILD_STATIC_ONLY
    if(extension->dlhandle)
    {
        lt_dlclose(extension->dlhandle);
    }
error_dll:
#endif /* !BUILD_STATIC_ONLY */
    globus_free(extension->name);
error_strdup:
    globus_free(extension);
error_alloc:
    globus_rmutex_unlock(&globus_l_extension_mutex);
error_param:
    GlobusExtensionDebugExitWithError();
    return result;
}
コード例 #8
0
static
globus_result_t
globus_l_extension_get_module(
    lt_dlhandle                         dlhandle,
    const char *                        module_name,
    globus_module_descriptor_t **       module_desc)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    globus_module_descriptor_t *        module;
    GlobusFuncName(globus_l_extension_get_module);
    
    module = (globus_module_descriptor_t *)
        lt_dlsym(dlhandle, "globus_extension_module");

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

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

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


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

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

        free(module_descriptor_name);
    }

    if (!module)
    {
        const char *                    error;
        
        error = lt_dlerror();
        
        GlobusExtensionDebugPrintf(
            GLOBUS_L_EXTENSION_DEBUG_DLL,
            (_GCSL("[%s] Couldn't find module descriptor : %s\n"),
                _globus_func_name, error ? error : "(null)"));
        result = globus_error_put(
            globus_error_construct_error(
                GLOBUS_EXTENSION_MODULE,
                NULL,
                GLOBUS_EXTENSION_ERROR_LOOKUP_FAILED,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Couldn't find module descriptor : %s\n",
                error ? error : "(null)"));
    }
    
    *module_desc = module;
    return result;
}
コード例 #9
0
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;
}
コード例 #10
0
globus_result_t
globus_usage_stats_vsend(
    globus_usage_stats_handle_t         handle,
    int                                 param_count,
    va_list                             ap)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
#ifndef TARGET_ARCH_ARM
    int                                 i = 0;

    if(handle == NULL)
    {
        return globus_error_put(
            globus_error_construct_error(
                GLOBUS_USAGE_MODULE,
                NULL,
                GLOBUS_USAGE_STATS_ERROR_TYPE_OOM,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Handle is NULL."));
    }
                
    if(handle->optout)
    {
        return result;
    }

    globus_mutex_lock(&handle->mutex);    
    {
        if(handle->inuse)
        {
            globus_mutex_unlock(&handle->mutex);   
            return globus_error_put(
                globus_error_construct_error(
                    GLOBUS_USAGE_MODULE,
                    NULL,
                    GLOBUS_USAGE_STATS_ERROR_TYPE_OOM,
                    __FILE__,
                    _globus_func_name,
                    __LINE__,
                    "Handle is busy."));
        }
        else
        {
            handle->inuse = GLOBUS_TRUE;
        }
    }
    globus_mutex_unlock(&handle->mutex);
    
    handle->data_length = handle->header_length;
    
    if(param_count > 0)
    {
        memcpy(handle->data + handle->data_length, " ", 1);
        handle->data_length += 1;

        for(i = 0; i < param_count; ++i)
        {
            const char *                key = va_arg(ap, char *);
            const char *                value = va_arg(ap, char *);
            size_t                      length;
            size_t                      val_len;
            const unsigned char *       val_start;
            
            val_len = strlen(value);
            length = strlen(key) + val_len;

            if(strchr(value, ' '))
            {
                if((PACKET_SIZE - handle->data_length) < (length + 5))
                {
                    return globus_error_put(
                        globus_error_construct_error(
                            GLOBUS_USAGE_MODULE,
                            NULL,
                            GLOBUS_USAGE_STATS_ERROR_TYPE_TOO_BIG,
                            __FILE__,
                            _globus_func_name,
                            __LINE__,
                            "Parameters don't fit into one packet"));
                }
                handle->data_length += sprintf(
                    (char *) handle->data + handle->data_length,
                    "%s=\"%s\" ", key, value);
                val_start = handle->data + handle->data_length - val_len - 2;
                GlobusUsageTr(val_start, val_len, '"', '\'');
                GlobusUsageTr(val_start, val_len, '\n', ' ');
            }
            else
            {
                if((PACKET_SIZE - handle->data_length) < (length + 3))
                {
                    return globus_error_put(
                        globus_error_construct_error(
                            GLOBUS_USAGE_MODULE,
                            NULL,
                            GLOBUS_USAGE_STATS_ERROR_TYPE_TOO_BIG,
                            __FILE__,
                            _globus_func_name,
                            __LINE__,
                            "Parameters don't fit into one packet"));
                }
                handle->data_length += sprintf(
                    (char *) handle->data + handle->data_length,
                    "%s=%s ", key, value);
                val_start = handle->data + handle->data_length - val_len - 1;
                GlobusUsageTr(val_start, val_len, '"', '\'');
                GlobusUsageTr(val_start, val_len, '\n', ' ');
            }
        }
    }
コード例 #11
0
globus_result_t
globus_usage_stats_handle_init(
    globus_usage_stats_handle_t *       handle,
    uint16_t                            code,
    uint16_t                            version,
    const char *                        targets)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
#ifndef TARGET_ARCH_ARM
    globus_i_usage_stats_handle_t *     new_handle;
    char *                              targets_env;
    globus_list_t *                     targets_list;
    char *                              contact;
    globus_sockaddr_t                   addr;
    int                                 host[16];
    int                                 count;
    char                                hostname[255];
    int                                 rc = 0;
    int                                 i;

    new_handle = globus_calloc(1, sizeof(globus_i_usage_stats_handle_t));
    if(!new_handle)
    {
        return globus_error_put(
            globus_error_construct_error(
                GLOBUS_USAGE_MODULE,
                NULL,
                GLOBUS_USAGE_STATS_ERROR_TYPE_OOM,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Out of memory"));
    }

    new_handle->optout = getenv("GLOBUS_USAGE_OPTOUT");
    if(new_handle->optout)
    {
        *handle = new_handle;
        return GLOBUS_SUCCESS;
    }

    globus_mutex_init(&new_handle->mutex, NULL);

    new_handle->inuse = GLOBUS_FALSE;
    
    new_handle->code = htons(code);
    new_handle->version = htons(version);

    memset(new_handle->data, 0, PACKET_SIZE);

    memcpy(new_handle->data + new_handle->data_length, 
           (void *)&new_handle->code, 2);
    new_handle->data_length += 2;

    memcpy(new_handle->data + new_handle->data_length, 
           (void *)&new_handle->version, 2);
    new_handle->data_length += 2;

    rc = globus_libc_gethostaddr(&addr);
    if(rc != 0)
    {
        return globus_error_put(
            globus_error_construct_error(
                GLOBUS_USAGE_MODULE,
                NULL,
                GLOBUS_USAGE_STATS_ERROR_TYPE_UNKNOWN_HOSTNAME,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Unable to get hostaddr."));
    }
    
    result = globus_libc_addr_to_contact_string(
        &addr, GLOBUS_LIBC_ADDR_NUMERIC, &contact);
    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    result = globus_libc_contact_string_to_ints(
        contact, host, &count, NULL);
    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    globus_libc_free(contact);

    if(count == 4)
    {
        memset(new_handle->data + new_handle->data_length, 0, 12);
        new_handle->data_length += 12;
    }

    for (i = 0; i < count; i++)
    {
        new_handle->data[new_handle->data_length++] = (unsigned char) host[i];
    }

    /* timestamp will go here */
    new_handle->data_length += 4;

    if(globus_libc_gethostname(hostname, 255) == 0)
    {
        new_handle->data_length += 
            sprintf((char *) new_handle->data + new_handle->data_length,
                "HOSTNAME=%s", hostname);
    }
    new_handle->header_length = new_handle->data_length;
    
    if(targets)
    {
        globus_l_usage_stats_split_targets(targets, &new_handle->targets);
    }
    else if((targets_env = getenv("GLOBUS_USAGE_TARGETS")) 
            != NULL)
    {
        globus_l_usage_stats_split_targets(
            targets_env, &new_handle->targets);
    }
    else
    {
        globus_l_usage_stats_split_targets(
            GLOBUS_L_USAGE_STATS_DEFAULT_TARGETS, 
            &new_handle->targets);
    }


    result = globus_xio_handle_create(
        &new_handle->xio_handle,
        globus_l_usage_stats_stack);
    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    result = globus_xio_open(
        new_handle->xio_handle,
        NULL, NULL);
    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    targets_list = new_handle->targets;
    while(targets_list)
    {
        globus_xio_data_descriptor_t *  dd;
        dd = (globus_xio_data_descriptor_t *) globus_malloc(
            sizeof(globus_xio_data_descriptor_t));
            
        result = globus_xio_data_descriptor_init(
            dd,
            new_handle->xio_handle);
        if(result != GLOBUS_SUCCESS)
        {
            return result;
        }

        result = globus_xio_data_descriptor_cntl(
            *dd,
            globus_l_usage_stats_udp_driver,
            GLOBUS_XIO_UDP_SET_CONTACT,
            (char *)globus_list_first(targets_list));
        if(result != GLOBUS_SUCCESS)
        {
            goto exit;
        }
        
        globus_list_insert(&new_handle->xio_desc_list, dd);
        
        targets_list = globus_list_rest(targets_list);
    }
    
    *handle = new_handle;

    return GLOBUS_SUCCESS;

exit:
#endif
    return result;
}