From a756414e7164ed193c422b698b4d4c8f5e682ae5 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 31 Jul 2016 22:05:03 +0300 Subject: [PATCH] Skip unreadable files during sync, remove extra stat calls (fix #63) --- debian/changelog | 4 ++-- libgrive/src/base/Resource.cc | 38 ++++++++++++++++++++++++++++------- libgrive/src/base/Resource.hh | 1 + 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6b2790a..db47f06 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -grive2 (0.5.1+git20160706) unstable; urgency=medium +grive2 (0.5.1+git20160731) unstable; urgency=medium * Newer dev version - -- Vitaliy Filippov Wed, 13 Jul 2016 21:12:55 +0300 + -- Vitaliy Filippov Wed, 31 Jul 2016 22:04:53 +0300 grive2 (0.5+git20160114) unstable; urgency=medium diff --git a/libgrive/src/base/Resource.cc b/libgrive/src/base/Resource.cc index fecbe56..72c3a26 100644 --- a/libgrive/src/base/Resource.cc +++ b/libgrive/src/base/Resource.cc @@ -52,7 +52,8 @@ Resource::Resource( const fs::path& root_folder ) : m_is_editable( true ), m_parent ( 0 ), m_state ( sync ), - m_json ( NULL ) + m_json ( NULL ), + m_local_exists( true ) { } @@ -62,7 +63,8 @@ Resource::Resource( const std::string& name, const std::string& kind ) : m_is_editable( true ), m_parent ( 0 ), m_state ( unknown ), - m_json ( NULL ) + m_json ( NULL ), + m_local_exists( false ) { } @@ -87,17 +89,22 @@ void Resource::FromRemoteFolder( const Entry& remote ) Log( "folder %1% is read-only", path, log::verbose ) ; // already sync - if ( fs::is_directory( path ) ) + if ( m_local_exists && m_kind == "folder" ) { Log( "folder %1% is in sync", path, log::verbose ) ; m_state = sync ; } - else if ( fs::exists( path ) ) + else if ( m_local_exists && m_kind == "file" ) { // TODO: handle type change Log( "%1% changed from folder to file", path, log::verbose ) ; m_state = sync ; } + else if ( m_local_exists && m_kind == "bad" ) + { + Log( "%1% inaccessible", path, log::verbose ) ; + m_state = sync ; + } else if ( remote.MTime().Sec() > m_mtime.Sec() ) // FIXME only seconds are stored in local index { // remote folder created after last sync, so remote is newer @@ -163,9 +170,13 @@ void Resource::FromRemoteFile( const Entry& remote ) m_state = m_parent->m_state ; } + else if ( m_kind == "bad" ) + { + m_state = sync; + } + // local not exists - // FIXME: Remove additional stat() call here - else if ( !fs::exists( path ) ) + else if ( !m_local_exists ) { Trace( "file %1% change stamp = %2%", Path(), remote.ChangeStamp() ) ; @@ -246,10 +257,23 @@ void Resource::FromLocal( Val& state ) { fs::path path = Path() ; bool is_dir; - os::Stat( path, &m_ctime, NULL, &is_dir ) ; + try + { + os::Stat( path, &m_ctime, NULL, &is_dir ) ; + } + catch ( os::Error &e ) + { + // invalid symlink, unreadable file or something else + int const* eno = boost::get_error_info< boost::errinfo_errno >(e); + Log( "Error accessing %1%: %2%; skipping file", path.string(), strerror( *eno ), log::warning ); + m_state = sync; + m_kind = "bad"; + return; + } m_name = path.filename().string() ; m_kind = is_dir ? "folder" : "file"; + m_local_exists = true; bool is_changed; if ( state.Has( "ctime" ) && (u64_t) m_ctime.Sec() <= state["ctime"].U64() && diff --git a/libgrive/src/base/Resource.hh b/libgrive/src/base/Resource.hh index 531b78d..e7ee0ac 100644 --- a/libgrive/src/base/Resource.hh +++ b/libgrive/src/base/Resource.hh @@ -162,6 +162,7 @@ private : State m_state ; Val* m_json ; + bool m_local_exists ; } ; } // end of namespace gr::v1