1 /* 2 * Part of WCM Commander 3 * https://github.com/corporateshark/WCMCommander 4 * wcm@linderdaum.com 5 */ 6 7 #pragma once 8 9 #include <sys/stat.h> 10 #include <time.h> 11 #include <atomic> 12 13 #include "wal.h" 14 #include "ncdialogs.h" 15 16 #include "vfspath.h" 17 #include "strconfig.h" 18 #include "globals.h" 19 20 21 #ifdef _WIN32 22 class FSTime 23 { 24 enum { FILETIME_OK = 1, TIME_T_OK = 2 }; 25 char flags; 26 FILETIME ft; 27 time_t tt; 28 public: 29 enum TIMESTAMP { TIME_CURRENT }; FSTime()30 FSTime() : flags(0) {} FSTime(TIMESTAMP timestamp)31 FSTime(TIMESTAMP timestamp) 32 { 33 time_t t; 34 time(&t); 35 SetTimeT(t); 36 } FSTime(time_t t)37 FSTime( time_t t ): flags( TIME_T_OK ), tt( t ) {} FSTime(FILETIME t)38 FSTime( FILETIME t ): flags( FILETIME_OK ), ft( t ) {} 39 time_t GetTimeT(); 40 FILETIME GetFileTime(); SetTimeT(time_t val)41 void SetTimeT( time_t val ) { tt = val; flags = TIME_T_OK; } SetFileTime(FILETIME val)42 void SetFileTime( FILETIME val ) { ft = val; flags = FILETIME_OK; } 43 time_t()44 operator time_t() { return GetTimeT(); } FILETIME()45 operator FILETIME() { return GetFileTime(); } 46 FSTime& operator = ( time_t t ) { SetTimeT( t ); return *this; } 47 FSTime& operator = ( FILETIME ft ) { SetFileTime( ft ); return *this; } 48 }; 49 #else 50 typedef time_t FSTime; 51 #endif 52 53 #ifdef _WIN32 54 # if !defined( S_IFMT ) 55 # define S_IFMT 0170000 //bitmask for the file type bitfields 56 # endif 57 # if !defined( S_IFSOCK ) 58 # define S_IFSOCK 0140000 //socket 59 # endif 60 # if !defined( S_IFLNK ) 61 # define S_IFLNK 0120000 //symbolic link 62 # endif 63 # if !defined( S_IFREG ) 64 # define S_IFREG 0100000 //regular file 65 # endif 66 # if !defined( S_IFBLK ) 67 # define S_IFBLK 0060000 //block device 68 # endif 69 # if !defined( S_IFDIR ) 70 # define S_IFDIR 0040000 //directory 71 # endif 72 # if !defined( S_IFCHR ) 73 # define S_IFCHR 0020000 //character device 74 # endif 75 # if !defined( S_IFIFO ) 76 # define S_IFIFO 0010000 //fifo 77 # endif 78 # if !defined( S_ISUID ) 79 # define S_ISUID 0004000 //set UID bit 80 # endif 81 # if !defined( S_ISGID ) 82 # define S_ISGID 0002000 //set GID bit (see below) 83 # endif 84 # if !defined( S_ISVTX ) 85 # define S_ISVTX 0001000 //sticky bit (see below) 86 # endif 87 # if !defined( S_IRWXU ) 88 # define S_IRWXU 00700 //mask for file owner permissions 89 # endif 90 # if !defined( S_IRUSR ) 91 # define S_IRUSR 00400 //owner has read permission 92 # endif 93 # if !defined( S_IWUSR ) 94 # define S_IWUSR 00200 //owner has write permission 95 # endif 96 # if !defined( S_IXUSR ) 97 # define S_IXUSR 00100 //owner has execute permission 98 # endif 99 # if !defined( S_IRWXG ) 100 # define S_IRWXG 00070 //mask for group permissions 101 # endif 102 # if !defined( S_IRGRP ) 103 # define S_IRGRP 00040 //group has read permission 104 # endif 105 # if !defined( S_IWGRP ) 106 # define S_IWGRP 00020 //group has write permission 107 # endif 108 # if !defined( S_IXGRP ) 109 # define S_IXGRP 00010 //group has execute permission 110 # endif 111 # if !defined( S_IRWXO ) 112 # define S_IRWXO 00007 //mask for permissions for others (not in group) 113 # endif 114 # if !defined( S_IROTH ) 115 # define S_IROTH 00004 //others have read permission 116 # endif 117 # if !defined( S_IWOTH ) 118 # define S_IWOTH 00002 //others have write permisson 119 # endif 120 # if !defined( S_IXOTH ) 121 # define S_IXOTH 00001 //others have execute permission 122 # endif 123 #endif 124 125 struct FSStatVfs 126 { 127 int64_t size; 128 int64_t avail; 129 FSStatVfsFSStatVfs130 FSStatVfs() : size( -1 ), avail( -1 ) {} 131 }; 132 133 struct FSStat 134 { 135 FSString link; 136 137 #ifdef _WIN32 138 DWORD dwFileAttributes; 139 #endif 140 int mode; 141 int64_t size; 142 FSTime m_CreationTime; 143 FSTime m_LastAccessTime; 144 FSTime m_LastWriteTime; 145 // for future use with ZwQueryDirectoryFile() 146 FSTime m_ChangeTime; 147 int uid; 148 int gid; 149 150 dev_t dev; 151 ino_t ino; 152 FSStatFSStat153 FSStat(): 154 #ifdef _WIN32 155 dwFileAttributes( 0 ), 156 #endif 157 mode( 0 ), size( 0 ), m_CreationTime( 0 ), m_LastAccessTime( 0 ), m_LastWriteTime( 0 ), m_ChangeTime( 0 ), uid( -1 ), gid( -1 ), dev( 0 ), ino( 0 ) 158 {} 159 FSStatFSStat160 FSStat( const FSStat& a ) 161 : mode( a.mode ) 162 , size( a.size ) 163 , m_CreationTime( a.m_CreationTime ) 164 , m_LastAccessTime( a.m_LastAccessTime ) 165 , m_LastWriteTime( a.m_LastWriteTime ) 166 , m_ChangeTime( a.m_ChangeTime ) 167 , uid( a.uid ) 168 , gid( a.gid ) 169 , dev( a.dev ) 170 , ino( a.ino ) 171 { 172 link.Copy( a.link ); 173 } 174 FSStat& operator = ( const FSStat& a ) 175 { 176 link.Copy( a.link ); 177 mode = a.mode; 178 size = a.size; 179 m_CreationTime = a.m_CreationTime; 180 m_LastAccessTime = a.m_LastAccessTime; 181 m_LastWriteTime = a.m_LastWriteTime; 182 m_ChangeTime = a.m_ChangeTime; 183 uid = a.uid; 184 gid = a.gid; 185 dev = a.dev; 186 ino = a.ino; 187 return *this; 188 } 189 IsLnkFSStat190 bool IsLnk() const { return !link.IsNull(); } IsRegFSStat191 bool IsReg() const { return ( mode & S_IFMT ) == S_IFREG; } IsDirFSStat192 bool IsDir() const { return ( mode & S_IFMT ) == S_IFDIR; } IsExeFSStat193 bool IsExe() const { return ( mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) != 0; } IsBadFSStat194 bool IsBad() const { return ( mode & S_IFMT ) == 0; } SetBadFSStat195 void SetBad() { mode = 0; } 196 197 unicode_t* GetMTimeStr( unicode_t buf[64] ); 198 unicode_t* GetModeStr( unicode_t buf[64] ); 199 unicode_t* GetPrintableSizeStr( unicode_t buf[64] ); 200 ~FSStatFSStat201 ~FSStat() {}; 202 }; 203 204 #ifdef _WIN32 205 class W32NetRes 206 { 207 struct Node 208 { 209 int size; 210 NETRESOURCEW rs; 211 }; 212 unsigned char* data; Clear()213 void Clear() { if ( data ) { delete [] data; data = 0; } }; 214 static unsigned char* Copy( const unsigned char* ); 215 public: W32NetRes()216 W32NetRes(): data( 0 ) {} 217 void Set( NETRESOURCEW* p ); 218 W32NetRes(NETRESOURCEW * p)219 W32NetRes( NETRESOURCEW* p ): data( 0 ) {Set( p );} W32NetRes(const W32NetRes & a)220 W32NetRes( const W32NetRes& a ): data( Copy( a.data ) ) {} 221 W32NetRes& operator = ( const W32NetRes& a ) { Clear(); data = Copy( a.data ); return *this; } Get()222 NETRESOURCEW* Get() volatile { return ( data ) ? &( ( ( Node* )data )->rs ) : 0; } ~W32NetRes()223 ~W32NetRes() { if ( data ) { delete [] data; } } 224 }; 225 #endif 226 227 228 struct FSNode: public iIntrusiveCounter 229 { 230 enum EXTTYPES { SERVER = 1, WORKGROUP, FILESHARE }; 231 232 #ifdef _WIN32 233 W32NetRes _w32NetRes; 234 #endif 235 236 bool isSelected; 237 int extType; 238 FSStat st; 239 FSString name; 240 FSNode* next; 241 FSNode* originNode; 242 FSNodeFSNode243 FSNode(): isSelected( false ), extType( 0 ), next( 0 ), originNode( 0 ) {} FSNodeFSNode244 FSNode( const FSNode& a ): isSelected( a.isSelected ), extType( a.extType ), st( a.st ), next( 0 ), originNode( 0 ) { name.Copy( a.name ); } 245 FSNode& operator = ( const FSNode& a ) 246 { isSelected = a.isSelected; extType = a.extType; st = a.st; next = 0; name.Copy( a.name ); originNode = a.originNode; return *this;} 247 NameFSNode248 FSString& Name() { return name; } SizeFSNode249 int64_t Size() const { return st.size; } IsDirFSNode250 bool IsDir() const { return st.IsDir(); } IsLnkFSNode251 bool IsLnk() const { return st.IsLnk(); } IsRegFSNode252 bool IsReg() const { return st.IsReg(); } 253 #ifdef _WIN32 254 bool IsExe(); 255 #else IsExeFSNode256 bool IsExe() const { return st.IsExe(); } 257 #endif IsBadFSNode258 bool IsBad() const { return st.IsBad(); } 259 260 #ifdef _WIN32 261 /// should be hidden in panels IsHiddenFSNode262 bool IsHidden() const { return IsAttrHidden() || IsAttrSystem(); } IsAttrHiddenFSNode263 bool IsAttrHidden() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) != 0; } IsAttrSystemFSNode264 bool IsAttrSystem() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM ) != 0; } IsAttrReadOnlyFSNode265 bool IsAttrReadOnly() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) != 0; } IsAttrArchiveFSNode266 bool IsAttrArchive() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE ) != 0; } IsAttrCompressedFSNode267 bool IsAttrCompressed() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED ) != 0; } IsAttrEncryptedFSNode268 bool IsAttrEncrypted() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED ) != 0; } IsAttrNotIndexedFSNode269 bool IsAttrNotIndexed() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ) != 0; } IsAttrSparseFSNode270 bool IsAttrSparse() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE ) != 0; } IsAttrTemporaryFSNode271 bool IsAttrTemporary() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY ) != 0; } IsAttrOfflineFSNode272 bool IsAttrOffline() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE ) != 0; } IsAttrReparsePointFSNode273 bool IsAttrReparsePoint() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) != 0; } IsAttrVirtualFSNode274 bool IsAttrVirtual() const { return ( st.dwFileAttributes & FILE_ATTRIBUTE_VIRTUAL ) != 0; } 275 SetAttrFSNode276 void SetAttr( bool a, int Mask ) 277 { 278 if ( a ) 279 { 280 st.dwFileAttributes |= Mask; 281 } 282 else 283 { 284 st.dwFileAttributes &= ~Mask; 285 } 286 } 287 SetAttrReadOnlyFSNode288 void SetAttrReadOnly( bool a ) { SetAttr( a, FILE_ATTRIBUTE_READONLY ); } SetAttrArchiveFSNode289 void SetAttrArchive( bool a ) { SetAttr( a, FILE_ATTRIBUTE_ARCHIVE ); } SetAttrHiddenFSNode290 void SetAttrHidden( bool a ) { SetAttr( a, FILE_ATTRIBUTE_HIDDEN ); } SetAttrSystemFSNode291 void SetAttrSystem( bool a ) { SetAttr( a, FILE_ATTRIBUTE_SYSTEM ); } SetAttrNotIndexedFSNode292 void SetAttrNotIndexed( bool a ) { SetAttr( a, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ); } SetAttrTemporaryFSNode293 void SetAttrTemporary( bool a ) { SetAttr( a, FILE_ATTRIBUTE_TEMPORARY ); } 294 #else IsHiddenFSNode295 bool IsHidden() { return name.GetUnicode()[0] == '.'; } 296 SetAttrFSNode297 void SetAttr( bool a, int Mask ) 298 { 299 if ( a ) 300 { 301 st.mode |= Mask; 302 } 303 else 304 { 305 st.mode &= ~Mask; 306 } 307 } 308 IsAttrUserReadFSNode309 bool IsAttrUserRead() const { return ( st.mode & S_IRUSR ) != 0; } IsAttrUserWriteFSNode310 bool IsAttrUserWrite() const { return ( st.mode & S_IWUSR ) != 0; } IsAttrUserExecuteFSNode311 bool IsAttrUserExecute() const { return ( st.mode & S_IXUSR ) != 0; } IsAttrGroupReadFSNode312 bool IsAttrGroupRead() const { return ( st.mode & S_IRGRP ) != 0; } IsAttrGroupWriteFSNode313 bool IsAttrGroupWrite() const { return ( st.mode & S_IWGRP ) != 0; } IsAttrGroupExecuteFSNode314 bool IsAttrGroupExecute() const { return ( st.mode & S_IXGRP ) != 0; } IsAttrOthersReadFSNode315 bool IsAttrOthersRead() const { return ( st.mode & S_IROTH ) != 0; } IsAttrOthersWriteFSNode316 bool IsAttrOthersWrite() const { return ( st.mode & S_IWOTH ) != 0; } IsAttrOthersExecuteFSNode317 bool IsAttrOthersExecute() const { return ( st.mode & S_IXOTH ) != 0; } 318 SetAttrUserReadFSNode319 void SetAttrUserRead( bool a ) { SetAttr( a, S_IRUSR ); } SetAttrUserWriteFSNode320 void SetAttrUserWrite( bool a ) { SetAttr( a, S_IWUSR ); } SetAttrUserExecuteFSNode321 void SetAttrUserExecute( bool a ) { SetAttr( a, S_IXUSR ); } SetAttrGroupReadFSNode322 void SetAttrGroupRead( bool a ) { SetAttr( a, S_IRGRP ); } SetAttrGroupWriteFSNode323 void SetAttrGroupWrite( bool a ) { SetAttr( a, S_IWGRP ); } SetAttrGroupExecuteFSNode324 void SetAttrGroupExecute( bool a ) { SetAttr( a, S_IXGRP ); } SetAttrOthersReadFSNode325 void SetAttrOthersRead( bool a ) { SetAttr( a, S_IROTH ); } SetAttrOthersWriteFSNode326 void SetAttrOthersWrite( bool a ) { SetAttr( a, S_IWOTH ); } SetAttrOthersExecuteFSNode327 void SetAttrOthersExecute( bool a ) { SetAttr( a, S_IXOTH ); } 328 #endif GetLastWriteTimeFSNode329 FSTime GetLastWriteTime() const { return st.m_LastWriteTime; }; GetCreationTimeFSNode330 FSTime GetCreationTime() const { return st.m_CreationTime; }; GetLastAccessTimeFSNode331 FSTime GetLastAccessTime() const { return st.m_LastAccessTime; }; GetChangeTimeFSNode332 FSTime GetChangeTime() const { return st.m_ChangeTime; } 333 SetLastWriteTimeFSNode334 void SetLastWriteTime( FSTime t ) { st.m_LastWriteTime = t; }; SetCreationTimeFSNode335 void SetCreationTime( FSTime t ) { st.m_CreationTime = t; }; SetLastAccessTimeFSNode336 void SetLastAccessTime( FSTime t ) { st.m_LastAccessTime = t; }; SetChangeTimeFSNode337 void SetChangeTime( FSTime t ) { st.m_ChangeTime = t; } 338 IsSelectedFSNode339 bool IsSelected() const { return isSelected; } SetSelectedFSNode340 void SetSelected() { isSelected = true; } ClearSelectedFSNode341 void ClearSelected() { isSelected = false; } GetUnicodeNameFSNode342 const unicode_t* GetUnicodeName() const { return name.GetUnicode(); } GetUtf8NameFSNode343 const char* GetUtf8Name() const { return name.GetUtf8(); } 344 GetUIDFSNode345 int GetUID() const { return st.uid; } GetGIDFSNode346 int GetGID() const { return st.gid; } 347 CmpByNameFSNode348 int CmpByName( FSNode& a, bool case_sensitive ) { return case_sensitive ? name.Cmp( a.name ) : name.CmpNoCase( a.name ); } 349 int CmpByExt( FSNode& a, bool case_sensitive ); 350 351 ~FSNode(); 352 }; 353 354 enum BSearchMode 355 { 356 EXACT_MATCH_ONLY, 357 EXACT_OR_CLOSEST_PRECEDING_NODE, 358 EXACT_OR_CLOSEST_SUCCEEDING_NODE, 359 }; 360 361 enum SORT_MODE 362 { 363 SORT_NONE = 0, //unsorted 364 SORT_NAME, 365 SORT_EXT, 366 SORT_SIZE, 367 SORT_MTIME 368 }; 369 370 class FSList: public iIntrusiveCounter 371 { 372 FSNode* first, *last; 373 int count; 374 public: FSList()375 FSList(): first( 0 ), last( 0 ), count( 0 ) {}; Count()376 int Count() const { return count; }; 377 First()378 FSNode* First() { return first; } 379 380 void Append( clPtr<FSNode> ); 381 void Clear(); 382 383 std::vector<FSNode*> GetArray(); 384 385 std::vector<FSNode*> GetFilteredArray( bool showHidden, int* pCount ); 386 387 void CopyFrom( const FSList& a, bool onlySelected = false ); 388 void CopyOne( FSNode* node ); 389 ~FSList()390 ~FSList() { Clear(); } 391 392 CLASS_COPY_PROTECTION( FSList ); 393 }; 394 395 typedef int FSNodeCmpFunc(FSNode* n1, FSNode* n2); 396 class FSNodeVectorSorter 397 { 398 static FSNodeCmpFunc* getCmpFunc(bool isAscending, bool isCaseSensitive, SORT_MODE sortMode); 399 400 public: 401 static void Sort(std::vector<FSNode*>& nodeVector, bool isAscending, bool isCaseSensitive, SORT_MODE sortMode); 402 static int BSearch(FSNode& n, const std::vector<FSNode*>& nodeVector, BSearchMode searchMode, bool isAscending, bool isCaseSensitive, SORT_MODE sortMode); 403 }; 404 405 struct FSSmbParam 406 { 407 408 volatile char server[0x100]; //all utf8 409 volatile char domain[0x100]; 410 volatile char user[0x100]; 411 volatile char pass[0x100]; 412 volatile bool isSet; 413 FSSmbParamFSSmbParam414 FSSmbParam(): isSet( 0 ) { server[0] = domain[0] = user[0] = pass[0] = 0; } 415 SetServerFSSmbParam416 void SetServer( const char* s ) 417 { 418 volatile char* p = server; 419 int n = sizeof( server ) - 1; 420 421 for ( ; *s && n > 0; s++, p++, n-- ) 422 { 423 *p = *s; 424 } 425 426 *p = 0; 427 } 428 GetConfFSSmbParam429 void GetConf( StrConfig& conf ) 430 { 431 conf.Set( "SERVER", const_cast<char*>( server ) ); 432 conf.Set( "DOMAIN", const_cast<char*>( domain ) ); 433 conf.Set( "USER", const_cast<char*>( user ) ); 434 } 435 _copyFSSmbParam436 static void _copy( char* dest, const char* src, int destSize ) 437 { 438 int n = destSize; 439 440 for ( ; *src && n > 1; src++, dest++, n-- ) { *dest = *src; } 441 442 *dest = 0; 443 } 444 445 SetConfFSSmbParam446 void SetConf( StrConfig& conf ) 447 { 448 const char* s = conf.GetStrVal( "SERVER" ); 449 450 if ( s ) { _copy( const_cast<char*>( server ), s, sizeof( server ) ); } 451 452 s = conf.GetStrVal( "DOMAIN" ); 453 454 if ( s ) { _copy( const_cast<char*>( domain ), s, sizeof( domain ) ); } 455 456 s = conf.GetStrVal( "USER" ); 457 458 if ( s ) { _copy( const_cast<char*>( user ), s, sizeof( user ) ); } 459 } 460 }; 461 462 struct FSFtpParam 463 { 464 std::string server; 465 volatile int port; 466 volatile int charset; 467 volatile bool anonymous; 468 std::string user; 469 std::string pass; 470 volatile bool passive; 471 volatile bool isSet; 472 FSFtpParamFSFtpParam473 FSFtpParam(): port( 21 ), 474 #ifdef _WIN32 475 charset( CS_UTF8 ), 476 #else 477 charset( sys_charset_id ), 478 #endif 479 anonymous( true ), 480 passive( true ), 481 isSet( false ) 482 {} 483 GetConfFSFtpParam484 void GetConf( StrConfig& conf ) 485 { 486 conf.Set( "SERVER", server.c_str() ); 487 conf.Set( "USER", user.c_str() ); 488 conf.Set( "PASSWORD", g_WcmConfig.systemStorePasswords ? pass.c_str() : "" ); 489 conf.Set( "PORT", port ); 490 conf.Set( "ANONYMOUS", anonymous ? 1 : 0 ); 491 conf.Set( "PASSIVE", passive ? 1 : 0 ); 492 493 conf.Set( "CHARSET", charset_table.NameById( charset ) ); 494 } 495 SetConfFSFtpParam496 void SetConf( StrConfig& conf ) 497 { 498 const char* s = conf.GetStrVal( "SERVER" ); 499 500 if ( s ) { server = s; } 501 502 s = conf.GetStrVal( "USER" ); 503 504 if ( s ) { user = s; } 505 506 s = conf.GetStrVal( "PASSWORD" ); 507 508 if ( s ) { pass = s; } 509 510 int n = conf.GetIntVal( "PORT" ); 511 512 if ( n > 0 ) { port = n; } 513 514 n = conf.GetIntVal( "ANONYMOUS" ); 515 anonymous = n == 0 ? false : true; 516 517 n = conf.GetIntVal( "PASSIVE" ); 518 passive = n == 0 ? false : true; 519 520 charset = charset_table.IdByName( conf.GetStrVal( "CHARSET" ) ); 521 522 isSet = anonymous; 523 } 524 525 inline bool operator == ( const FSFtpParam& Other ) const 526 { 527 return 528 ( this->server == Other.server ) && 529 ( this->anonymous == Other.anonymous && ( this->anonymous || (this->user == Other.user) ) ) && 530 ( this->port == Other.port ); 531 } 532 }; 533 534 535 struct FSSftpParam 536 { 537 std::string server; 538 volatile int port; 539 volatile int charset; 540 std::string user; 541 volatile bool isSet; FSSftpParamFSSftpParam542 FSSftpParam(): port( 22 ), 543 #ifdef _WIN32 544 charset( CS_UTF8 ), 545 #else 546 charset( sys_charset_id ), 547 #endif 548 isSet( false ) {} 549 GetConfFSSftpParam550 void GetConf( StrConfig& conf ) 551 { 552 conf.Set( "SERVER", server.c_str() ); 553 conf.Set( "USER", user.c_str() ); 554 // conf.Set( "PASSWORD", g_WcmConfig.systemStorePasswords ? pass.c_str() : "" ); 555 conf.Set( "PORT", port ); 556 conf.Set( "CHARSET", charset_table.NameById( charset ) ); 557 } 558 SetConfFSSftpParam559 void SetConf( StrConfig& conf ) 560 { 561 const char* s = conf.GetStrVal( "SERVER" ); 562 563 if ( s ) { server = s; } 564 565 s = conf.GetStrVal( "USER" ); 566 567 if ( s ) { user = s; } 568 569 // s = conf.GetStrVal( "PASSWORD" ); 570 571 // if ( s ) { pass = s; } 572 573 int n = conf.GetIntVal( "PORT" ); 574 575 if ( n > 0 ) { port = n; } 576 577 charset = charset_table.IdByName( conf.GetStrVal( "CHARSET" ) ); 578 } 579 580 inline bool operator == ( const FSSftpParam& Other ) const 581 { 582 return 583 this->server == Other.server && 584 this->user == Other.user && 585 this->port == Other.port; 586 } 587 }; 588 589 struct FSPromptData 590 { 591 volatile bool visible; 592 std::string prompt; 593 }; 594 595 class FSCInfo 596 { 597 public: FSCInfo()598 FSCInfo() {} 599 virtual ~FSCInfo(); 600 virtual bool IsStopped() const; 601 virtual bool SmbLogon( FSSmbParam* a ); 602 virtual bool FtpLogon( FSFtpParam* a ); 603 virtual bool Prompt( const unicode_t* header, const unicode_t* message, FSPromptData* p, int count ); 604 }; 605 606 class FSCSimpleInfo: public FSCInfo 607 { 608 public: 609 std::atomic<bool> m_Stopped; FSCSimpleInfo()610 FSCSimpleInfo() 611 : m_Stopped( false ) 612 {} 613 virtual ~FSCSimpleInfo(); Reset()614 void Reset() { m_Stopped = false; } SetStop()615 void SetStop() { m_Stopped = true; } 616 virtual bool IsStopped() const override; 617 }; 618 619 620 /* 621 все фанкции, возвращающие int возвращают 0 при успехе -1 при ошибке и -2 при StopEvent 622 одна FS (один и тот же объект) может в один период времени мспользоваться только одним потоком 623 624 id файла - int 625 */ 626 627 628 class FS: public iIntrusiveCounter 629 { 630 public: 631 enum TYPES { SYSTEM = 0, SFTP = 1, SAMBA = 2, FTP = 3, WIN32NET = 4, TMP = 5 }; 632 enum FLAGS { HAVE_READ = 1, HAVE_WRITE = 2, HAVE_SYMLINK = 4, HAVE_SEEK = 8 }; 633 enum OPENFLAGS { SHARE_READ = 1, SHARE_WRITE = 2 }; 634 private: 635 int _type; 636 public: FS(int t)637 FS( int t ): _type( t ) { } Type()638 int Type() const { return _type; } IsPersistent()639 virtual bool IsPersistent() { return true; } // persistent FS location can be saved on app exit and restored on next startup 640 SetError(int * p,int err)641 static int SetError(int* p, int err) { if (p) { *p = err; }; return err; } 642 643 virtual unsigned Flags() = 0; 644 virtual bool IsEEXIST( int err ) = 0; 645 virtual bool IsENOENT( int err ) = 0; 646 virtual bool IsEXDEV( int err ) = 0; IsNORENAME(int err)647 bool IsNORENAME( int err ) { return IsEXDEV( err ); }; 648 virtual FSString StrError( int err ) = 0; //строка ощибки с указанным идентификатором 649 virtual bool Equal( FS* fs ) = 0; //должна отрабатывать null (как false) 650 651 virtual int OpenRead ( FSPath& path, int flags, int* err, FSCInfo* info ); 652 virtual int OpenCreate ( FSPath& path, bool overwrite, int mode, int flags, int* err, FSCInfo* info ); 653 virtual int Close ( int fd, int* err, FSCInfo* info ); 654 virtual int Read ( int fd, void* buf, int size, int* err, FSCInfo* info ); 655 virtual int Write ( int fd, void* buf, int size, int* err, FSCInfo* info ); 656 virtual int Seek ( int fd, SEEK_FILE_MODE mode, seek_t pos, seek_t* pRet, int* err, FSCInfo* info ); 657 virtual int Rename ( FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info ); 658 virtual int MkDir ( FSPath& path, int mode, int* err, FSCInfo* info ); 659 virtual int Delete ( FSPath& path, int* err, FSCInfo* info ); 660 virtual int RmDir ( FSPath& path, int* err, FSCInfo* info ); 661 virtual int SetFileTime ( FSPath& path, FSTime cTime, FSTime aTime, FSTime mTime, int* err, FSCInfo* info ); 662 virtual int ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info ); 663 virtual int Stat( FSPath& path, FSStat* st, int* err, FSCInfo* info ); 664 /// apply attributes to a file 665 virtual int StatSetAttr( FSPath& path, const FSStat* st, int* err, FSCInfo* info ); 666 virtual int FStat( int fd, FSStat* st, int* err, FSCInfo* info ); 667 virtual int Symlink ( FSPath& path, FSString& str, int* err, FSCInfo* info ); 668 virtual int StatVfs( FSPath& path, FSStatVfs* st, int* err, FSCInfo* info ); 669 virtual int64_t GetFileSystemFreeSpace( FSPath& path, int* err ); 670 671 virtual FSString Uri( FSPath& path ) = 0; 672 673 virtual unicode_t* GetUserName( int user, unicode_t buf[64] ); 674 virtual unicode_t* GetGroupName( int group, unicode_t buf[64] ); 675 676 virtual ~FS(); 677 CLASS_COPY_PROTECTION( FS ); 678 }; 679 680 #ifdef _WIN32 681 class FSSysHandles 682 { 683 Mutex mutex; 684 enum { SIZE = 32 }; 685 struct Node 686 { 687 volatile bool busy; 688 volatile HANDLE handle; 689 }; 690 Node table[SIZE]; 691 public: FSSysHandles()692 FSSysHandles() { for ( int i = 0; i < SIZE; i++ ) { table[i].busy = false; } } New()693 int New() 694 { 695 MutexLock lock( &mutex ); 696 697 for ( int i = 0; i < SIZE; i++ ) 698 if ( !table[i].busy ) { table[i].handle = INVALID_HANDLE_VALUE; table[i].busy = true; return i; } 699 700 return -1; 701 }; Handle(int n)702 HANDLE* Handle( int n ) 703 { 704 MutexLock lock( &mutex ); 705 706 if ( n >= 0 && n < SIZE && table[n].busy ) 707 { 708 return const_cast<HANDLE*>( &( table[n].handle ) ); 709 } 710 711 return 0; 712 } Free(int n)713 void Free( int n ) 714 { 715 MutexLock lock( &mutex ); 716 717 if ( n >= 0 && n < SIZE && table[n].busy ) 718 { 719 table[n].busy = false; 720 table[n].handle = INVALID_HANDLE_VALUE; 721 } 722 } 723 }; 724 #endif 725 726 727 class FSSys: public FS 728 { 729 #ifdef _WIN32 730 volatile int _drive; 731 FSSysHandles handles; 732 public: FSSys()733 FSSys() 734 : _drive(-1) 735 , FS( FS::SYSTEM ) 736 {} 737 #endif // _WIN32 738 public: 739 #ifdef _WIN32 740 //0-'A'...'Z', -1 - network FSSys(int drive)741 explicit FSSys( int drive ): FS( FS::SYSTEM ), _drive( drive ) {} Drive()742 int Drive() const { return _drive; } 743 #else 744 FSSys(): FS( FS::SYSTEM ) {} 745 #endif 746 virtual unsigned Flags(); 747 virtual bool IsEEXIST( int err ); 748 virtual bool IsENOENT( int err ); 749 virtual bool IsEXDEV( int err ); 750 virtual FSString StrError( int err ); 751 virtual bool Equal( FS* fs ); 752 753 virtual int OpenRead ( FSPath& path, int flags, int* err, FSCInfo* info ); 754 virtual int OpenCreate ( FSPath& path, bool overwrite, int mode, int flags, int* err, FSCInfo* info ); 755 virtual int Close ( int fd, int* err, FSCInfo* info ); 756 virtual int Read ( int fd, void* buf, int size, int* err, FSCInfo* info ); 757 virtual int Write ( int fd, void* buf, int size, int* err, FSCInfo* info ); 758 virtual int Seek ( int fd, SEEK_FILE_MODE mode, seek_t pos, seek_t* pRet, int* err, FSCInfo* info ); 759 virtual int Rename ( FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info ); 760 virtual int MkDir ( FSPath& path, int mode, int* err, FSCInfo* info ); 761 virtual int Delete ( FSPath& path, int* err, FSCInfo* info ); 762 virtual int RmDir ( FSPath& path, int* err, FSCInfo* info ); 763 virtual int SetFileTime ( FSPath& path, FSTime cTime, FSTime aTime, FSTime mTime, int* err, FSCInfo* info ) override; 764 virtual int ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info ); 765 virtual int Stat ( FSPath& path, FSStat* st, int* err, FSCInfo* info ); 766 virtual int StatSetAttr( FSPath& path, const FSStat* st, int* err, FSCInfo* info ); 767 virtual int FStat( int fd, FSStat* st, int* err, FSCInfo* info ); 768 virtual int Symlink ( FSPath& path, FSString& str, int* err, FSCInfo* info ); 769 virtual int StatVfs( FSPath& path, FSStatVfs* st, int* err, FSCInfo* info ); 770 virtual FSString Uri( FSPath& path ); 771 virtual int64_t GetFileSystemFreeSpace( FSPath& path, int* err ); 772 773 virtual unicode_t* GetUserName( int user, unicode_t buf[64] ); 774 virtual unicode_t* GetGroupName( int group, unicode_t buf[64] ); 775 776 virtual ~FSSys(); 777 }; 778 779 780 781 #ifdef _WIN32 782 783 class FSWin32Net: public FS 784 { 785 volatile W32NetRes _res; 786 public: 787 enum { ERRNOSUPPORT = -1000 }; FSWin32Net(NETRESOURCEW * p)788 FSWin32Net( NETRESOURCEW* p ): FS( FS::WIN32NET ), _res( p ) {}; 789 virtual unsigned Flags() override; 790 virtual bool IsEEXIST( int err ) override; 791 virtual bool IsENOENT( int err ) override; 792 virtual bool IsEXDEV( int err ) override; 793 virtual FSString StrError( int err ) override; 794 virtual bool Equal( FS* fs ) override; 795 virtual int OpenRead ( FSPath& path, int flags, int* err, FSCInfo* info ) override; 796 virtual int OpenCreate ( FSPath& path, bool overwrite, int mode, int flags, int* err, FSCInfo* info ) override; 797 virtual int Close ( int fd, int* err, FSCInfo* info ) override; 798 virtual int Read ( int fd, void* buf, int size, int* err, FSCInfo* info ) override; 799 virtual int Write ( int fd, void* buf, int size, int* err, FSCInfo* info ) override; 800 virtual int Seek ( int fd, SEEK_FILE_MODE mode, seek_t pos, seek_t* pRet, int* err, FSCInfo* info ) override; 801 virtual int Rename ( FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info ) override; 802 virtual int MkDir ( FSPath& path, int mode, int* err, FSCInfo* info ) override; 803 virtual int Delete ( FSPath& path, int* err, FSCInfo* info ) override; 804 virtual int RmDir ( FSPath& path, int* err, FSCInfo* info ) override; 805 virtual int SetFileTime ( FSPath& path, FSTime cTIme, FSTime aTime, FSTime mTime, int* err, FSCInfo* info ) override; 806 virtual int ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info ) override; 807 virtual int Stat ( FSPath& path, FSStat* st, int* err, FSCInfo* info ) override; 808 virtual int Symlink ( FSPath& path, FSString& str, int* err, FSCInfo* info ) override; 809 virtual FSString Uri( FSPath& path ) override; 810 virtual ~FSWin32Net(); 811 }; 812 813 #endif 814 815 816 //path - должен быть абсолютным (если нет - то вернет false) 817 extern bool ParzeLink( FSPath& path, FSString& link ); 818 819 /// HH:MM:SS 820 std::string GetFSTimeStrTime( FSTime TimeValue ); 821 /// DD:MM:YYYY 822 std::string GetFSTimeStrDate( FSTime TimeValue ); 823 /// DD:MM:YYYY, HH:MM:SS 824 FSTime GetFSTimeFromStr( const std::string& Date, const std::string& Time ); 825 826