void file_cpi_impl::sync_copy (saga::impl::void_t & ret, saga::url dest, int flags) { adaptor_data_t AdaptorData(this); file_instance_data_t InstanceData (this); GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(InstanceData->location_); saga::url target = merge_urls(InstanceData->location_.get_url(), dest); try { if(ConnectionHandle->exist(target.get_url())) { if(ConnectionHandle->is_dir(target.get_url())) { std::string url_path = target.get_path(); if(url_path.rfind("/") != url_path.length()-1) url_path.append("/"); saga::url this_name; this->sync_get_name(this_name); url_path.append(this_name.get_path()); target.set_path(url_path); } } ConnectionHandle->copy_url(InstanceData->location_.get_url(), target.get_url()); } catch( curl_file_adaptor::exception const & e ) { error_package ep = curl_file_adaptor ::error_default_redirect(e, InstanceData->location_.get_url()); SAGA_OSSTREAM strm; strm << "Could not copy [" << InstanceData->location_ << " -> " << target << "]. " << ep.error_text; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), ep.saga_error); } }
void dir_cpi_impl::sync_is_entry (bool & is_entry, saga::url url) { adaptor_data_t AdaptorData(this); directory_instance_data_t InstanceData(this); this->throw_if_local(InstanceData->location_); this->check_if_open ("dir_cpi_impl::sync_is_entry", InstanceData->location_); saga::url u = merge_urls(InstanceData->location_.get_url(), url); bool is_dir = true; bool is_link = true; try { GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(u, write_log_, logfile_loc_); is_dir = ConnectionHandle->is_dir(u.get_url()); is_link = ConnectionHandle->is_symlink(u.get_url()); } catch( globus_gridftp_file_adaptor::exception const &e) { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, InstanceData->location_.get_url()); SAGA_OSSTREAM strm; strm << "Could not check if [" << u.get_url() << "] is an entry. " << ep.error_text; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), ep.saga_error); } if( !is_dir && !is_link ) is_entry = true; else is_entry = false; }
void file_cpi_impl::sync_move (saga::impl::void_t & ret, saga::url dest, int flags) { adaptor_data_t AdaptorData(this); file_instance_data_t InstanceData (this); try { sync_copy(ret, dest, flags); } catch(saga::exception const & e) { SAGA_OSSTREAM strm; strm << "Could not move [" << InstanceData->location_ << " -> " << dest << "]. Copying source file failed!"; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), e.get_error()); } try { sync_remove(ret, flags); } catch(saga::exception const & e) { SAGA_OSSTREAM strm; strm << "Could not move [" << InstanceData->location_ << " -> " << dest << "]. Removing source file failed!"; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), e.get_error()); } /// This code tries to generate a proper URL for the moved file /// and sets this instance's location to the new location /// FIXME: is this behaviour ok - spec. doesn't say anything about it? saga::url target = merge_urls(InstanceData->location_.get_url(), dest); try { GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(InstanceData->location_); if(ConnectionHandle->exist(target.get_url())) { if(ConnectionHandle->is_dir(target.get_url())) { std::string url_path = target.get_path(); if(url_path.rfind("/") != url_path.length()-1) url_path.append("/"); saga::url this_name; this->sync_get_name(this_name); url_path.append(this_name.get_path()); target.set_path(url_path); } } } catch( curl_file_adaptor::exception const & e ) { //FIXME ??? } InstanceData->location_ = target; // FIXME: is this behaviour ok? }
void dir_cpi_impl::sync_remove (saga::impl::void_t & ret, saga::url url, int flags) { adaptor_data_t AdaptorData(this); directory_instance_data_t InstanceData(this); this->throw_if_local(InstanceData->location_); this->check_if_open ("dir_cpi_impl::sync_remove", InstanceData->location_); saga::url u = merge_urls(InstanceData->location_.get_url(), url); GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(u, write_log_, logfile_loc_); try { if( ConnectionHandle->is_dir( u.get_url() ) ) { if(flags & saga::filesystem::Recursive) { saga::filesystem::directory basedir(u); std::vector<saga::url> entries = basedir.list(); for(unsigned int i = 0; i < entries.size(); ++i) { if(basedir.is_dir(entries[i])) { basedir.remove(entries[i], saga::filesystem::Recursive); } else { basedir.remove(entries[i], saga::filesystem::None); } } ConnectionHandle->remove_directory( u.get_url() ); } } else { ConnectionHandle->remove_file( u.get_url() ); } } catch( globus_gridftp_file_adaptor::exception const & e ) { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, u.get_url()); SAGA_OSSTREAM strm; strm << "Could not remove [" << u << "]. " << ep.error_text; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), ep.saga_error); } }
void dir_cpi_impl::sync_change_dir (saga::impl::void_t &, saga::url new_dir) { adaptor_data_t AdaptorData(this); directory_instance_data_t InstanceData(this); this->throw_if_local(InstanceData->location_); saga::url url = merge_urls(InstanceData->location_.get_url(), new_dir); GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(url, write_log_, logfile_loc_); bool is_dir = false; try { is_dir = ConnectionHandle->is_dir( url.get_url() ); } catch( exception const & e ) { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, InstanceData->location_.get_url()); std::string e_text("Could not change directory. " + ep.error_text); SAGA_ADAPTOR_THROW(e_text, ep.saga_error); } if( !is_dir ) { SAGA_OSSTREAM strm; strm << "Could not change to directory [" << InstanceData->location_ << "]. " << "URL doesn't point to a directory." ; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } InstanceData->location_ = url; }
dir_cpi_impl::dir_cpi_impl (proxy * p, cpi_info const & info, saga::ini::ini const & glob_ini, saga::ini::ini const & adap_ini, boost::shared_ptr<saga::adaptor> adaptor) : directory_cpi (p, info, adaptor, cpi::Noflags) { adaptor_data_t adata(this); instance_data idata(this); // Read some stuff from the .ini file saga::ini::ini prefs = adap_ini.get_section ("preferences"); if (prefs.has_entry("write_ftp_log")) { std::string wfl = prefs.get_entry("write_ftp_log"); if(wfl == "true" || wfl == "True" || wfl == "TRUE") { write_log_ = true; } else { write_log_ = false; } } if (prefs.has_entry("logilfe_location")) logfile_loc_ = prefs.get_entry("logilfe_location"); else logfile_loc_ = "saga_gridftp.log"; saga::url location(idata->location_); std::string host(location.get_host()); std::string scheme(location.get_scheme()); // check if we can handle url scheme if (scheme != "file" && scheme != "gridftp" && scheme != "gsiftp") { SAGA_OSSTREAM strm; strm << "Could not initialize file object for [" << idata->location_ << "]. " << "Only griftp:// and gsiftp:// schemes are supported."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::adaptors::AdaptorDeclined); } this->is_local_dir_ = false; if (scheme == "file") { this->is_local_dir_ = true; // make sure directory exist namespace fs = boost::filesystem; try { std::string url = saga::url::unescape(location.get_path()); #if BOOST_FILESYSTEM_VERSION > 2 fs::path fpath (url); #else fs::path fpath (url, fs::native); #endif if ( ! fs::exists (fpath) ) { SAGA_OSSTREAM strm; strm << "Local directory doesn't exist: [" << location << "]."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::adaptors::AdaptorDeclined); } else { is_open_ = true; // otherwise check in copy() will fail return; } } catch (boost::system::system_error const& e) { SAGA_ADAPTOR_THROW( location.get_string() + ": caught filesystem exception: " + e.what(), saga::NoSuccess); } } else { if (host.empty()) { SAGA_OSSTREAM strm; strm << "Could not initialize file object for [" << idata->location_ << "]. " << "URL doesn't define a hostname."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } } // check if we have x.509 contexts available and if they are usable // with this adaptor. if no context is usable, the constructor fails with // an authorization failed exception. std::vector <saga::context> contexts = p->get_session ().list_contexts (); std::vector <saga::context> context_list; // holds a list of reasons why a context can't be used. if no context // can be used, the list will be appended to the exception message otherwise // it will be discarded. std::vector <std::string> context_error_list; for (unsigned int i = 0; i < contexts.size (); i++) { globus_adaptors_shared::check_x509_globus_cert(contexts[i], context_list, context_error_list); } if(context_list.size() <1) { SAGA_OSSTREAM strm; strm << "Could not initialize directory object for " << idata->location_ << ". " << "No valid and/or usable x.509 context could be found:\n"; for(unsigned int i=0; i<context_error_list.size(); ++i) { strm << " - " << context_error_list[i] << "\n"; } SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::AuthorizationFailed); } //If we've made it here, it should be safe to load // the GRAM modules now. The loader employs a sigleton mechanism, // so ut doesn't matter if we call this method multiple times. globus_module_loader::globus_init (); GridFTPConnection * ConnectionHandle = adata->getConnectionHandleForURL(saga::url(idata->location_.get_url()), write_log_, logfile_loc_); // check if file exists AND is a dir (not a file) bool exists = true; bool is_dir = false; try { is_dir = ConnectionHandle->is_dir(idata->location_.get_url()); } catch( globus_gridftp_file_adaptor::exception const & e ) { if( e.get_error() == DoesNotExist ) { exists = false; } else { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, idata->location_.get_url()); std::string e_text("Could not opend directory. " + ep.error_text); SAGA_ADAPTOR_THROW(e_text, ep.saga_error); } } // check for openmode // saga::filesystem::flags OpenMode = (saga::filesystem::flags)idata->mode_; if(exists) { if(!is_dir) { SAGA_ADAPTOR_THROW ("Could not open directory. URL doesn't point to a directory: " + idata->location_.get_url(), saga::BadParameter); } else { if((OpenMode & saga::filesystem::Create) && (OpenMode & saga::filesystem::Exclusive)) { SAGA_ADAPTOR_THROW ("Could not open directory with 'Exclusive' flag set. The directory already exists: " + idata->location_.get_url(), saga::AlreadyExists); } } } else // !exists { if(!(OpenMode & saga::filesystem::Create)) { SAGA_ADAPTOR_THROW ("Could not open directory. The directory doesn't exist and 'Create' flag is not set: " + idata->location_.get_url(), saga::DoesNotExist); } else { try { ConnectionHandle->make_directory( idata->location_.get_url() ); } catch( globus_gridftp_file_adaptor::exception const & e ) { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, idata->location_.get_url()); std::string e_text("Could not opend directory. " + ep.error_text); SAGA_ADAPTOR_THROW(e_text, ep.saga_error); } } } this->is_open_ = true; }
void dir_cpi_impl::sync_copy (saga::impl::void_t & ret, saga::url src, saga::url dst, int flags) { adaptor_data_t AdaptorData(this); directory_instance_data_t InstanceData (this); if(dst.get_scheme().empty() && dst.get_host().empty()) { SAGA_OSSTREAM strm; strm << "Could not copy [" << InstanceData->location_ << " -> " << dst << "]. Please specify scheme and/or hostname."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } if(dst.get_scheme() == "file") { if(dst.get_host() != "localhost") { SAGA_OSSTREAM strm; strm << "Could not copy [" << InstanceData->location_ << " -> " << dst << "]. If target URL scheme is 'file://', only 'localhost' is accepted as host."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } // avoid file:// -> file:// copy. if (InstanceData->location_.get_scheme() != "gridftp" && InstanceData->location_.get_scheme() != "gsiftp") { SAGA_OSSTREAM strm; strm << "Cannot copy file [" << InstanceData->location_ << "]. " << "Supported source URL schemes are: gridftp:// and gsiftp://"; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::adaptors::AdaptorDeclined); } } else { if(dst.get_scheme() != "gridftp" && dst.get_scheme() != "gsiftp" ) { SAGA_OSSTREAM strm; strm << "Could not copy [" << InstanceData->location_ << " -> " << dst << "]. Only gridftp:// and gsiftp:// and file:// schemes are supported for target urls."; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } } this->check_if_open ("dir_cpi_impl::sync_copy", InstanceData->location_); saga::url u_src = merge_urls(InstanceData->location_.get_url(), src); saga::url u_dst = merge_urls(InstanceData->location_.get_url(), dst); try { GridFTPConnection * ConnectionHandle = AdaptorData->getConnectionHandleForURL(InstanceData->location_, write_log_, logfile_loc_); if(ConnectionHandle->exist(u_dst.get_url())) { if(ConnectionHandle->is_dir(u_dst.get_url())) { std::string url_path = u_dst.get_path(); if(url_path.rfind("/") != url_path.length()-1) url_path.append("/"); saga::url this_name; this->sync_get_name(this_name); url_path.append(this_name.get_path()); u_dst.set_path(url_path); } } ConnectionHandle->copy_url(u_src.get_url(), u_dst.get_url()); } catch( globus_gridftp_file_adaptor::exception const & e ) { error_package ep = globus_gridftp_file_adaptor ::error_default_redirect(e, u_src.get_url()); SAGA_OSSTREAM strm; strm << "Could not copy [" << u_src << " -> " << u_dst << "]. " << ep.error_text; SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), ep.saga_error); } }