Fix #136 - Skip links, sockets, fifos and etc

pull/59/merge
Vitaliy Filippov 2017-03-19 12:48:01 +03:00
parent e8a8801c75
commit a0aff5b146
3 changed files with 28 additions and 18 deletions

View File

@ -262,10 +262,10 @@ void Resource::FromLocal( Val& state )
if ( !IsRoot() ) if ( !IsRoot() )
{ {
fs::path path = Path() ; fs::path path = Path() ;
bool is_dir; FileType ft ;
try 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 ) catch ( os::Error &e )
{ {
@ -276,22 +276,30 @@ void Resource::FromLocal( Val& state )
m_kind = "bad"; m_kind = "bad";
return; 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_name = path.filename().string() ;
m_kind = is_dir ? "folder" : "file"; m_kind = ft == FT_DIR ? "folder" : "file";
m_local_exists = true; m_local_exists = true;
bool is_changed; bool is_changed;
if ( state.Has( "ctime" ) && (u64_t) m_ctime.Sec() <= state["ctime"].U64() && 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"]; m_md5 = state["md5"];
is_changed = false; is_changed = false;
} }
else else
{ {
if ( !is_dir ) if ( ft != FT_DIR )
{ {
// File is changed locally. TODO: Detect conflicts // File is changed locally. TODO: Detect conflicts
is_changed = ( state.Has( "size" ) && m_size != state["size"].U64() ) || 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 ); assert( m_parent && m_parent->m_json != NULL );
if ( !m_json ) if ( !m_json )
m_json = &((*m_parent->m_json)["tree"]).Item( Name() ); m_json = &((*m_parent->m_json)["tree"]).Item( Name() );
bool is_dir; FileType ft;
if ( re_stat ) if ( re_stat )
os::Stat( Path(), &m_ctime, NULL, &is_dir ); os::Stat( Path(), &m_ctime, NULL, &ft );
else else
is_dir = IsFolder(); ft = IsFolder() ? FT_DIR : FT_FILE;
m_json->Set( "ctime", Val( m_ctime.Sec() ) ); 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( "md5", Val( m_md5 ) );
m_json->Set( "size", Val( m_size ) ); m_json->Set( "size", Val( m_size ) );

View File

@ -39,12 +39,12 @@
namespace gr { namespace os { 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 = {} ; struct stat s = {} ;
if ( ::stat( filename.c_str(), &s ) != 0 ) 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 #if defined __APPLE__ && defined __DARWIN_64_BIT_INO_T
*t = DateTime( s.st_ctimespec.tv_sec, s.st_ctimespec.tv_nsec ) ; *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 ) if ( size )
*size = s.st_size; *size = s.st_size;
if ( is_dir ) if ( ft )
*is_dir = S_ISDIR( s.st_mode ) ? true : false; *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 ) void SetFileTime( const fs::path& filename, const DateTime& t )

View File

@ -29,12 +29,14 @@ namespace gr {
class DateTime ; class DateTime ;
class Path ; class Path ;
enum FileType { FT_FILE = 1, FT_DIR = 2, FT_UNKNOWN = 3 } ;
namespace os namespace os
{ {
struct Error : virtual Exception {} ; struct Error : virtual Exception {} ;
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 ) ;
void Stat( const fs::path& filename, DateTime *t, off64_t *size, bool *is_dir ) ; 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 std::string& filename, const DateTime& t ) ;
void SetFileTime( const fs::path& filename, const DateTime& t ) ; void SetFileTime( const fs::path& filename, const DateTime& t ) ;