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; }
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 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; }
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); }
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)); } } }
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 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; }
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; }