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 ); }
void OperRDThread::Run() { int n = 8; int ret_err; while (true) { if (!(fs->Flags() & FS::HAVE_SYMLINK)) break; FSStat st; if (fs->Stat(path, &st, &ret_err, Info())) throw_msg("%s", fs->StrError(ret_err).GetUtf8()); if (!st.IsLnk()) break; n--; if (n<0) throw_msg("too more symbolic links '%s'", path.GetUtf8()); path.Pop(); if (!ParzeLink(path, st.link)) throw_msg("invalid symbolic link '%s'", path.GetUtf8()); } cptr<FSList> list = new FSList; int ret = fs->ReadDir(list.ptr(), path, &ret_err, Info()); if (ret) throw_msg("%s", fs->StrError(ret_err).GetUtf8()); MutexLock lock(Node().GetMutex()); //!!! if (Node().NBStopped()) return; OperRDData *data = ((OperRDData*)Node().Data()); data->list = list; data->path = path; data->executed = true; }
void OperRDThread::Run() { if ( !fs.Ptr() ) { return; } int n = 8; int ret_err; int havePostponedStatError = 0; FSString postponedStrError; while ( true ) { if ( !( fs->Flags() & FS::HAVE_SYMLINK ) ) { break; } FSStat st; // if path is inaccessible, try .. path. Throw the exception later // This makes panel at least having some valid folder while ( fs->Stat( path, &st, &ret_err, Info() ) ) { havePostponedStatError = 1; postponedStrError = fs->StrError( ret_err ); if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() ) { throw_msg( "%s", postponedStrError.GetUtf8() ); } } // yell immediately if the path is inaccessible (orig behavior) //if (fs->Stat(path, &st, &ret_err, Info())) // throw_msg("%s", fs->StrError(ret_err).GetUtf8()); if ( !st.IsLnk() ) { break; } n--; if ( n < 0 ) { throw_msg( "too many symbolic links '%s'", path.GetUtf8() ); } path.Pop(); if ( !ParzeLink( path, st.link ) ) { throw_msg( "invalid symbolic link '%s'", path.GetUtf8() ); } } clPtr<FSList> list = new FSList; int havePostponedReadError = 0; // if directory is not readable, try .. path. Throw the exception later // "Stat" call above does not catch this: it checks only folder existence, but not accessibilly while ( fs->ReadDir( list.ptr(), path, &ret_err, Info() ) ) { havePostponedReadError = 1; postponedStrError = fs->StrError( ret_err ); if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() ) { throw_msg( "%s", postponedStrError.GetUtf8() ); } } // yell immediately if the dir is unreadable (orig behavior) //int ret = fs->ReadDir(list.ptr(), path, &ret_err, Info()); //if (ret) // throw_msg("%s", fs->StrError(ret_err).GetUtf8()); FSStatVfs vst; fs->StatVfs( path, &vst, &ret_err, Info() ); MutexLock lock( Node().GetMutex() ); //!!! if ( Node().NBStopped() ) { return; } OperRDData* data = ( ( OperRDData* )Node().Data() ); data->list = list; data->path = path; data->executed = true; data->vst = vst; if ( havePostponedReadError || havePostponedStatError ) { data->nonFatalErrorString = postponedStrError; } }
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 }