void GridFTP_Commands::data_connect_store_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) { GridFTP_Commands *it = (GridFTP_Commands*)arg; logger.msg(Arc::VERBOSE, "data_connect_store_callback"); globus_thread_blocking_will_block(); globus_mutex_lock(&(it->data_lock)); it->time_spent_disc=0; it->time_spent_network=0; it->last_action_time=time(NULL); logger.msg(Arc::VERBOSE, "Data channel connected (store)"); if(it->check_abort(error)) { it->froot.close(false); globus_mutex_unlock(&(it->data_lock)); return; }; it->data_eof = false; /* make buffers */ it->compute_data_buffer(); if(!(it->allocate_data_buffer())) { it->froot.close(false); it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return; }; /* register all available buffers */ it->data_callbacks=0; globus_result_t res = GLOBUS_SUCCESS; for(unsigned int i = 0;i<it->data_buffer_num;i++) { if(!((it->data_buffer)[i].data)) continue; struct timezone tz; gettimeofday(&(it->data_buffer[i].time_last),&tz); res=globus_ftp_control_data_read(&(it->handle), (globus_byte_t*)(it->data_buffer[i].data), it->data_buffer_size, &data_store_callback,it); if(res==GLOBUS_SUCCESS) { it->data_callbacks++; } else { break; }; }; if(it->data_callbacks==0) { logger.msg(Arc::ERROR, "Failed to register any buffer"); if(res != GLOBUS_SUCCESS) { logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str()); }; it->froot.close(false); it->free_data_buffer(); it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return; }; globus_mutex_unlock(&(it->data_lock)); return; }
/* *** list transfer callbacks *** */ void GridFTP_Commands::list_retrieve_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t* /* buffer */,globus_size_t /* length */,globus_off_t /* offset */,globus_bool_t /* eof */) { GridFTP_Commands *it = (GridFTP_Commands*)arg; globus_mutex_lock(&(it->data_lock)); it->last_action_time=time(NULL); if(it->check_abort(error)) { it->free_data_buffer(); globus_mutex_unlock(&(it->data_lock)); return; }; globus_bool_t eodf; globus_size_t size; if(it->dir_list_pointer == it->dir_list.end()) { it->virt_offset=0; it->transfer_mode=false; it->free_data_buffer(); logger.msg(Arc::VERBOSE, "Closing channel (list)"); it->send_response("226 Transfer completed.\r\n"); globus_mutex_unlock(&(it->data_lock)); return; }; globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE); ++(it->dir_list_pointer); if(it->dir_list_pointer == it->dir_list.end()) { size=0; eodf=GLOBUS_TRUE; } else { size=make_list_string(*(it->dir_list_pointer),it->list_mode, it->data_buffer[0].data,it->data_buffer_size, it->list_name_prefix.c_str()); eodf=GLOBUS_FALSE; }; globus_result_t res; res=globus_ftp_control_data_write(&(it->handle), (globus_byte_t*)(it->data_buffer[0].data), size,it->list_offset,eodf, &list_retrieve_callback,it); if(res != GLOBUS_SUCCESS) { it->free_data_buffer(); it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return; }; globus_mutex_unlock(&(it->data_lock)); }
void GridFTP_Commands::list_connect_retrieve_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) { GridFTP_Commands *it = (GridFTP_Commands*)arg; globus_mutex_lock(&(it->data_lock)); it->last_action_time=time(NULL); if(it->check_abort(error)) { globus_mutex_unlock(&(it->data_lock)); return; }; it->data_buffer_size=4096; it->data_buffer_num=1; if(!it->allocate_data_buffer()) { it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return; }; it->dir_list_pointer=it->dir_list.begin(); globus_size_t size; globus_bool_t eodf; if(it->dir_list_pointer == it->dir_list.end()) { size=0; eodf=GLOBUS_TRUE; } else { size=make_list_string(*(it->dir_list_pointer),it->list_mode, it->data_buffer[0].data,it->data_buffer_size, it->list_name_prefix.c_str()); eodf=GLOBUS_FALSE; }; it->list_offset = 0; logger.msg(Arc::VERBOSE, "Data channel connected (list)"); globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE); globus_result_t res; res=globus_ftp_control_data_write(&(it->handle), (globus_byte_t*)(it->data_buffer[0].data), size,it->list_offset,eodf, &list_retrieve_callback,it); if(res != GLOBUS_SUCCESS) { it->free_data_buffer(); it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return; }; it->list_offset+=size; globus_mutex_unlock(&(it->data_lock)); }
void GridFTP_Commands::data_store_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t *buffer,globus_size_t length,globus_off_t offset,globus_bool_t eof) { globus_thread_blocking_will_block(); GridFTP_Commands *it = (GridFTP_Commands*)arg; struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); globus_mutex_lock(&(it->data_lock)); it->last_action_time=time(NULL); logger.msg(Arc::VERBOSE, "Data channel (store) %i %i %i", (int)offset, (int)length, (int)eof); it->data_callbacks--; if(it->check_abort(error)) { if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);}; globus_mutex_unlock(&(it->data_lock)); return; }; if(eof) it->data_eof=true; /* find this buffer */ unsigned int i; for(i = 0;i<it->data_buffer_num;i++) { if((it->data_buffer)[i].data == (unsigned char*)buffer) break; }; if(i >= it->data_buffer_num) { /* lost buffer - probably memory corruption */ logger.msg(Arc::ERROR, "data_store_callback: lost buffer"); it->force_abort(); if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);}; globus_mutex_unlock(&(it->data_lock)); return; }; unsigned long long int time_diff = (tv.tv_sec-(it->data_buffer[i].time_last.tv_sec))*1000000+ (tv.tv_usec-(it->data_buffer[i].time_last.tv_usec)); it->time_spent_network+=time_diff; /* write data to file NOTE: it->data_lock is not unlocked here because it->froot.write is not thread safe */ struct timeval tv_last; gettimeofday(&tv_last,&tz); if(it->froot.write(it->data_buffer[i].data, (it->virt_offset)+offset,length) != 0) { logger.msg(Arc::ERROR, "Closing channel (store) due to error: %s", it->froot.error); it->force_abort(); if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);}; globus_mutex_unlock(&(it->data_lock)); return; }; gettimeofday(&tv,&tz); time_diff=(tv.tv_sec-tv_last.tv_sec)*1000000+(tv.tv_usec-tv_last.tv_usec); it->time_spent_disc+=time_diff; if(it->data_eof) { if(it->data_callbacks==0) { logger.msg(Arc::VERBOSE, "Closing channel (store)"); it->free_data_buffer(); it->virt_offset=0; it->virt_restrict=false; it->transfer_mode=false; if(it->froot.close() != 0) { if(it->froot.error.length()) { it->send_response("451 "+it->froot.error+"\r\n"); } else { it->send_response("451 Local error\r\n"); }; } else { logger.msg(Arc::VERBOSE, "Time spent waiting for network: %.3f ms", (float)(it->time_spent_network/1000.0)); logger.msg(Arc::VERBOSE, "Time spent waiting for disc: %.3f ms", (float)(it->time_spent_disc/1000.0)); it->send_response("226 Requested file transfer completed\r\n"); }; }; globus_mutex_unlock(&(it->data_lock)); return; }; /* register buffer */ globus_result_t res; gettimeofday(&(it->data_buffer[i].time_last),&tz); res=globus_ftp_control_data_read(&(it->handle), (globus_byte_t*)(it->data_buffer[i].data), it->data_buffer_size, &data_store_callback,it); if(res != GLOBUS_SUCCESS) { /* Because this error can be caused by EOF, abort should not be called unless this is last buffer */ if(it->data_callbacks==0) { logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str()); it->force_abort(); it->free_data_buffer();it->froot.close(false); }; globus_mutex_unlock(&(it->data_lock)); return; }; it->data_callbacks++; globus_mutex_unlock(&(it->data_lock)); return; }