<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, GridWay Project Leads (GridWay.org)                   */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "gw_tm_ftp_transfer.h"
#include "gw_common.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

char *print_error(globus_object_t *err);

extern gw_tm_ftp_transfer_t **	gw_tm_ftp_xfr_pool;
extern int	GW_TM_FTP_XFR_POOL_MAX;

char *err_str;

int gw_tm_ftp_mad_init(int ids)
{
    static int initialized = 0;
    int rc;
	
    if (initialized == 1 )
        return 0;
			    
    rc = globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    if ( rc != GLOBUS_SUCCESS )
        return 1;

   	rc = globus_module_activate(GLOBUS_GASS_COPY_MODULE);
    if ( rc != GLOBUS_SUCCESS )
        return 1;
 
	gw_tm_ftp_init_xfr_pool(ids);
	
	initialized = 1;
    
    return 0;
}


/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_init(gw_tm_ftp_transfer_t *xfr, int jid)
{
    globus_result_t  grc;
	
    grc = globus_ftp_client_handleattr_init(&(xfr->attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
		
	grc = globus_ftp_client_handleattr_set_cache_all(&(xfr->attr), GLOBUS_TRUE);
    if ( grc != GLOBUS_SUCCESS )
		return -1;
	
    grc = globus_ftp_client_handle_init(&(xfr->handle),&(xfr->attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_ftp_client_operationattr_init(&(xfr->op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_init(&(xfr->gass_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_init(&(xfr->src_gass_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_ftp_client_operationattr_init(&(xfr->src_op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_set_ftp(&(xfr->gass_attr), &(xfr->op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
    
    grc = globus_gass_copy_attr_set_ftp(&(xfr->src_gass_attr), &(xfr->src_op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
	
	grc = globus_gass_copy_handleattr_init(&(xfr->gass_handel_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
	
	grc = globus_gass_copy_handle_init(&(xfr->gass_handle), &(xfr->gass_handel_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_set_no_third_party_transfers(&(xfr->gass_handle), GLOBUS_FALSE);
    if ( grc != GLOBUS_SUCCESS )
		return -1;
        
    xfr->jid = jid;
    xfr->handle_in_use = GW_FALSE;
    xfr->base_dir = NULL;
    xfr->list_buffer = NULL;    
    xfr->buffer_length = 0;
    xfr->read_buffer = (globus_byte_t *) malloc( GW_TM_FTP_BUFFER_LENGTH * sizeof(globus_byte_t));
    xfr->current_xfr.dst_url = NULL;
    xfr->current_xfr.src_url = NULL;
    xfr->current_xfr.cp_xfr_id = 0;
    
    gw_tm_ftp_stack_init(&(xfr->file_stack));
	
    gw_tm_ftp_queue_init(&(xfr->url_queue));	
	
    return 0;
}

void gw_tm_ftp_transfer_flush(gw_tm_ftp_transfer_t *xfr)
{    
	if ( xfr->list_buffer != NULL )
		free(xfr->list_buffer);
		
	xfr->list_buffer = NULL;
    xfr->buffer_length = 0;
}

void gw_tm_ftp_transfer_cancel_cb(	void *                      user_arg,
                                   	globus_gass_copy_handle_t * handle,
                                   	globus_object_t *           err)
{
	int xfr_id;
	gw_tm_ftp_transfer_t * xfr;	
	xfr_id = *( (int *) user_arg );
	
	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    {
	    	free(user_arg);
	    	return;
	    }
	else
	{
    	free(user_arg);
		return;	
	}
	
   	free(user_arg);
	        
	globus_ftp_client_handle_destroy(&(xfr->handle));
    globus_ftp_client_handleattr_destroy(&(xfr->attr));
	
	globus_ftp_client_operationattr_destroy(&(xfr->op_attr));
	globus_ftp_client_operationattr_destroy(&(xfr->src_op_attr));
	
	globus_gass_copy_handle_destroy(&(xfr->gass_handle));
	globus_gass_copy_handleattr_destroy(&(xfr->gass_handel_attr));
	
	/* THERE IS NO FUNCTION TO DESTROY 	globus_gass_copy_attr_t */
	/*
	globus_gass_copy_attr_destroy(&(xfr->gass_attr));
	globus_gass_copy_attr_destroy(&(xfr->src_gass_attr));
	*/

	if ( xfr->current_xfr.src_url != NULL )
		free(xfr->current_xfr.src_url);	
		
	if ( xfr->current_xfr.dst_url != NULL )
		free(xfr->current_xfr.dst_url);
	
	if ( xfr->list_buffer != NULL )
		free(xfr->list_buffer);
		
	if ( xfr->read_buffer != NULL )
		free(xfr->read_buffer);	
		
	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);

    gw_tm_ftp_stack_destroy(&(xfr->file_stack));
    gw_tm_ftp_queue_destroy(&(xfr->url_queue));	
	
    printf("END %i - SUCCESS -\n",xfr_id);
	
    free(gw_tm_ftp_xfr_pool[xfr_id]);
   	
    gw_tm_ftp_xfr_pool[xfr_id] = NULL;
	
}

void gw_tm_ftp_transfer_destroy(gw_tm_ftp_transfer_t *xfr)
{    
	int *xfr_id;
	globus_result_t rc;
	
	xfr_id = ( int *) malloc(sizeof(int));
	*xfr_id = xfr->jid;
	
	globus_ftp_client_abort(&(xfr->handle));
	
	rc = globus_gass_copy_cancel( &(xfr->gass_handle), gw_tm_ftp_transfer_cancel_cb,
        (void *)  xfr_id);
    
    if ( rc != GLOBUS_SUCCESS ) /* No transfer in progress */
		gw_tm_ftp_transfer_cancel_cb((void *)  xfr_id, NULL, NULL);
	    
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_expand_url(
        int xfr_id,
        const char *url_dir,
        globus_ftp_client_complete_callback_t done_cb)
{
	globus_result_t grc;
	int rc;
	int length;
	gw_tm_ftp_transfer_t *xfr;
	int *_xfr_id;
	
	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    	return 1;
	else
		return 1;	
		
	length = strlen(url_dir);

	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);
	
	if ( url_dir[length-1] != '/' )
	{
		xfr->base_dir = (char *) malloc ( (length + 2)	* sizeof(char) );
		snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
	}
	else
		xfr->base_dir = strdup(url_dir);
		
	xfr->base_dir_length = strlen(xfr->base_dir);
	
	rc = gw_tm_ftp_stack_push(&(xfr->file_stack), xfr->base_dir, GW_TM_FTP_DIR, GW_TRUE);
		
	if ( rc != 0 )
		return 1;
	
	/* MACHINE LIST SHOULD BE CHECK IF FEATURE IS SUPPORTED */
	/* WE WILL USE LIST COMMAND...
	grc = globus_ftp_client_machine_list( &(xfr->handle), xfr->base_dir, 
			&(xfr->op_attr), done_cb, (void *) xfr);
	*/
	
	_xfr_id = ( int *) malloc (sizeof(int));
	*(_xfr_id) = xfr->jid;
	
	grc = globus_ftp_client_verbose_list( &(xfr->handle), xfr->base_dir,
			&(xfr->op_attr), done_cb, (void *) _xfr_id);

	if ( grc != GLOBUS_SUCCESS)
	{
		free(_xfr_id);
		return 1;
	}

	_xfr_id = ( int *) malloc (sizeof(int));
	*(_xfr_id) = xfr->jid;
		
	grc = globus_ftp_client_register_read (&(xfr->handle), (xfr->read_buffer),
			GW_TM_FTP_BUFFER_LENGTH, gw_tm_ftp_list_read_callback, (void *) _xfr_id);
			
    if ( grc != GLOBUS_SUCCESS )
    {
    	free(_xfr_id); /*Leaving one int (_xfr_id) behind!!!!*/
        return 1;
    }
    
    return 0;
}



/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void gw_tm_ftp_list_read_callback(void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err,
        globus_byte_t *buffer,
        globus_size_t length,
        globus_off_t offset,
        globus_bool_t eof)
{
    gw_tm_ftp_transfer_t * xfr;	
    globus_result_t grc;
    char *temp_p = NULL;
    char *start_ptr;
    char *end_ptr;
    char mode[16];
    char links[16];
    char owner[16];
    char group[16];
    char size[16];
    char month[16];
    char day[16];
    char hour_year[256];
    char file[256];	
    char *filename;
    char *url;
    int i, len, rc;
    int xfr_id;
        		    
    if(err)  /* ERROR DIR DOES NOT EXISTS : ERROR HANDLING NOT HERE */
        return;

    xfr_id = *( (int *) user_arg );
	
    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
        {
            free(user_arg);
            return;
        }
    else
    {
        free(user_arg);
        return;	
    }
	   	
    if( xfr->list_buffer == NULL && eof && offset == 0)
    {
        xfr->list_buffer = (char *) malloc( sizeof(char) *length); 
        xfr->buffer_length = length;
        
        memcpy(xfr->list_buffer,buffer,length);
    }
    else
    {
        if( (length + offset) > xfr->buffer_length )
        {
            temp_p = (char *) realloc(xfr->list_buffer, length + offset);    
            xfr->list_buffer = temp_p;
            xfr->buffer_length = length + offset;
        }       

        memcpy(xfr->list_buffer + offset,buffer,length);
    }
    
    if(!eof)
    {
        grc = globus_ftp_client_register_read (&(xfr->handle), buffer,
                GW_TM_FTP_BUFFER_LENGTH, gw_tm_ftp_list_read_callback, user_arg);
			
        if( grc != GLOBUS_SUCCESS ) /* ERROR & CANCEL? */
        {
            err_str = print_error(err);

            printf("RMDIR %d - FAILURE globus_ftp_client_register_read (%s)\n",
                    xfr->jid, err_str);

            free(err_str);
            free(user_arg);
            return;
        } 
    }
    else
    {
    	i = 0;
    	start_ptr = xfr->list_buffer;
    	end_ptr = xfr->list_buffer;
    	
    	while (i < xfr->buffer_length)
    	{
            while ((*end_ptr != '\n') && (*end_ptr != '\r'))
            {
                end_ptr++;
                i++;
            }
 
            *end_ptr = '\0';

            rc = sscanf(start_ptr, "%s %s %s %s %s %s %s %s %s",
                    mode, links, owner, group, size, month,
                    day, hour_year, file);

            if ( rc == 8 )
                filename = hour_year;
            else if (rc == 9)
                filename = file;
            else
            {
                start_ptr = end_ptr+1;
                end_ptr = start_ptr;
                i = i+1;
                continue;
            }
 
            if ( (strcmp(filename, ".") != 0)
                    && (strcmp(filename, "..") != 0) )
            {
                len = xfr->base_dir_length + strlen(filename) + 1;

                if (mode[0] == '-')
                {
                    url = (char *) malloc (sizeof(char)* len);

                    snprintf(url, sizeof(char)*len, "%s%s",
                            xfr->base_dir, filename);

                    gw_tm_ftp_stack_push(&(xfr->file_stack), url, GW_TM_FTP_FILE, GW_FALSE);
                    free(url);
                }
                else if (mode[0] == 'd')
                {
                    url = (char *) malloc (sizeof(char)* (len+1));
                    snprintf(url, sizeof(char)*(len + 1), "%s%s/",
                            xfr->base_dir, filename);

                    gw_tm_ftp_stack_push(&(xfr->file_stack), url, GW_TM_FTP_DIR, GW_FALSE);
                    free(url);
                }
            }

            start_ptr = end_ptr+1;
            end_ptr = start_ptr;
	    i = i+1;
        }
 
        free(xfr->list_buffer);
 
        xfr->list_buffer = NULL;
        xfr->buffer_length = 0;
 
        free(user_arg);
    }

    return;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_rmdir(int xfr_id, const char *url_dir)
{
	int rc;

	rc = gw_tm_ftp_transfer_expand_url(xfr_id, url_dir, gw_tm_ftp_transfer_rmdir_cb);	
	
	return rc;
}							   

/* -------------------------------------------------------------------------- */

void gw_tm_ftp_transfer_rmdir_cb(
        void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err)
{
    gw_tm_ftp_transfer_t *xfr;
    gw_tm_ftp_stack_t *file;
    globus_result_t grc;
    int xfr_id;
 
    xfr_id = *( (int *) user_arg );

    if ( (xfr_id < GW_TM_FTP_XFR_POOL_MAX) && (xfr_id >= 0) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
        {
            /*printf("RMDIR %d - FAILURE transfer does not exist.\n", xfr_id);*/
 
            free(user_arg);
            return;
        }
	else
	{
	    /*printf("RMDIR %d - FAILURE invalid transfer id in callback.\n", xfr_id);*/
	    			
            free(user_arg);
            return;
	}

    if (err != GLOBUS_SUCCESS) /* ERROR RMDIR OR EXPAND */
    {
        err_str = print_error(err);

        printf("RMDIR %d - FAILURE rmdir_cb (%s).\n", xfr->jid, err_str);

        free(err_str);
        free(user_arg);
        return;
    }

    file = gw_tm_ftp_stack_pop(&(xfr->file_stack));

    if( file != NULL )
    {
       if ( (file->type == GW_TM_FTP_DIR) && (file->expanded == GW_FALSE) )
       {
            gw_tm_ftp_transfer_flush(xfr);
            gw_tm_ftp_transfer_expand_url(xfr_id, file->file_name, 
                    gw_tm_ftp_transfer_rmdir_cb);

            free(file->file_name);
            free(file);
            free(user_arg);
            return;
        }
        else
        {
            if ( file->type == GW_TM_FTP_FILE )
                grc = globus_ftp_client_delete(&(xfr->handle),
                        file->file_name, &(xfr->op_attr),
       	                gw_tm_ftp_transfer_rmdir_cb, user_arg);
            else
                grc = globus_ftp_client_rmdir(&(xfr->handle),
                        file->file_name, &(xfr->op_attr),
                        gw_tm_ftp_transfer_rmdir_cb, user_arg);

            if ( grc != GLOBUS_SUCCESS )
            {
                err_str = print_error(err);

                printf("RMDIR %d - FAILURE globus_ftp_client_delete/rmdir %s (%s)\n",
                        xfr->jid, file->file_name, err_str);

                free(err_str);
                free(file->file_name);
                free(user_arg);
            }

            free(file);
            return;
        }
    }

    printf("RMDIR %d - SUCCESS -\n", xfr->jid);
    free(user_arg);
}


/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void gw_tm_ftp_transfer_exists_dir_cb(void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err)
{
    gw_tm_ftp_transfer_t *  xfr;
    int                     xfr_id;

    xfr_id = *( (int *) user_arg );

    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
    else
    {
        /*printf("EXISTS %d - FAILURE transfer does not exist.\n", xfr_id);*/
    	
        free(user_arg);
        return;
    }
    else
    {
    	/*printf("EXISTS %d - FAILURE invalid transfer id in callback.\n", xfr_id);*/		
    	
        free(user_arg);
        return;	
    }
 
    if(err != GLOBUS_SUCCESS) /* FILE DOES NOT EXISTS, OR GSS ERROR*/
    {    		
    	printf("EXISTS %d - FAILURE -\n", xfr->jid);
    }
    else
    {
        printf("EXISTS %d - SUCCESS -\n", xfr->jid);
    }
 
    free(user_arg);
}

/* ---------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_exists_dir (int                              xfr_id,
						   		   const char *                     url_dir)
{
    globus_result_t        grc;
   	int				   length;
	gw_tm_ftp_transfer_t * xfr;
	int *                  _xfr_id;
	
	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    	return 1;
	else
		return 1;	   	
	
	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);

	length = strlen(url_dir);
			
	if ( url_dir[length-1] != '/' )
	{
		xfr->base_dir = (char *) malloc ( (length + 2)	* sizeof(char) );
		snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
	}
	else
		xfr->base_dir = strdup(url_dir);
		
	xfr->base_dir_length = strlen(xfr->base_dir);

	_xfr_id = ( int *) malloc (sizeof(int));
	*(_xfr_id) = xfr->jid;
		
	grc = globus_ftp_client_exists ( &(xfr->handle), 
							         xfr->base_dir, 
							         &(xfr->op_attr), 
							         gw_tm_ftp_transfer_exists_dir_cb, 
							         (void *) _xfr_id);
	if (grc != GLOBUS_SUCCESS)
	{
		free(_xfr_id);
		return 1;
	}
	else
		return 0;
	
}							   
							   


/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_mkdir(int                                xfr_id,
						   	 const char *                       url_dir)
{
    globus_result_t        grc;
   	int				   length;
	gw_tm_ftp_transfer_t * xfr;
	int *                  _xfr_id;

	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    	return 1;
	else
		return 1;	   
			
	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);
	
	length = strlen(url_dir);

	if ( url_dir[length-1] != '/' )
	{
		xfr->base_dir = (char *) malloc ( (length + 2)	* sizeof(char) );
		snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
	}
	else
		xfr->base_dir = strdup(url_dir);<commit_msg>Aesthetic changes<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, GridWay Project Leads (GridWay.org)                   */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "gw_tm_ftp_transfer.h"
#include "gw_common.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

char *print_error(globus_object_t *err);

extern gw_tm_ftp_transfer_t **gw_tm_ftp_xfr_pool;
extern int GW_TM_FTP_XFR_POOL_MAX;

char *err_str;

int gw_tm_ftp_mad_init(int ids)
{
    static int initialized = 0;
    int rc;
	
    if (initialized == 1 )
        return 0;
			    
    rc = globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
    if ( rc != GLOBUS_SUCCESS )
        return 1;

    rc = globus_module_activate(GLOBUS_GASS_COPY_MODULE);
    if ( rc != GLOBUS_SUCCESS )
        return 1;
 
    gw_tm_ftp_init_xfr_pool(ids);
	
    initialized = 1;
    
    return 0;
}


/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_init(gw_tm_ftp_transfer_t *xfr, int jid)
{
    globus_result_t  grc;
	
    grc = globus_ftp_client_handleattr_init(&(xfr->attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
		
	grc = globus_ftp_client_handleattr_set_cache_all(&(xfr->attr), GLOBUS_TRUE);
    if ( grc != GLOBUS_SUCCESS )
		return -1;
	
    grc = globus_ftp_client_handle_init(&(xfr->handle),&(xfr->attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_ftp_client_operationattr_init(&(xfr->op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_init(&(xfr->gass_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_init(&(xfr->src_gass_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_ftp_client_operationattr_init(&(xfr->src_op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_attr_set_ftp(&(xfr->gass_attr), &(xfr->op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
    
    grc = globus_gass_copy_attr_set_ftp(&(xfr->src_gass_attr), &(xfr->src_op_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;
	
	grc = globus_gass_copy_handleattr_init(&(xfr->gass_handel_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

	grc = globus_gass_copy_handle_init(&(xfr->gass_handle), &(xfr->gass_handel_attr));
    if ( grc != GLOBUS_SUCCESS )
		return -1;

    grc = globus_gass_copy_set_no_third_party_transfers(&(xfr->gass_handle), GLOBUS_FALSE);
    if ( grc != GLOBUS_SUCCESS )
		return -1;
 
    xfr->jid = jid;
    xfr->handle_in_use = GW_FALSE;
    xfr->base_dir = NULL;
    xfr->list_buffer = NULL;    
    xfr->buffer_length = 0;
    xfr->read_buffer = (globus_byte_t *) malloc( GW_TM_FTP_BUFFER_LENGTH * sizeof(globus_byte_t));
    xfr->current_xfr.dst_url = NULL;
    xfr->current_xfr.src_url = NULL;
    xfr->current_xfr.cp_xfr_id = 0;
 
    gw_tm_ftp_stack_init(&(xfr->file_stack));

    gw_tm_ftp_queue_init(&(xfr->url_queue));	

    return 0;
}

void gw_tm_ftp_transfer_flush(gw_tm_ftp_transfer_t *xfr)
{    
    if ( xfr->list_buffer != NULL )
        free(xfr->list_buffer);
		
    xfr->list_buffer = NULL;
    xfr->buffer_length = 0;
}

void gw_tm_ftp_transfer_cancel_cb(void *user_arg,
        globus_gass_copy_handle_t *handle,
        globus_object_t *err)
{
	int xfr_id;
	gw_tm_ftp_transfer_t * xfr;
	xfr_id = *( (int *) user_arg );
	
	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    {
	    	free(user_arg);
	    	return;
	    }
	else
	{
    	free(user_arg);
		return;	
	}
	
   	free(user_arg);
	        
	globus_ftp_client_handle_destroy(&(xfr->handle));
    globus_ftp_client_handleattr_destroy(&(xfr->attr));
	
	globus_ftp_client_operationattr_destroy(&(xfr->op_attr));
	globus_ftp_client_operationattr_destroy(&(xfr->src_op_attr));
	
	globus_gass_copy_handle_destroy(&(xfr->gass_handle));
	globus_gass_copy_handleattr_destroy(&(xfr->gass_handel_attr));
	
	/* THERE IS NO FUNCTION TO DESTROY 	globus_gass_copy_attr_t */
	/*
	globus_gass_copy_attr_destroy(&(xfr->gass_attr));
	globus_gass_copy_attr_destroy(&(xfr->src_gass_attr));
	*/

	if ( xfr->current_xfr.src_url != NULL )
		free(xfr->current_xfr.src_url);	
		
	if ( xfr->current_xfr.dst_url != NULL )
		free(xfr->current_xfr.dst_url);
	
	if ( xfr->list_buffer != NULL )
		free(xfr->list_buffer);
		
	if ( xfr->read_buffer != NULL )
		free(xfr->read_buffer);	
		
	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);

    gw_tm_ftp_stack_destroy(&(xfr->file_stack));
    gw_tm_ftp_queue_destroy(&(xfr->url_queue));	
	
    printf("END %i - SUCCESS -\n",xfr_id);
	
    free(gw_tm_ftp_xfr_pool[xfr_id]);
   	
    gw_tm_ftp_xfr_pool[xfr_id] = NULL;
	
}

void gw_tm_ftp_transfer_destroy(gw_tm_ftp_transfer_t *xfr)
{    
	int *xfr_id;
	globus_result_t rc;
	
	xfr_id = ( int *) malloc(sizeof(int));
	*xfr_id = xfr->jid;
	
	globus_ftp_client_abort(&(xfr->handle));
	
	rc = globus_gass_copy_cancel( &(xfr->gass_handle), gw_tm_ftp_transfer_cancel_cb,
        (void *)  xfr_id);
    
    if ( rc != GLOBUS_SUCCESS ) /* No transfer in progress */
		gw_tm_ftp_transfer_cancel_cb((void *)  xfr_id, NULL, NULL);
	    
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_expand_url(int xfr_id,
        const char *url_dir,
        globus_ftp_client_complete_callback_t done_cb)
{
    globus_result_t grc;
    int rc;
    int length;
    gw_tm_ftp_transfer_t *xfr;
    int *_xfr_id;
	
    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
            return 1;
    else
        return 1;

	length = strlen(url_dir);

	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);
	
	if ( url_dir[length-1] != '/' )
	{
		xfr->base_dir = (char *) malloc ( (length + 2)	* sizeof(char) );
		snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
	}
	else
		xfr->base_dir = strdup(url_dir);
		
	xfr->base_dir_length = strlen(xfr->base_dir);
	
	rc = gw_tm_ftp_stack_push(&(xfr->file_stack), xfr->base_dir, GW_TM_FTP_DIR, GW_TRUE);
		
	if ( rc != 0 )
		return 1;
	
	/* MACHINE LIST SHOULD BE CHECK IF FEATURE IS SUPPORTED */
	/* WE WILL USE LIST COMMAND...
	grc = globus_ftp_client_machine_list( &(xfr->handle), xfr->base_dir, 
			&(xfr->op_attr), done_cb, (void *) xfr);
	*/
	
	_xfr_id = ( int *) malloc (sizeof(int));
	*(_xfr_id) = xfr->jid;
	
	grc = globus_ftp_client_verbose_list( &(xfr->handle), xfr->base_dir,
			&(xfr->op_attr), done_cb, (void *) _xfr_id);

	if ( grc != GLOBUS_SUCCESS)
	{
		free(_xfr_id);
		return 1;
	}

    _xfr_id = ( int *) malloc (sizeof(int));
    *(_xfr_id) = xfr->jid;
		
    grc = globus_ftp_client_register_read (&(xfr->handle), (xfr->read_buffer),
            GW_TM_FTP_BUFFER_LENGTH, gw_tm_ftp_list_read_callback, (void *) _xfr_id);
			
    if ( grc != GLOBUS_SUCCESS )
    {
    	free(_xfr_id); /*Leaving one int (_xfr_id) behind!!!!*/
        return 1;
    }
    
    return 0;
}



/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void gw_tm_ftp_list_read_callback(void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err,
        globus_byte_t *buffer,
        globus_size_t length,
        globus_off_t offset,
        globus_bool_t eof)
{
    gw_tm_ftp_transfer_t * xfr;	
    globus_result_t grc;
    char *temp_p = NULL;
    char *start_ptr;
    char *end_ptr;
    char mode[16];
    char links[16];
    char owner[16];
    char group[16];
    char size[16];
    char month[16];
    char day[16];
    char hour_year[256];
    char file[256];	
    char *filename;
    char *url;
    int i, len, rc;
    int xfr_id;
 
    if(err)  /* ERROR DIR DOES NOT EXISTS : ERROR HANDLING NOT HERE */
        return;

    xfr_id = *( (int *) user_arg );
	
    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
        {
            free(user_arg);
            return;
        }
    else
    {
        free(user_arg);
        return;	
    }
	   	
    if( xfr->list_buffer == NULL && eof && offset == 0)
    {
        xfr->list_buffer = (char *) malloc( sizeof(char) *length); 
        xfr->buffer_length = length;
        
        memcpy(xfr->list_buffer,buffer,length);
    }
    else
    {
        if( (length + offset) > xfr->buffer_length )
        {
            temp_p = (char *) realloc(xfr->list_buffer, length + offset);    
            xfr->list_buffer = temp_p;
            xfr->buffer_length = length + offset;
        }       

        memcpy(xfr->list_buffer + offset,buffer,length);
    }
    
    if(!eof)
    {
        grc = globus_ftp_client_register_read (&(xfr->handle), buffer,
                GW_TM_FTP_BUFFER_LENGTH, gw_tm_ftp_list_read_callback, user_arg);
			
        if( grc != GLOBUS_SUCCESS ) /* ERROR & CANCEL? */
        {
            err_str = print_error(err);

            printf("RMDIR %d - FAILURE globus_ftp_client_register_read (%s)\n",
                    xfr->jid, err_str);

            free(err_str);
            free(user_arg);
            return;
        } 
    }
    else
    {
    	i = 0;
    	start_ptr = xfr->list_buffer;
    	end_ptr = xfr->list_buffer;
    	
    	while (i < xfr->buffer_length)
    	{
            while ((*end_ptr != '\n') && (*end_ptr != '\r'))
            {
                end_ptr++;
                i++;
            }
 
            *end_ptr = '\0';

            rc = sscanf(start_ptr, "%s %s %s %s %s %s %s %s %s",
                    mode, links, owner, group, size, month,
                    day, hour_year, file);

            if ( rc == 8 )
                filename = hour_year;
            else if (rc == 9)
                filename = file;
            else
            {
                start_ptr = end_ptr+1;
                end_ptr = start_ptr;
                i = i+1;
                continue;
            }
 
            if ( (strcmp(filename, ".") != 0)
                    && (strcmp(filename, "..") != 0) )
            {
                len = xfr->base_dir_length + strlen(filename) + 1;

                if (mode[0] == '-')
                {
                    url = (char *) malloc (sizeof(char)* len);

                    snprintf(url, sizeof(char)*len, "%s%s",
                            xfr->base_dir, filename);

                    gw_tm_ftp_stack_push(&(xfr->file_stack), url, GW_TM_FTP_FILE, GW_FALSE);
                    free(url);
                }
                else if (mode[0] == 'd')
                {
                    url = (char *) malloc (sizeof(char)* (len+1));
                    snprintf(url, sizeof(char)*(len + 1), "%s%s/",
                            xfr->base_dir, filename);

                    gw_tm_ftp_stack_push(&(xfr->file_stack), url, GW_TM_FTP_DIR, GW_FALSE);
                    free(url);
                }
            }

            start_ptr = end_ptr+1;
            end_ptr = start_ptr;
	    i = i+1;
        }
 
        free(xfr->list_buffer);
 
        xfr->list_buffer = NULL;
        xfr->buffer_length = 0;
 
        free(user_arg);
    }

    return;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_rmdir(int xfr_id, const char *url_dir)
{
	int rc;

	rc = gw_tm_ftp_transfer_expand_url(xfr_id, url_dir, gw_tm_ftp_transfer_rmdir_cb);	
	
	return rc;
}							   

/* -------------------------------------------------------------------------- */

void gw_tm_ftp_transfer_rmdir_cb(
        void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err)
{
    gw_tm_ftp_transfer_t *xfr;
    gw_tm_ftp_stack_t *file;
    globus_result_t grc;
    int xfr_id;
 
    xfr_id = *( (int *) user_arg );

    if ( (xfr_id < GW_TM_FTP_XFR_POOL_MAX) && (xfr_id >= 0) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
        {
            /*printf("RMDIR %d - FAILURE transfer does not exist.\n", xfr_id);*/
 
            free(user_arg);
            return;
        }
	else
	{
	    /*printf("RMDIR %d - FAILURE invalid transfer id in callback.\n", xfr_id);*/
	    			
            free(user_arg);
            return;
	}

    if (err != GLOBUS_SUCCESS) /* ERROR RMDIR OR EXPAND */
    {
        err_str = print_error(err);

        printf("RMDIR %d - FAILURE rmdir_cb (%s).\n", xfr->jid, err_str);

        free(err_str);
        free(user_arg);
        return;
    }

    file = gw_tm_ftp_stack_pop(&(xfr->file_stack));

    if( file != NULL )
    {
       if ( (file->type == GW_TM_FTP_DIR) && (file->expanded == GW_FALSE) )
       {
            gw_tm_ftp_transfer_flush(xfr);
            gw_tm_ftp_transfer_expand_url(xfr_id, file->file_name, 
                    gw_tm_ftp_transfer_rmdir_cb);

            free(file->file_name);
            free(file);
            free(user_arg);
            return;
        }
        else
        {
            if ( file->type == GW_TM_FTP_FILE )
                grc = globus_ftp_client_delete(&(xfr->handle),
                        file->file_name, &(xfr->op_attr),
       	                gw_tm_ftp_transfer_rmdir_cb, user_arg);
            else
                grc = globus_ftp_client_rmdir(&(xfr->handle),
                        file->file_name, &(xfr->op_attr),
                        gw_tm_ftp_transfer_rmdir_cb, user_arg);

            if ( grc != GLOBUS_SUCCESS )
            {
                err_str = print_error(err);

                printf("RMDIR %d - FAILURE globus_ftp_client_delete/rmdir %s (%s)\n",
                        xfr->jid, file->file_name, err_str);

                free(err_str);
                free(user_arg);
            }

            free(file->file_name);
            free(file);
            return;
        }
    }

    printf("RMDIR %d - SUCCESS -\n", xfr->jid);
    free(user_arg);
}


/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void gw_tm_ftp_transfer_exists_dir_cb(void *user_arg,
        globus_ftp_client_handle_t *handle,
        globus_object_t *err)
{
    gw_tm_ftp_transfer_t *xfr;
    int xfr_id;

    xfr_id = *( (int *) user_arg );

    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
    else
    {
        /*printf("EXISTS %d - FAILURE transfer does not exist.\n", xfr_id);*/
    	
        free(user_arg);
        return;
    }
    else
    {
    	/*printf("EXISTS %d - FAILURE invalid transfer id in callback.\n", xfr_id);*/		
    	
        free(user_arg);
        return;	
    }
 
    if(err != GLOBUS_SUCCESS) /* FILE DOES NOT EXISTS, OR GSS ERROR*/
    {    		
    	printf("EXISTS %d - FAILURE -\n", xfr->jid);
    }
    else
    {
        printf("EXISTS %d - SUCCESS -\n", xfr->jid);
    }
 
    free(user_arg);
}

/* ---------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_exists_dir(int xfr_id,
        const char *url_dir)
{
    globus_result_t grc;
    int length;
    gw_tm_ftp_transfer_t *xfr;
    int *_xfr_id;
	
    if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
        if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
            xfr = gw_tm_ftp_xfr_pool[xfr_id];
        else
            return 1;
    else
        return 1;	   	
	
    if ( xfr->base_dir != NULL )
        free(xfr->base_dir);

    length = strlen(url_dir);

    if ( url_dir[length-1] != '/' )
    {
        xfr->base_dir = (char *) malloc( (length + 2)*sizeof(char) );
        snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
    }
    else
        xfr->base_dir = strdup(url_dir);

    xfr->base_dir_length = strlen(xfr->base_dir);

    _xfr_id = ( int *) malloc (sizeof(int));
    *(_xfr_id) = xfr->jid;

    grc = globus_ftp_client_exists(&(xfr->handle), xfr->base_dir, &(xfr->op_attr), 
            gw_tm_ftp_transfer_exists_dir_cb, (void *) _xfr_id);

    if (grc != GLOBUS_SUCCESS)
    {
        free(_xfr_id);
        return 1;
    }
    else
        return 0;

}



/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int gw_tm_ftp_transfer_mkdir(int xfr_id,
        const char *url_dir)
{
    globus_result_t        grc;
   	int				   length;
	gw_tm_ftp_transfer_t * xfr;
	int *                  _xfr_id;

	if ( ( xfr_id < GW_TM_FTP_XFR_POOL_MAX ) && (xfr_id >= 0 ) )
	    if ( gw_tm_ftp_xfr_pool[xfr_id] != NULL )
	    	xfr = gw_tm_ftp_xfr_pool[xfr_id];
	    else
	    	return 1;
	else
		return 1;	   
			
	if ( xfr->base_dir != NULL )
		free(xfr->base_dir);
	
	length = strlen(url_dir);

	if ( url_dir[length-1] != '/' )
	{
		xfr->base_dir = (char *) malloc ( (length + 2)	* sizeof(char) );
		snprintf(xfr->base_dir,(length + 2)*sizeof(char), "%s/",url_dir);
	}
	else
		xfr->base_dir = strdup(url_dir);
{'fraction_non_alphanumeric': 0.2048290901447676, 'fraction_numerical': 0.005307269908830562, 'mean_word_length': 1.5481689763674098, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 279, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2125325', 'n_tokens_mistral': 14169, 'n_tokens_neox': 13130, 'n_words': 2201}