From a0aff5b1462edacd364036c465fbbf32fc00f2c1 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 19 Mar 2017 12:48:01 +0300 Subject: [PATCH] Fix #136 - Skip links, sockets, fifos and etc --- libgrive/src/base/Resource.cc | 28 ++++++++++++++++++---------- libgrive/src/util/OS.cc | 12 ++++++------ libgrive/src/util/OS.hh | 6 ++++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libgrive/src/base/Resource.cc b/libgrive/src/base/Resource.cc index 23ce335..72c8052 100644 --- a/libgrive/src/base/Resource.cc +++ b/libgrive/src/base/Resource.cc @@ -262,10 +262,10 @@ void Resource::FromLocal( Val& state ) if ( !IsRoot() ) { fs::path path = Path() ; - bool is_dir; + FileType ft ; try { - os::Stat( path, &m_ctime, (off64_t*)&m_size, &is_dir ) ; + os::Stat( path, &m_ctime, (off64_t*)&m_size, &ft ) ; } catch ( os::Error &e ) { @@ -276,22 +276,30 @@ void Resource::FromLocal( Val& state ) m_kind = "bad"; return; } + if ( ft == FT_UNKNOWN ) + { + // Skip sockets/FIFOs/etc + Log( "File %1% is not a regular file or directory; skipping file", path.string(), log::warning ); + m_state = sync; + m_kind = "bad"; + return; + } m_name = path.filename().string() ; - m_kind = is_dir ? "folder" : "file"; + m_kind = ft == FT_DIR ? "folder" : "file"; m_local_exists = true; bool is_changed; if ( state.Has( "ctime" ) && (u64_t) m_ctime.Sec() <= state["ctime"].U64() && - ( is_dir || state.Has( "md5" ) ) ) + ( ft == FT_DIR || state.Has( "md5" ) ) ) { - if ( !is_dir ) + if ( ft != FT_DIR ) m_md5 = state["md5"]; is_changed = false; } else { - if ( !is_dir ) + if ( ft != FT_DIR ) { // File is changed locally. TODO: Detect conflicts is_changed = ( state.Has( "size" ) && m_size != state["size"].U64() ) || @@ -703,13 +711,13 @@ void Resource::SetIndex( bool re_stat ) assert( m_parent && m_parent->m_json != NULL ); if ( !m_json ) m_json = &((*m_parent->m_json)["tree"]).Item( Name() ); - bool is_dir; + FileType ft; if ( re_stat ) - os::Stat( Path(), &m_ctime, NULL, &is_dir ); + os::Stat( Path(), &m_ctime, NULL, &ft ); else - is_dir = IsFolder(); + ft = IsFolder() ? FT_DIR : FT_FILE; m_json->Set( "ctime", Val( m_ctime.Sec() ) ); - if ( !is_dir ) + if ( ft != FT_DIR ) { m_json->Set( "md5", Val( m_md5 ) ); m_json->Set( "size", Val( m_size ) ); diff --git a/libgrive/src/util/OS.cc b/libgrive/src/util/OS.cc index 9095e73..e8b468f 100644 --- a/libgrive/src/util/OS.cc +++ b/libgrive/src/util/OS.cc @@ -39,12 +39,12 @@ namespace gr { namespace os { -void Stat( const fs::path& filename, DateTime *t, off_t *size, bool *is_dir ) +void Stat( const fs::path& filename, DateTime *t, off_t *size, FileType *ft ) { - Stat( filename.string(), t, size, is_dir ) ; + Stat( filename.string(), t, size, ft ) ; } -void Stat( const std::string& filename, DateTime *t, off64_t *size, bool *is_dir ) +void Stat( const std::string& filename, DateTime *t, off64_t *size, FileType *ft ) { struct stat s = {} ; if ( ::stat( filename.c_str(), &s ) != 0 ) @@ -57,7 +57,7 @@ void Stat( const std::string& filename, DateTime *t, off64_t *size, bool *is_dir ) ; } - if (t) + if ( t ) { #if defined __APPLE__ && defined __DARWIN_64_BIT_INO_T *t = DateTime( s.st_ctimespec.tv_sec, s.st_ctimespec.tv_nsec ) ; @@ -67,8 +67,8 @@ void Stat( const std::string& filename, DateTime *t, off64_t *size, bool *is_dir } if ( size ) *size = s.st_size; - if ( is_dir ) - *is_dir = S_ISDIR( s.st_mode ) ? true : false; + if ( ft ) + *ft = S_ISDIR( s.st_mode ) ? FT_DIR : ( S_ISREG( s.st_mode ) ? FT_FILE : FT_UNKNOWN ) ; } void SetFileTime( const fs::path& filename, const DateTime& t ) diff --git a/libgrive/src/util/OS.hh b/libgrive/src/util/OS.hh index 4349783..bd28e30 100644 --- a/libgrive/src/util/OS.hh +++ b/libgrive/src/util/OS.hh @@ -29,12 +29,14 @@ namespace gr { class DateTime ; class Path ; +enum FileType { FT_FILE = 1, FT_DIR = 2, FT_UNKNOWN = 3 } ; + namespace os { struct Error : virtual Exception {} ; - void Stat( const std::string& filename, DateTime *t, off64_t *size, bool *is_dir ) ; - void Stat( const fs::path& filename, DateTime *t, off64_t *size, bool *is_dir ) ; + void Stat( const std::string& filename, DateTime *t, off64_t *size, FileType *ft ) ; + void Stat( const fs::path& filename, DateTime *t, off64_t *size, FileType *ft ) ; void SetFileTime( const std::string& filename, const DateTime& t ) ; void SetFileTime( const fs::path& filename, const DateTime& t ) ;