static
globus_ftp_client_plugin_t *
globus_l_ftp_client_restart_plugin_copy(
    globus_ftp_client_plugin_t *		plugin_template,
    void *					plugin_specific)
{
    globus_ftp_client_plugin_t *		newguy;
    globus_l_ftp_client_restart_plugin_t *	d;
    globus_l_ftp_client_restart_plugin_t *	newd;
    globus_result_t				result;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    newguy = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
    if(newguy == GLOBUS_NULL)
    {
	goto error_exit;
    }
    result = globus_ftp_client_restart_plugin_init(newguy,
	    d->max_retries,
	    &d->interval,
	    &d->deadline);

    if(result != GLOBUS_SUCCESS)
    {
	goto free_exit;
    }
    result = globus_ftp_client_plugin_get_plugin_specific(newguy,
	                                                  (void **) &newd);
    if(result != GLOBUS_SUCCESS)
    {
	goto destroy_exit;
    }
    newd->backoff = d->backoff;
    newd->stall_timeout = d->stall_timeout;

    return newguy;

destroy_exit:
    globus_ftp_client_restart_plugin_destroy(newguy);
free_exit:
    globus_libc_free(newguy);
error_exit:
    return GLOBUS_NULL;
}
int main()
{
    int rc = 0;
    int count=0;
    globus_ftp_client_handle_t handle;
    globus_ftp_client_plugin_t restart_plugin;
    globus_ftp_client_plugin_t debug_plugin;
    globus_result_t result;
    globus_ftp_client_handleattr_t handleattr;

    globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    globus_module_activate(GLOBUS_FTP_CLIENT_RESTART_PLUGIN_MODULE);
    globus_module_activate(GLOBUS_FTP_CLIENT_DEBUG_PLUGIN_MODULE);

    /* Test using attributes */
    result = globus_ftp_client_handleattr_init(&handleattr);
    globus_assert(result == GLOBUS_SUCCESS);

    result = globus_ftp_client_restart_plugin_init(
	    &restart_plugin,
	    0,
	    GLOBUS_NULL,
	    GLOBUS_NULL);
    globus_assert(result == GLOBUS_SUCCESS);

    result = globus_ftp_client_debug_plugin_init(
	    &debug_plugin,
	    stderr,
	    "hello");
    globus_assert(result == GLOBUS_SUCCESS);

    /* Test 1: insert restart plugin into handle attr */
    count++;
    result = globus_ftp_client_handleattr_add_plugin(&handleattr,
	                                             &restart_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 2: insert restart plugin into handle attr (fail) */
    count++;
    result = globus_ftp_client_handleattr_add_plugin(&handleattr,
	                                             &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 3: create/destroy handle with attr */
    count++;
    result = globus_ftp_client_handle_init(&handle, &handleattr);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    else if(globus_ftp_client_handle_destroy(&handle) != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 4: insert debug plugin into handle attr */
    count++;
    result = globus_ftp_client_handleattr_add_plugin(&handleattr,
	                                             &debug_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 5: create/destroy handle with attr */
    count++;
    result = globus_ftp_client_handle_init(&handle, &handleattr);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    else if(globus_ftp_client_handle_destroy(&handle) != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 6: remove restart plugin from handle attr */
    count++;
    result = globus_ftp_client_handleattr_remove_plugin(&handleattr,
	                                                &restart_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 7: remove restart plugin from handle attr (fail) */
    count++;
    result = globus_ftp_client_handleattr_remove_plugin(&handleattr,
	                                                &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 8: insert debug plugin into handle attr (fail) */
    count++;
    result = globus_ftp_client_handleattr_add_plugin(&handleattr,
	                                             &debug_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 9: remove debug plugin from handle attr */
    count++;
    result = globus_ftp_client_handleattr_remove_plugin(&handleattr,
	                                                &debug_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 10: remove restart plugin from handle attr (fail) */
    count++;
    result = globus_ftp_client_handleattr_remove_plugin(&handleattr,
	                                                &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test 11: create/destroy handle with attr */
    count++;
    result = globus_ftp_client_handle_init(&handle, &handleattr);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    else if(globus_ftp_client_handle_destroy(&handle) != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    /* Test without attributes */
    /* Test 12: create handle without attr */
    count++;
    result = globus_ftp_client_handle_init(&handle, GLOBUS_NULL);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 13: add restart plugin into handle */
    count++;
    result = globus_ftp_client_handle_add_plugin(&handle, &restart_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 14: add restart plugin into handle (fail) */
    count++;
    result = globus_ftp_client_handle_add_plugin(&handle, &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 15: add debug plugin into handle */
    count++;
    result = globus_ftp_client_handle_add_plugin(&handle, &debug_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 16: remove restart plugin from handle */
    count++;
    result = globus_ftp_client_handle_remove_plugin(&handle, &restart_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 17: remove restart plugin from handle (fail) */
    count++;
    result = globus_ftp_client_handle_remove_plugin(&handle, &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 18: add debug plugin into handle (fail) */
    count++;
    result = globus_ftp_client_handle_add_plugin(&handle, &debug_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 19: remove debug plugin into handle */
    count++;
    result = globus_ftp_client_handle_remove_plugin(&handle, &debug_plugin);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 20: remove restart plugin into handle (fail) */
    count++;
    result = globus_ftp_client_handle_remove_plugin(&handle, &restart_plugin);
    if(result == GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }
    /* Test 21: destroy handle */
    count++;
    result = globus_ftp_client_handle_destroy(&handle);
    if(result != GLOBUS_SUCCESS)
    {
	printf("Failed test %d\n", count);
	rc++;
    }

    globus_module_deactivate_all();
    return rc;
}
void
test_parse_args(int argc,
		char **argv,
		globus_ftp_client_handleattr_t * handle_attr,
		globus_ftp_client_operationattr_t * operation_attr,
		char **src,
		char **dst)
{
    int c;
    extern char * optarg;
    extern int opterr;
    globus_reltime_t timeout;
    globus_ftp_client_plugin_t *plugin;
    globus_ftp_control_dcau_t dcau;
    globus_abstime_t deadline_time;
    globus_reltime_t interval_time;
    int max_retries;
    long interval;
    long deadline;
    char * subject;

    *src = GLOBUS_NULL;
    *dst = GLOBUS_NULL;

    setvbuf(stdout, 0, _IONBF, 0);
    
#ifdef WIN32
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
    _setmode(_fileno(stderr), _O_BINARY);
#endif

    opterr = 0;
    while((c = getopt(argc, argv, "-f:a:ps:d:r:zMTc:t:i")) != -1)
    {
	switch(c)
	{
	case 'a':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_ABORT_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_abort_plugin_init(plugin);


	    if(atoi(optarg) >= FTP_ABORT_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Abort plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    globus_ftp_client_test_abort_plugin_set_abort_point(plugin,
							        atoi(optarg));

	    globus_ftp_client_test_abort_plugin_set_abort_counter(
		plugin,
		&test_abort_count);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'p':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_DEBUG_PLUGIN_MODULE);
	    globus_ftp_client_debug_plugin_init(plugin, stderr, "[Debug Plugin]");

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'M':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PERF_PLUGIN_MODULE);
	    globus_ftp_client_test_perf_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'T':
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_THROUGHPUT_PLUGIN_MODULE);
	    globus_ftp_client_test_throughput_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;

	case 'z':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_PAUSE_PLUGIN_MODULE);

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_pause_plugin_init(plugin);

	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);

	    break;
	case 'r':
	    globus_module_activate(GLOBUS_FTP_CLIENT_TEST_RESTART_PLUGIN_MODULE);
	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_test_restart_plugin_init(plugin);
	    if(atoi(optarg) >= FTP_RESTART_LAST ||
	       atoi(optarg) < 0)
	    {
		printf("Restart plugin argument out of range\n");
		globus_module_deactivate_all();
		exit(1);
	    }
	    else
	    {
		char *p;
		p = strchr(optarg, ',');
		if(p)
		{
		    GlobusTimeReltimeSet(timeout, atoi(p+1),0);
		}
		else
		{
		    GlobusTimeReltimeSet(timeout, 0, 0);
		}
		globus_ftp_client_test_restart_plugin_set_restart_point(
		    plugin,
		    atoi(optarg),
		    &timeout);
		globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    }

	    break;
	case 's':
	    *src = optarg;
	    break;
	case 'd':
	    *dst = optarg;
	    break;
	case 'c':
	    if(!strcmp(optarg, "none"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_NONE;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else if(!strcmp(optarg, "self"))
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SELF;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    else
	    {
		dcau.mode = GLOBUS_FTP_CONTROL_DCAU_SUBJECT;
		dcau.subject.subject = optarg;
		globus_ftp_client_operationattr_set_dcau(operation_attr,
							  &dcau);
	    }
	    break;
	case 't':
	    if(!strcmp(optarg, "clear"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_CLEAR);
	    }
	    else if(!strcmp(optarg, "safe"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    }
	    else if(!strcmp(optarg, "private"))
	    {
		globus_ftp_client_operationattr_set_data_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_PRIVATE);
	    }
	    break;
	case 'f':
	    globus_module_activate(GLOBUS_FTP_CLIENT_RESTART_PLUGIN_MODULE);
	    sscanf(optarg, "%d,%ld,%ld", &max_retries, &interval, &deadline);

	    if(interval < 0.1)
	    {
		GlobusTimeReltimeSet(interval_time, 0, 0);
	    }
	    else
	    {
		GlobusTimeReltimeSet(interval_time, interval, 0);
	    }
	    deadline_time.tv_sec = deadline;
	    deadline_time.tv_nsec = 0;

	    plugin = globus_libc_malloc(sizeof(globus_ftp_client_plugin_t));
	    globus_ftp_client_restart_plugin_init(plugin,
		                                  max_retries,
		                                  &interval_time,
						  &deadline_time);
	    globus_ftp_client_handleattr_add_plugin(handle_attr, plugin);
	    break;

	case 'i':
	    globus_ftp_client_operationattr_set_control_protection(
			operation_attr,
			GLOBUS_FTP_CONTROL_PROTECTION_SAFE);
	    break;
	case '?':
        /*  globus_module_deactivate_all();
	    exit(0); 
	*/
	    break;
	}
    }
    
    subject = globus_libc_getenv("GLOBUS_FTP_CLIENT_TEST_SUBJECT");
    if(subject)
    {
        globus_ftp_client_operationattr_set_authorization(
            operation_attr,
            GSS_C_NO_CREDENTIAL,
            ":globus-mapping:",
            "",
            GLOBUS_NULL,
            subject);
    }
}