clPtr<FS> ParzeFtpURI( const unicode_t* uri, FSPath& path, clPtr<FS>* checkFS, int count ) { path.Set( rootPathStr ); if ( !uri[0] ) { return clPtr<FS>(); } FSFtpParam param; const unicode_t* userDelimiter = FindFirstChar( uri, '@' ); if ( *userDelimiter ) { param.user = FSString( CS_UNICODE, uri, userDelimiter - uri ).GetUnicode(); uri = userDelimiter + 1; param.anonymous = false; } else { param.anonymous = true; } const unicode_t* host_port_End = FindFirstChar( uri, '/' ); const unicode_t* host_End = FindFirstChar( uri, ':' ); FSString host( CS_UNICODE, uri, ( ( host_End < host_port_End ) ? host_End : host_port_End ) - uri ); int port = 0; for ( const unicode_t* s = host_End + 1; s < host_port_End; s++ ) if ( *s >= '0' && *s <= '9' ) { port = port * 10 + ( *s - '0' ); } else { break; } if ( port > 0 && port < 65536 ) { param.port = port; } param.server = host.GetUnicode(); uri = host_port_End; FSString link = uri; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } for ( int i = 0; i < count; i++ ) if ( checkFS[i].Ptr() && checkFS[i]->Type() == FS::FTP ) { FSFtp* p = ( FSFtp* )checkFS[i].Ptr(); FSFtpParam checkParam; p->GetParam( &checkParam ); if ( !CmpStr<const unicode_t>( param.server.Data(), checkParam.server.Data() ) && ( param.anonymous == checkParam.anonymous && ( param.anonymous || !CmpStr<const unicode_t>( param.user.Data(), checkParam.user.Data() ) ) ) && param.port == checkParam.port ) { return checkFS[i]; } } return new FSFtp( ¶m ); }
clPtr<FS> ParzeSmbURI( const unicode_t* uri, FSPath& path, clPtr<FS>* checkFS, int count ) { path.Set( rootPathStr ); if ( !uri[0] ) { return new FSSmb(); } FSSmbParam param; const unicode_t* userDelimiter = FindFirstChar( uri, '@' ); if ( *userDelimiter ) { FSString s( CS_UNICODE, uri, userDelimiter - uri ); SetString( const_cast<char*>( param.user ), sizeof( param.user ), s.GetUtf8() ); uri = userDelimiter + 1; } const unicode_t* hostEnd = FindFirstChar( uri, '/' ); FSString host( CS_UNICODE, uri, hostEnd - uri ); SetString( const_cast<char*>( param.server ), sizeof( param.server ), host.GetUtf8() ); uri = hostEnd; FSString link = uri; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } return new FSSmb( ¶m ); }
clPtr<FS> clArchPlugin::OpenFS( clPtr<FS> Fs, FSPath& Path ) const { FSString Uri = Fs->Uri( Path ); struct archive* Arch = ArchOpen( Uri.GetUtf8() ); if ( Arch == nullptr ) { return nullptr; } FSArchNode RootDir; RootDir.fsStat.mode = S_IFDIR; FSPath NodePath; struct archive_entry* entry = archive_entry_new2( Arch ); int Res; while ( ( Res = archive_read_next_header2( Arch, entry ) ) == ARCHIVE_OK ) { NodePath.Set( CS_UTF8, archive_entry_pathname( entry ) ); FSString* ItemName = NodePath.GetItem( NodePath.Count() - 1 ); if ( NodePath.Count() == 1 && ( ItemName->IsDot() || ItemName->IsEmpty() ) ) { // skip root dir continue; } const mode_t Mode = archive_entry_mode( entry ); const int64_t Size = archive_entry_size( entry ); RootDir.entryOffset += Size; FSStat ItemStat; ItemStat.mode = S_ISREG( Mode ) ? Mode : S_IFDIR; ItemStat.size = Size; ItemStat.m_CreationTime = archive_entry_ctime( entry ); ItemStat.m_LastAccessTime = archive_entry_atime( entry ); ItemStat.m_LastWriteTime = archive_entry_mtime( entry ); ItemStat.m_ChangeTime = ItemStat.m_LastWriteTime; FSArchNode* Dir = ArchGetParentDir( &RootDir, NodePath, ItemStat ); FSArchNode* Item = Dir->Add( FSArchNode( ItemName->GetUtf8(), ItemStat ) ); if (Item) { Item->entryOffset = archive_read_header_position( Arch ); } } if ( Res != ARCHIVE_EOF ) { dbg_printf( "Couldn't read archive entry: %s\n", archive_error_string( Arch ) ); } archive_entry_free( entry ); ArchClose( Arch ); return new FSArch( RootDir, Uri ); }
clPtr<FS> ParzeCurrentSystemURL( FSPath& path ) { #ifdef _WIN32 int drive = 3; //c: char buf[0x100]; UINT l = GetSystemDirectory( buf, sizeof( buf ) ); if ( l > 0 ) { int c = buf[0]; drive = ( c >= 'A' && c <= 'Z' ) ? c - 'A' : ( ( c >= 'a' && c <= 'z' ) ? c - 'a' : 3 ); } path.Set( CS_UTF8, "/" ); return new FSSys( drive ); #else int bufSize = 1024; std::vector<sys_char_t> buf( bufSize ); while ( true ) { if ( getcwd( buf.data(), bufSize ) ) { break; } if ( errno != ERANGE ) { throw_syserr( 0, "Botva" ); } bufSize *= 2; buf.resize( bufSize ); } path.Set( sys_charset_id, buf.data() ); return new FSSys(); //systemclPtr<FS>; #endif }
clPtr<FS> ParzeURI( const unicode_t* uri, FSPath& path, clPtr<FS>* checkFS, int count ) { #ifdef LIBSMBCLIENT_EXIST if ( uri[0] == 's' && uri[1] == 'm' && uri[2] == 'b' && uri[3] == ':' && uri[4] == '/' && uri[5] == '/' ) { return ParzeSmbURI( uri + 6, path, checkFS, count ); } #endif if ( uri[0] == 'f' && uri[1] == 't' && uri[2] == 'p' && uri[3] == ':' && uri[4] == '/' && uri[5] == '/' ) { return ParzeFtpURI( uri + 6, path, checkFS, count ); } #if defined(LIBSSH_EXIST) || defined(LIBSSH2_EXIST) if ( uri[0] == 's' && uri[1] == 'f' && uri[2] == 't' && uri[3] == 'p' && uri[4] == ':' && uri[5] == '/' && uri[6] == '/' ) { return ParzeSftpURI( uri + 7, path, checkFS, count ); } #endif if ( uri[0] == 'f' && uri[1] == 'i' && uri[2] == 'l' && uri[3] == 'e' && uri[4] == ':' && uri[5] == '/' && uri[6] == '/' ) { uri += 6; //оставляем 1 символ '/' } #ifdef _WIN32 int c = uri[0]; if ( c == '\\' || c == '/' ) { if ( uri[1] == '/' || uri[1] == '\\' ) { FSString link = uri + 1; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } if ( path.Count() == 1 ) { clPtr<FS> netFs = new FSWin32Net( 0 ); path.Set( CS_UTF8, "/" ); return netFs; } if ( path.Count() == 2 ) { static unicode_t aa[] = {'\\', '\\', 0}; std::vector<wchar_t> name = UnicodeToUtf16( carray_cat<unicode_t>( aa, path.GetItem( 1 )->GetUnicode() ).data() ); NETRESOURCEW r; r.dwScope = RESOURCE_GLOBALNET; r.dwType = RESOURCETYPE_ANY; r.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC; r.dwUsage = RESOURCEUSAGE_CONTAINER; r.lpLocalName = 0; r.lpRemoteName = name.data(); r.lpComment = 0; r.lpProvider = 0; clPtr<FS> netFs = new FSWin32Net( &r ); path.Set( CS_UTF8, "/" ); return netFs; } return new FSSys( -1 ); } FSString link = uri; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>(); } if ( c >= 'A' && c <= 'Z' ) { c = c - 'A' + 'a'; } if ( c < 'a' || c > 'z' || uri[1] != ':' || ( uri[2] != '/' && uri[2] != '\\' ) ) { FSString link = uri; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>(); } FSString link = uri + 2; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } return new FSSys( c - 'a' ); #else FSString link = uri; if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); } if ( uri[0] != '/' ) { return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>(); } return new FSSys(); //systemclPtr<FS>; #endif }
bool PathListFSToData(PathList::Data& data, clPtr<FS>* fs, FSPath* path) { clPtr<StrConfig> cfg = new StrConfig(); clPtr<FS> TempFs; FSPath TempPath; if ( fs->ptr()->Type() == FS::TMP ) { // if we are on Temp panel then use base FS TempFs = ((FSTmp*) fs->ptr())->GetBaseFS(); fs = &TempFs; // path on Temp panel may starts with additional '\' or '/' const char* PathOnTemp = path->GetUtf8(); if ( PathOnTemp && ( PathOnTemp[0] == '\\' || PathOnTemp[0] == '/' ) ) { TempPath.Set( CS_UTF8, ++PathOnTemp ); path = &TempPath; } } if (fs[0]->Type() == FS::SYSTEM) { cfg->Set("TYPE", "SYSTEM"); cfg->Set("Path", path->GetUtf8()); #ifdef _WIN32 const int disk = ((FSSys*)fs[0].Ptr())->Drive(); if (disk >= 0) { cfg->Set("Disk", disk); } #endif } else if (fs[0]->Type() == FS::FTP) { cfg->Set("TYPE", "FTP"); cfg->Set("Path", path->GetUtf8()); FSFtpParam param = ((FSFtp*)fs[0].Ptr())->GetParamValue(); param.GetConf(*cfg.ptr()); } else #if defined(LIBSSH_EXIST) || defined(LIBSSH2_EXIST) if (fs[0]->Type() == FS::SFTP) { cfg->Set("TYPE", "SFTP"); cfg->Set("Path", path->GetUtf8()); FSSftpParam param = ((FSSftp*)fs[0].Ptr())->GetParamValue(); param.GetConf(*cfg.ptr()); } else #endif #ifdef LIBSMBCLIENT_EXIST if (fs[0]->Type() == FS::SAMBA) { cfg->Set("TYPE", "SMB"); cfg->Set("Path", path->GetUtf8()); FSSmbParam param = ((FSSmb*)fs[0].Ptr())->GetParamValue(); param.GetConf(*cfg.ptr()); } else #endif return false; data.name = utf8_to_unicode(fs[0]->Uri(*path).GetUtf8()); data.conf = cfg; return true; }