static void
transfer(
    globus_gridftp_server_control_op_t      op,
    void *                                  data_handle,
    const char *                            local_target,
    const char *                            mod_name,
    const char *                            mod_parms,
    globus_range_list_t                     range_list,
    void *                                  user_arg)
{
    int                                     ctr;
    globus_size_t                           off = 0;
    globus_size_t                           len = 256;
    globus_abstime_t                        abstime;

    globus_gridftp_server_control_events_enable(
        op,
        GLOBUS_GRIDFTP_SERVER_CONTROL_EVENT_ABORT,
        abort_cb,
        NULL);

    globus_gridftp_server_control_events_enable(
        op,
        GLOBUS_GRIDFTP_SERVER_CONTROL_EVENT_PERF |
                GLOBUS_GRIDFTP_SERVER_CONTROL_EVENT_RESTART,

        event_cb,
        NULL);

    globus_gridftp_server_control_begin_transfer(op);

    globus_mutex_lock(&gs_l_mutex);
    {
        for(ctr = 0; ctr < 500 && !globus_l_done; ctr++)
        {
            GlobusTimeAbstimeSet(abstime, 0, 50000);
            globus_cond_timedwait(&gs_l_cond, &gs_l_mutex, &abstime);
            off += len;
        }
    }
    globus_mutex_unlock(&gs_l_mutex);

    globus_gridftp_server_control_finished_transfer(
        op, GLOBUS_GRIDFTP_SERVER_CONTROL_RESPONSE_SUCCESS, NULL);



    globus_l_done = GLOBUS_FALSE;
}
static
void
l_ticker_cb(
    void *                              user_arg)
{
    globus_l_ftp_client_restart_plugin_t *  d;
    globus_abstime_t	                    when;
    globus_bool_t                           retry = GLOBUS_TRUE;

    d = (globus_l_ftp_client_restart_plugin_t *) user_arg;

    /* no reason to do anything here if the transfer isnt running */
    if(!d->xfer_running || d->abort_pending)
    {
        return;
    }

    /* allow 1 tic to insure resolution */
    if(d->ticker > 1)
    {
        if(d->abort_pending)
        {
            return;
        }
        
        if(d->max_retries == 0)
        {
            retry = GLOBUS_FALSE;
        }
        else if(d->max_retries > 0)
        {
            d->max_retries--;
        }
        
        GlobusTimeAbstimeGetCurrent(when);
        if((d->deadline.tv_sec != 0 || d->deadline.tv_nsec != 0) &&
            globus_abstime_cmp(&when, &d->deadline) > 0)
        {
            retry = GLOBUS_FALSE;
        }

        GlobusTimeAbstimeSet(when, d->interval.tv_sec, d->interval.tv_usec);
        
        if(retry)
        {
            if(d->backoff)
            {
                GlobusTimeReltimeMultiply(d->interval, 2);
            }
            
            switch(d->operation)
            {
                case GLOBUS_FTP_CLIENT_GET:
                    globus_ftp_client_plugin_restart_get(
                        d->ticker_ftp_handle,
                        d->source_url,
                        &d->source_attr,
                        NULL,
                        &when);
                    break;
                case GLOBUS_FTP_CLIENT_PUT:
                    globus_ftp_client_plugin_restart_put(
                        d->ticker_ftp_handle,
                        d->dest_url,
                        &d->dest_attr,
                        NULL,
                        &when);
                    break;
                case GLOBUS_FTP_CLIENT_TRANSFER:
                    globus_ftp_client_plugin_restart_third_party_transfer(
                        d->ticker_ftp_handle,
                        d->source_url,
                        &d->source_attr,
                        d->dest_url,
                        &d->dest_attr,
                        NULL,
                        &when);
                    break;
    
                default:
                    globus_assert(0 && "should never happen--memory corruption");
            }
        }
    }
    d->ticker++;

    if(!retry)
    {
        globus_ftp_client_plugin_abort(d->ticker_ftp_handle);
    }
}
static
void
globus_l_ftp_client_restart_plugin_fault(
    globus_ftp_client_plugin_t *		plugin,
    void *					plugin_specific,
    globus_ftp_client_handle_t *		handle,
    const char *				url,
    globus_object_t *				error)
{
    globus_l_ftp_client_restart_plugin_t *	d;
    globus_abstime_t				when;

    d = (globus_l_ftp_client_restart_plugin_t *) plugin_specific;

    if(d->abort_pending)
    {
        return;
    }

    if(d->max_retries == 0)
    {
	return;
    }
    else if(d->max_retries > 0)
    {
	d->max_retries--;
    }

    GlobusTimeAbstimeGetCurrent(when);
    if((d->deadline.tv_sec != 0 || d->deadline.tv_nsec != 0) &&
	globus_abstime_cmp(&when, &d->deadline) > 0)
    {
	return;
    }
    GlobusTimeAbstimeSet(when, d->interval.tv_sec, d->interval.tv_usec);

    switch(d->operation)
    {
	case GLOBUS_FTP_CLIENT_CHMOD:
	    globus_ftp_client_plugin_restart_chmod(
		    handle,
		    d->source_url,
		    d->chmod_file_mode,
		    &d->source_attr,
		    &when);
	    break;

	case GLOBUS_FTP_CLIENT_CKSM:
	    globus_ftp_client_plugin_restart_cksm(
		    handle,
		    d->source_url,
		    d->checksum_offset,
		    d->checksum_length,
		    d->checksum_alg,
		    &d->source_attr,
		    &when);
	    break;

	case GLOBUS_FTP_CLIENT_DELETE:
	    globus_ftp_client_plugin_restart_delete(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;

	case GLOBUS_FTP_CLIENT_FEAT:
	    globus_ftp_client_plugin_restart_feat(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;

        case GLOBUS_FTP_CLIENT_MKDIR:
	    globus_ftp_client_plugin_restart_mkdir(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_RMDIR:
	    globus_ftp_client_plugin_restart_rmdir(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_MOVE:
	    globus_ftp_client_plugin_restart_move(
		    handle,
		    d->source_url,
		    d->dest_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_LIST:
	    globus_ftp_client_plugin_restart_verbose_list(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_NLST:
	    globus_ftp_client_plugin_restart_list(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_MLSD:
	    globus_ftp_client_plugin_restart_machine_list(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_MLST:
	    globus_ftp_client_plugin_restart_mlst(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_STAT:
	    globus_ftp_client_plugin_restart_stat(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_GET:
	    globus_ftp_client_plugin_restart_get(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    GLOBUS_NULL,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_PUT:
	    globus_ftp_client_plugin_restart_put(
		    handle,
		    d->dest_url,
		    &d->dest_attr,
		    GLOBUS_NULL,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_TRANSFER:
	    globus_ftp_client_plugin_restart_third_party_transfer(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    d->dest_url,
		    &d->dest_attr,
		    GLOBUS_NULL,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_MDTM:
	    globus_ftp_client_plugin_restart_modification_time(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
	case GLOBUS_FTP_CLIENT_SIZE:
	    globus_ftp_client_plugin_restart_size(
		    handle,
		    d->source_url,
		    &d->source_attr,
		    &when);
	    break;
    default: /* Only state left is FTP_CLIENT_IDLE */
	  globus_assert(0 && "Unexpected state");
    }

    if(d->backoff)
    {
	GlobusTimeReltimeMultiply(d->interval, 2);
    }
}