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 ); }
bool OperCFThread::Copy(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath, cstrhash<bool,unicode_t> &resList) { if (list->Count()<=0) return true; FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); FSStat st; int ret_error; int res = destFs->Stat(__destPath, &st, &ret_error, Info()); if (res == -2) return false; if (res && !destFs->IsENOENT(ret_error)) { RedMessage( _LT("Can't copy to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } bool exist = (res == 0); if (list->Count()>1) { //если файлов >1 то копировать можно только в каталог if (!exist) { RedMessage( _LT("Can't copy files, destination is not found:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } if (!st.IsDir()) { RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } for (FSNode *node = list->First(); node; node = node->next) { if (Info()->Stopped()) return false; srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); if (!CopyNode(srcFs, srcPath, node, destFs, destPath, false)) return false; resList[node->Name().GetUnicode()] = true; } } else { // 1 element if (exist && st.IsDir()) destPath.SetItemStr(destPos, list->First()->Name()); srcPath.SetItemStr(srcPos, list->First()->Name()); if (!CopyNode(srcFs, srcPath, list->First(), destFs, destPath, false)) return false; resList[list->First()->Name().GetUnicode()] = true; }; return true; }
bool OperCFThread::Move(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath) { if (list->Count()<=0) return true; FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); FSStat st; int ret_error; int r = destFs->Stat(__destPath, &st, &ret_error, Info()); if (r == -2) return false; if (list->Count()>1) { //если файлов >1 то копировать можно только в каталог if (r) { RedMessage( _LT("Can't move files, bad destination directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!st.IsDir()) { RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } for (FSNode *node = list->First(); node; node = node->next) { srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); //printf("MOVE '%s'\n", srcPath.GetUtf8()); if (!MoveNode(srcFs, srcPath, node, destFs, destPath)) return false; } } else { // 1 element if (r && !destFs->IsENOENT(ret_error)) { RedMessage( _LT("Can't move to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!r && st.IsDir()) destPath.SetItemStr(destPos, list->First()->Name()); FSNode *node = list->First(); srcPath.SetItemStr(srcPos, list->First()->Name()); if (!MoveNode(srcFs, srcPath, list->First(), destFs, destPath)) return false; } return true; }
int FSTmp::MkDir(FSPath& path, int mode, int* err, FSCInfo* info) { FSPath parentPath; parentPath.Copy(path, path.Count() - 1); FSTmpNode* parent = rootDir.findByFsPath(&parentPath); if (!parent) return SetError(err, FSTMP_ERROR_FILE_NOT_FOUND); FSTmpNode* parentDir = parent; FSTmpNode fsTmpNode(path.GetItem(path.Count() - 1)->GetUnicode(), parentDir); parentDir->Add(&fsTmpNode); return SetError(err, 0); }
static void stripPathFromLastItem(FSPath& path) { FSString* lastItem = path.GetItem(path.Count() - 1); if (lastItem) { const unicode_t* lastU = lastItem->GetUnicode(); const unicode_t* lastDelim = unicode_strrchr(lastU, DIR_SPLITTER); if (lastDelim != 0) { path.SetItemStr(path.Count() - 1,FSString(lastDelim + 1)); } } }
int FSSys::Stat( FSPath& path, FSStat* fsStat, int* err, FSCInfo* info ) { if ( _drive >= 0 && path.Count() == 1 || _drive == -1 && path.Count() == 3 ) { //pseudo stat fsStat->size = 0; fsStat->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; fsStat->mode = S_IFDIR; fsStat->mtime = 0; fsStat->mode |= 0664; return 0; } WIN32_FIND_DATAW ent; HANDLE handle = FindFirstFileW( SysPathStr( _drive, path.GetUnicode() ).data(), &ent ); if ( handle == INVALID_HANDLE_VALUE ) { SetError( err, GetLastError() ); return -1; } try { fsStat->size = ( seek_t( ent.nFileSizeHigh ) << 32 ) + ent.nFileSizeLow; fsStat->dwFileAttributes = ent.dwFileAttributes; fsStat->mtime = ent.ftLastWriteTime; if ( ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { fsStat->mode = S_IFDIR; } else { fsStat->mode = S_IFREG; } fsStat->mode |= 0664; FindClose( handle ); return 0; } catch ( ... ) { FindClose( handle ); throw; } //... SetError( err, 50 ); return -1; }
void FSPath::Copy(const FSPath& a, int elementCount) { cacheCs = -2; data.clear(); if (elementCount<0 || elementCount>a.Count()) elementCount = a.Count(); for (int i = 0; i < elementCount; i++) { FSString s; s.Copy(a.data.const_item(i)); data.append(s); } }
bool DeleteListRecursively( FS* fs, FSPath path, FSList& list ) { const int cnt = path.Count(); int ret_err; for ( FSNode* node = list.First(); node; node = node->next ) { if ( node->extType ) { continue; } path.SetItemStr( cnt, node->Name() ); if ( node->IsDir() && !node->st.IsLnk() ) { if ( !DeleteDirRecursively( fs, path ) ) { return false; } } else if ( fs->Delete( path, &ret_err, nullptr ) != 0 ) { return false; } } return true; }
int FSTmp::Delete(FSPath& path, int* err, FSCInfo* info) { FSString* dName = path.GetItem(path.Count() - 1); FSTmpNode* n = rootDir.findByName(dName); if (n == 0) { return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);; } else { /* if (n->nodeType == FSTmpNode::NODE_FILE) { // remove file at base FS int ret = baseFS->Delete(n->baseFSPath, err, info); if (ret != 0) return ret; } */ // remove from tmpfs list for (auto it = n->parentDir->content.begin(); it != n->parentDir->content.end(); ++it) { if ((*it).name.Cmp(*dName) == 0) { n->parentDir->content.erase(it); return FS::SetError(err, 0); } } return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);; } }
void OperCFThread::CreateDirectory( FS* fs, FSPath& srcPath, FSPath& destPath, bool processMultipleFolders ) { if ( processMultipleFolders ) { const int DirIndex = srcPath.GetFirstUnmatchedItem( destPath ); FSPath Path; for ( int i = 0; i < destPath.Count(); i++ ) { // get next dir Path.PushStr( *destPath.GetItem( i ) ); int ret_err; // try to create dir if ( i >= DirIndex && fs->MkDir( Path, 0777, &ret_err, Info() ) ) { // skip "already exists" error if ( !fs->IsEEXIST( ret_err ) ) { throw_msg( "%s", fs->StrError( ret_err ).GetUtf8() ); } } } } else { int ret_err; if ( fs->MkDir( destPath, 0777, &ret_err, Info() ) ) { throw_msg( "%s", fs->StrError( ret_err ).GetUtf8() ); } } }
bool ParzeLink( FSPath& path, FSString& link ) { FSPath t( link ); if ( !path.IsAbsolute() && !t.IsAbsolute() ) { return false; } //не абсолютный путь int first = 0; if ( t.IsAbsolute() ) { path.Clear(); path.PushStr( FSString( "" ) ); first = 1; } for ( int i = first; i < t.Count(); i++ ) { FSString p = *( t.GetItem( i ) ); if ( p.IsDot() ) { continue; } if ( p.Is2Dot() ) { if ( path.Count() > 1 ) { path.Pop(); } } else { path.PushStr( p ); } } return true; }
bool OperCFThread::DeleteList( FS* fs, FSPath& _path, FSList& list ) { if ( Info()->Stopped() ) { return false; } FSPath path = _path; int cnt = path.Count(); for ( FSNode* node = list.First(); node; node = node->next ) { if ( node->extType ) { continue; } path.SetItemStr( cnt, node->Name() ); if ( node->IsDir() && !node->st.IsLnk() ) { if ( !DeleteDir( fs, path ) ) { return false; } if ( !RmDir( fs, path ) ) { return false; } continue; } if ( !DeleteFile( fs, path ) ) { return false; } } return true; }
bool OperCFThread::CopyDir(FS *srcFs, FSPath &__srcPath, FSNode *srcNode, FS *destFs, FSPath &__destPath, bool move) { if (Info()->Stopped()) return false; FSList list; int ret_error; while (true) { int ret = srcFs->ReadDir(&list, __srcPath, &ret_error, Info()); if (ret == -2) return false; if (!ret) break; switch ( RedMessage( _LT("Can`t open directory:\n") , srcFs->Uri(__srcPath).GetUtf8(), bRetrySkipCancel, srcFs->StrError(ret_error).GetUtf8()) ) { case CMD_SKIP: return true; case CMD_RETRY: continue; default: return false; } } while (destFs->MkDir(__destPath, MkDirMode, &ret_error, Info()) && !destFs->IsEEXIST(ret_error)) { switch (RedMessage( _LT("Can't create the directory:\n"), destFs->Uri(__destPath).GetUtf8(), bRetrySkipCancel, destFs->StrError(ret_error).GetUtf8())) { case CMD_CANCEL: return false; case CMD_SKIP: return true; } } FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); for (FSNode *node = list.First(); node; node = node->next) { if (Info()->Stopped()) return false; srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); if (!CopyNode(srcFs, srcPath, node, destFs, destPath, move)) return false; } destFs->SetFileTime(destPath, srcNode->st.mtime, srcNode->st.mtime, 0, Info()); return !move || RmDir(srcFs, __srcPath); }
void FSPath::Copy( const FSPath& a ) { cacheCs = -2; data.clear(); for ( int i = 0 ; i < a.Count(); i++ ) { FSString s; s.Copy( a.data.const_item( i ) ); data.append( s ); } }
int FSTmp::Rename(FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info) { FSTmpNode* n = rootDir.findByName(oldpath.GetItem(oldpath.Count() - 1)); if (n == 0) { return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND); } else { if (n->nodeType == FSTmpNode::NODE_FILE) { int ret = baseFS->Rename(n->baseFSPath, newpath, err, info); if (ret != 0) return ret; n->name = newpath.GetUnicode(); return SetError(err, 0); } else {// XXX ??? add case when new and old path are in different dirs ((FSTmpNode*)(n))->name = *newpath.GetItem(newpath.Count() - 1); return SetError(err, 0); } } }
int FSTmp::RmDir(FSPath& path, int* err, FSCInfo* info) { FSTmpNode* n = rootDir.findByFsPath(&path); FSString* dirName = path.GetItem(path.Count() - 1); for (auto it = n->parentDir->content.begin(); it != n->parentDir->content.end(); ++it) { if ((*it).name.Cmp(*dirName) == 0) { n->parentDir->content.erase(it); return FS::SetError(err, 0); } } return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND); }
void OperDirCalcThread::Calc() { MutexLock lock( Node().GetMutex() ); if ( !Node().Data() ) { return; } OperDirCalcData* CalcData = ( OperDirCalcData* )Node().Data(); clPtr<FS> fs = CalcData->dirFs; FSPath path = CalcData->_path; clPtr<FSList> list = CalcData->dirList; lock.Unlock(); //!!! //dbg_printf("OperDirCalcThread::Calc list data:"); //path.dbg_printf("FSPath:"); //for (FSNode* node = list->First(); node; node = node->next) // dbg_printf("%s\n", node->name.GetUtf8()); if (list->Count() == 0) { // then calculate current dir size CalcDir(fs.Ptr(), path); } else { // list is not empty: calculate size of objects in the list int cnt = path.Count(); for (FSNode* node = list->First(); node; node = node->next) { path.SetItemStr(cnt, node->Name()); //-V595 bool IsDir = node->IsDir() && !node->st.IsLnk(); if ( IsDir ) { int64_t Size = CalcDir( fs.Ptr(), path); if ( Size >= 0 && node && node->originNode ) { node->originNode->st.size = Size; } CalcData->folderCount++; } else { CalcData->fileCount++; CalcData->sumSize += node->st.size; } } } }
int FSTmp::SetFileTime(FSPath& path, FSTime cTime, FSTime aTime, FSTime mTime, int* err, FSCInfo* info) { FSTmpNode* fsTemp = rootDir.findByName(path.GetItem(path.Count() - 1)); if (fsTemp == 0) { return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND); } else { fsTemp->fsStat.m_CreationTime = cTime; fsTemp->fsStat.m_LastAccessTime = aTime; fsTemp->fsStat.m_LastWriteTime = mTime; fsTemp->fsStat.m_ChangeTime = mTime; if (fsTemp->nodeType == FSTmpNode::NODE_FILE) return baseFS->SetFileTime(fsTemp->baseFSPath, cTime, aTime, mTime, err, info); else return FS::SetError(err, 0); } }
int FSTmp::ReadDir(FSList* list, FSPath& path, int* err, FSCInfo* info) { list->Clear(); // Adding the ".." node to root dir even if it is disabled in config // to address CR #436: "Temporary panel should have .. item to go back to last directory" if (!g_WcmConfig.panelShowDotsInRoot) { if (path.Count() == 1) // i.e. on root level { clPtr<FSNode> pNode = new FSNode(); pNode->name = std::string(".."); pNode->st.mode = S_IFDIR; list->Append(pNode); } } FSTmpNode* n = rootDir.findByFsPath(&path); if (!n || n->nodeType != FSTmpNode::NODE_DIR) { return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND); } for (FSTmpNode& tn : n->content) { clPtr<FSNode> pNode = new FSNode(); pNode->name=(std::string("") + tn.name.GetUtf8()).c_str(); if (tn.nodeType == FSTmpNode::NODE_DIR) pNode->st = tn.fsStat; else { if (baseFS->Stat(tn.baseFSPath, & pNode->st, 0, 0) != 0) pNode->st = tn.fsStat; } list->Append(pNode); } return 0; }
int FSWin32Net::ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info ) { list->Clear(); if ( path.Count() > 1 ) { if ( err ) { *err = ERRNOSUPPORT; } return -1; } WNetEnumerator en; if ( !en.Open( _res.Get() ) ) { SetError( err, GetLastError() ); return -1; } try { while ( true ) { if ( info && info->Stopped() ) { return -2; } DWORD dwErr = 0; NETRESOURCEW* p = en.Next( &dwErr ); if ( !p ) { if ( !dwErr ) { break; } SetError( err, dwErr ); return -1; } if ( !p->lpRemoteName ) { continue; } wchar_t* pName = p->lpRemoteName; if ( p->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE || p->dwDisplayType == RESOURCEDISPLAYTYPE_SERVER ) { //выкинуть из названия шары имя сервера, а из названия сервера - косые символы wchar_t* last = 0; for ( wchar_t* s = pName; *s; s++ ) if ( *s == '\\' ) { last = s; } if ( last && last[1] ) { pName = last + 1; } } clPtr<FSNode> pNode = new FSNode(); pNode->name.Set( CS_UNICODE, Utf16ToUnicode( pName ).data() ); pNode->st.mode = S_IFDIR; pNode->st.mode |= 0664; pNode->_w32NetRes = W32NetRes( p ); switch ( p->dwDisplayType ) { //case RESOURCEDISPLAYTYPE_GENERIC: return "GENERIC"; case RESOURCEDISPLAYTYPE_DOMAIN: case RESOURCEDISPLAYTYPE_GROUP: case RESOURCEDISPLAYTYPE_NETWORK: pNode->extType = FSNode::WORKGROUP; break; case RESOURCEDISPLAYTYPE_SERVER: pNode->extType = FSNode::SERVER; break; case RESOURCEDISPLAYTYPE_DIRECTORY: case RESOURCEDISPLAYTYPE_SHARE: pNode->extType = FSNode::FILESHARE; break; }; list->Append( pNode ); }; return 0; } catch ( ... ) { throw; } SetError( err, 100 ); return -1; }
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; } }
int OperCFThread::MoveDir( FS* srcFs, FSPath& __srcPath, FSNode* srcNode, FS* destFs, FSPath& __destPath ) { if ( Info()->Stopped() ) { return -1; } if ( srcFs != destFs ) { return 1; } FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); if ( IsSameFile( srcFs, srcPath, &( srcNode->st ), destFs, destPath ) ) { RedMessage( _LT( "Can't move directory to itself:\n" ), srcFs->Uri( __srcPath ).GetUtf8() ); return -1; } FSStat st; int ret_error; if ( !destFs->Stat( destPath, &st, &ret_error, Info() ) ) { if ( !st.IsDir() ) { switch ( RedMessage( _LT( "Can't copy directory\n" ), srcFs->Uri( srcPath ).GetUtf8(), _LT( "to file" ), "\n", _LT( "Delete the file?" ), destFs->Uri( destPath ).GetUtf8(), bOkSkipCancel ) ) { case CMD_CANCEL: return -1; case CMD_SKIP: return 0; } if ( !Unlink( destFs, destPath ) ) { return -1; } } else { FSList list; while ( true ) { int ret = srcFs->ReadDir( &list, srcPath, &ret_error, Info() ); if ( ret == -2 ) { return -1; } if ( !ret ) { break; } switch ( RedMessage( _LT( "Can`t open directory:\n" ), srcFs->Uri( __srcPath ).GetUtf8(), bRetrySkipCancel, srcFs->StrError( ret_error ).GetUtf8() ) ) { case CMD_SKIP: return 0; case CMD_RETRY: continue; default: return -1; } } for ( FSNode* node = list.First(); node; node = node->next ) { if ( Info()->Stopped() ) { return -1; } srcPath.SetItemStr( srcPos, node->Name() ); destPath.SetItemStr( destPos, node->Name() ); if ( !MoveFile( srcFs, srcPath, node, destFs, destPath ) ) { return -1; } } destFs->SetFileTime( destPath, srcNode->st.m_CreationTime, srcNode->st.m_LastWriteTime, srcNode->st.m_LastWriteTime, 0, Info() ); return RmDir( srcFs, srcPath ) ? 0 : -1; } } if ( srcFs->Rename( srcPath, destPath, &ret_error, Info() ) ) { if ( srcFs->IsEXDEV( ret_error ) ) { return 1; } return RedMessage( _LT( "Can't rename the directory:\n" ), srcFs->Uri( srcPath ).GetUtf8(), "\nto\n", destFs->Uri( destPath ).GetUtf8(), bSkipCancel, srcFs->StrError( ret_error ).GetUtf8() ) == CMD_SKIP ? 0 : -1; } return 0; }
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 }
int64_t OperDirCalcThread::CalcDir( FS* fs, FSPath path ) { if ( Info()->Stopped() ) { return -1; } { //lock MutexLock lock( Node().GetMutex() ); if ( !Node().Data() ) { return -1; } OperDirCalcData* data = ( OperDirCalcData* )Node().Data(); MutexLock l1( &data->resMutex ); data->currentPath = path; } Node().SendSignal( 10 ); FSList list; int err; if ( fs->ReadDir( &list, path, &err, Info() ) ) { MutexLock lock( Node().GetMutex() ); if ( !Node().Data() ) { return -1; } MutexLock l1( &( ( OperDirCalcData* )Node().Data() )->resMutex ); ( ( OperDirCalcData* )Node().Data() )->badDirs++; return -1; }; int count = list.Count(); std::vector<FSNode*> p = list.GetArray(); //list.SortByName(p.ptr(), count, true, false); int lastPathPos = path.Count(); FSPath filePath = path; int64_t fileCount = 0; int64_t folderCount = 0; int64_t sumSize = 0; int i; for ( i = 0; i < count; i++ ) { if ( p[i]->IsDir() ) { folderCount++; continue; }; fileCount++; if ( p[i]->IsReg() && !p[i]->IsLnk() ) { sumSize += p[i]->Size(); } } { //lock MutexLock lock( Node().GetMutex() ); if ( !Node().Data() ) { return -1; } OperDirCalcData* data = ( OperDirCalcData* )Node().Data(); MutexLock l1( &data->resMutex ); data->fileCount += fileCount; data->folderCount += folderCount; data->sumSize += sumSize; } Node().SendSignal( 20 ); for ( i = 0; i < count; i++ ) { if ( p[i]->IsDir() && !p[i]->extType && p[i]->st.link.IsEmpty() ) { if ( Info()->Stopped() ) { return -1; } path.SetItemStr( lastPathPos, p[i]->Name() ); sumSize += CalcDir( fs, path ); } } return sumSize; }