static
globus_result_t
globus_l_net_manager_python_handle_exception(
    const char                         *func_name)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    PyObject                           *exception = NULL,
                                       *exception_string = NULL;
    const char                         *exception_cstr = NULL;

    exception = PyErr_Occurred();
    if (exception != NULL)
    {
        result = GLOBUS_FAILURE;

        exception_string = PyObject_Str(exception);
        if (exception_string)
        {
            exception_cstr = PyString_AsString(exception_string);
            if (exception_cstr)
            {
                result = globus_error_put(
                        globus_error_construct_string(
                            &globus_net_manager_python_module,
                            NULL,
                            "Python Exception in %s: %s",
                            func_name,
                            exception_cstr));
            }
            Py_DECREF(exception_string);
        }
    }
    return result;
}
static
void
restart_marker_plugin_abort_cb(
    globus_ftp_client_plugin_t *                plugin,
    void *                                      plugin_specific,
    globus_ftp_client_handle_t *                handle)
{
    restart_marker_plugin_info_t  *             ps;

    ps = (restart_marker_plugin_info_t *) plugin_specific;

    ps->error_obj = globus_error_construct_string(
        GLOBUS_FTP_CLIENT_MODULE,
        GLOBUS_NULL,
        "[restart_marker_plugin_abort_cb] Transfer aborted by user\n");
}
globus_result_t
globus_ftp_client_restart_marker_plugin_destroy(
    globus_ftp_client_plugin_t *                    plugin)
{
    globus_result_t                                 result;
    restart_marker_plugin_info_t *                  ps;
    GlobusFuncName(globus_ftp_client_restart_marker_plugin_destroy);

    if(plugin == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] NULL plugin at %s\n",
            GLOBUS_FTP_CLIENT_MODULE->module_name,
            _globus_func_name));
    }

    result = globus_ftp_client_plugin_get_plugin_specific(
        plugin,
        (void **) (void *) &ps);

    if(result != GLOBUS_SUCCESS)
    {
        return result;
    }

    if(ps->error_obj)
    {
        globus_object_free(ps->error_obj);
        ps->error_obj = GLOBUS_NULL;
    }

    if(ps->error_url)
    {
        globus_libc_free(ps->error_url);
        ps->error_url = GLOBUS_NULL;
    }

    globus_mutex_destroy(&ps->lock);
    globus_free(ps);

    return globus_ftp_client_plugin_destroy(plugin);
}
int main()
{
    globus_object_t * err;
    char * s;
    static char * myname = "main";

    globus_module_activate(GLOBUS_COMMON_MODULE);

    err = globus_error_construct_string(GLOBUS_COMMON_MODULE,
	    GLOBUS_ERROR_NO_INFO,
	    "[%s]: Error doing something hard at %s:%d\n",
	    GLOBUS_COMMON_MODULE->module_name,
	    myname,
	    __LINE__);
    s = globus_object_printable_to_string(err);

    globus_libc_printf("%s",s);
    return globus_module_deactivate_all();
}
int main()
{
    globus_object_t * err;
    char * s;
    char * t;
    static char * myname = "main";

    printf("1..1\n");

    globus_module_activate(GLOBUS_COMMON_MODULE);

#line myline
    err = globus_error_construct_string(GLOBUS_COMMON_MODULE, GLOBUS_ERROR_NO_INFO, "[%s]: Error doing something hard at %s:%d\n", GLOBUS_COMMON_MODULE->module_name, myname, __LINE__);
    s = globus_object_printable_to_string(err);
#line myline
    t = globus_common_create_string( "[%s]: Error doing something hard at %s:%d\n", GLOBUS_COMMON_MODULE->module_name, myname, __LINE__);
    ok(strcmp(s, t) == 0, "globus_common_error_string");
    free(s);
    free(t);

    return TEST_EXIT_CODE;
}
globus_result_t
globus_ftp_client_restart_marker_plugin_init(
    globus_ftp_client_plugin_t *                            plugin,
    globus_ftp_client_restart_marker_plugin_begin_cb_t      begin_cb,
    globus_ftp_client_restart_marker_plugin_marker_cb_t     marker_cb,
    globus_ftp_client_restart_marker_plugin_complete_cb_t   complete_cb,
    void *                                                  user_arg)
{
    restart_marker_plugin_info_t *                  ps;
    globus_result_t                                 result;
    GlobusFuncName(globus_ftp_client_restart_marker_plugin_init);

    if(plugin == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] NULL plugin at %s\n",
            GLOBUS_FTP_CLIENT_MODULE->module_name,
            _globus_func_name));
    }

    ps = (restart_marker_plugin_info_t *)
        globus_malloc(sizeof(restart_marker_plugin_info_t));

    if(ps == GLOBUS_NULL)
    {
        return globus_error_put(globus_error_construct_string(
            GLOBUS_FTP_CLIENT_MODULE,
            GLOBUS_NULL,
            "[%s] Out of memory at %s\n",
             GLOBUS_FTP_CLIENT_MODULE->module_name,
             _globus_func_name));
    }

    /*
     *  initialize plugin specific structure.
     */
    ps->user_arg       = user_arg;
    ps->begin_cb       = begin_cb;
    ps->marker_cb      = marker_cb;
    ps->complete_cb    = complete_cb;

    ps->error_url      = GLOBUS_NULL;
    ps->error_obj      = GLOBUS_NULL;

    globus_mutex_init(&ps->lock, GLOBUS_NULL);

    result = globus_ftp_client_plugin_init(
              plugin,
              GLOBUS_L_FTP_CLIENT_RESTART_MARKER_PLUGIN_NAME,
              GLOBUS_FTP_CLIENT_CMD_MASK_FILE_ACTIONS,
              ps);

    if(result != GLOBUS_SUCCESS)
    {
        globus_mutex_destroy(&ps->lock);
        globus_free(ps);

        return result;
    }

    globus_ftp_client_plugin_set_destroy_func(plugin,
        restart_marker_plugin_destroy_cb);
    globus_ftp_client_plugin_set_copy_func(plugin,
        restart_marker_plugin_copy_cb);
    globus_ftp_client_plugin_set_get_func(plugin,
        restart_marker_plugin_get_cb);
    globus_ftp_client_plugin_set_data_func(plugin,
        restart_marker_plugin_data_cb);
    globus_ftp_client_plugin_set_put_func(plugin,
        restart_marker_plugin_put_cb);
    globus_ftp_client_plugin_set_third_party_transfer_func(plugin,
        restart_marker_plugin_transfer_cb);
    globus_ftp_client_plugin_set_response_func(plugin,
        restart_marker_plugin_response_cb);
    globus_ftp_client_plugin_set_complete_func(plugin,
        restart_marker_plugin_complete_cb);
    globus_ftp_client_plugin_set_fault_func(plugin,
        restart_marker_plugin_fault_cb);
    globus_ftp_client_plugin_set_abort_func(plugin,
        restart_marker_plugin_abort_cb);

    return GLOBUS_SUCCESS;
}
/**
 * Initialize an instance of the GridFTP restart plugin
 * @ingroup globus_ftp_client_restart_plugin
 *
 * This function will initialize the plugin-specific instance data
 * for this plugin, and will make the plugin usable for ftp
 * client handle attribute and handle creation.
 *
 * @param plugin
 *        A pointer to an uninitialized plugin. The plugin will be
 *        configured as a restart plugin.
 * @param max_retries
 *        The maximum number of times to retry the operation before giving
 *        up on the transfer. If this value is less than or equal to 0,
 *        then the restart plugin will keep trying to restart the operation
 *        until it completes or the deadline is reached with an unsuccessful
 *        operation.
 * @param interval
 *        The interval to wait after a failures before retrying the transfer.
 *        If the interval is 0 seconds or GLOBUS_NULL, then an exponential 
 *        backoff will be used.
 * @param deadline
 *        An absolute timeout.  If the deadline is GLOBUS_NULL then the retry
 *        will never timeout.
 *
 * @return This function returns an error if
 * - plugin is null
 *
 * @see globus_ftp_client_restart_plugin_destroy(),
 *      globus_ftp_client_handleattr_add_plugin(),
 *      globus_ftp_client_handleattr_remove_plugin(),
 *      globus_ftp_client_handle_init()
 */
globus_result_t
globus_ftp_client_restart_plugin_init(
    globus_ftp_client_plugin_t *		plugin,
    int						max_retries,
    globus_reltime_t *				interval,
    globus_abstime_t *				deadline)
{
    char *                              env_str;
    globus_l_ftp_client_restart_plugin_t *	d;
    globus_result_t				result;
    GlobusFuncName(globus_ftp_client_restart_plugin_init);

    if(plugin == GLOBUS_NULL)
    {
	return globus_error_put(globus_error_construct_string(
		GLOBUS_FTP_CLIENT_MODULE,
		GLOBUS_NULL,
		"[%s] NULL plugin at %s\n",
		GLOBUS_FTP_CLIENT_MODULE->module_name,
		_globus_func_name));
    }
        
    d =
	globus_libc_calloc(1, sizeof(globus_l_ftp_client_restart_plugin_t));

    if(! d)
    {
	return globus_error_put(globus_error_construct_string(
		                GLOBUS_FTP_CLIENT_MODULE,
				GLOBUS_NULL,
				"[%s] Out of memory at %s\n",
				 GLOBUS_FTP_CLIENT_MODULE->module_name,
				 _globus_func_name));
    }

    result = globus_ftp_client_plugin_init(plugin,
				  GLOBUS_L_FTP_CLIENT_RESTART_PLUGIN_NAME,
				  GLOBUS_FTP_CLIENT_CMD_MASK_ALL,
				  d);
    if(result != GLOBUS_SUCCESS)
    {
	globus_libc_free(d);

	return result;
    }

    d->max_retries = max_retries > 0 ? max_retries : -1;

    if(interval)
    {
	GlobusTimeReltimeCopy(d->interval, *interval);
    }
    if((!interval) || (interval->tv_sec == 0 && interval->tv_usec == 0))
    {
	d->backoff = GLOBUS_TRUE;
	d->interval.tv_sec = 1;
	d->interval.tv_usec = 0;
    }
    else
    {
        d->backoff = GLOBUS_FALSE;
    }

    if(deadline)
    {
	GlobusTimeAbstimeCopy(d->deadline, *deadline);
    }
    else
    {
	GlobusTimeAbstimeCopy(d->deadline, globus_i_abstime_infinity);
    }

    d->dest_url = GLOBUS_NULL;
    d->source_url = GLOBUS_NULL;

    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, copy);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, destroy);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, chmod);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, cksm);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, delete);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, modification_time);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, size);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, feat);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, mkdir);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, rmdir);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, move);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, verbose_list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, machine_list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, mlst);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, stat);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, list);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, get);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, put);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, third_party_transfer);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, fault);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, abort);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, complete);
    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin, data);

    GLOBUS_FTP_CLIENT_RESTART_PLUGIN_SET_FUNC(plugin,
        response);

    env_str = globus_libc_getenv("GUC_STALL_TIMEOUT");
    if(env_str != NULL)
    {
        int                             sc;
        int                             to_secs;

        sc = sscanf(env_str, "%d", &to_secs);
        if(sc == 1)
        {
            globus_ftp_client_restart_plugin_set_stall_timeout(
                plugin, to_secs);
        }
    }

    return GLOBUS_SUCCESS;

result_exit:
    globus_ftp_client_plugin_destroy(plugin);
    return result;
}