Beispiel #1
0
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;
}
Beispiel #3
0
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);  
    }
    
}