bool OperCFThread::CopyLink( FS* srcFs, FSPath& srcPath, FSNode* srcNode, FS* destFs, FSPath& destPath, bool move ) { ASSERT( srcNode->st.IsLnk() ); if ( IsSameFile( srcFs, srcPath, &( srcNode->st ), destFs, destPath ) ) { RedMessage( _LT( "Can't copy link to itself:\n" ) , srcFs->Uri( srcPath ).GetUtf8() ); return false; } int ret_err; while ( destFs->Symlink( destPath, srcNode->st.link, &ret_err, Info() ) && !skipNonRegular ) switch ( RedMessage( _LT( "Can't create symbolic link:\n" ), destFs->Uri( destPath ).GetUtf8(), "to\n", srcNode->st.link.GetUtf8(), bSkipSkipallCancel, destFs->StrError( ret_err ).GetUtf8() ) ) { case CMD_CANCEL: return false; case CMD_SKIPALL: skipNonRegular = true; case CMD_SKIP: return true; } return !move || Unlink( srcFs, srcPath ); }
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 OperCFThread::MoveFile( FS* srcFs, FSPath& srcPath, FSNode* srcNode, FS* destFs, FSPath& destPath ) { if ( srcFs != destFs && !srcFs->Equal( destFs ) ) { return 1; } if ( IsSameFile( srcFs, srcPath, &( srcNode->st ), destFs, destPath ) ) { RedMessage( _LT( "Can't move file to itself:\n" ), srcFs->Uri( srcPath ).GetUtf8() ); return -1; } int ret_error; FSStat st; if ( !destFs->Stat( destPath, &st, &ret_error, Info() ) ) { if ( !commitAll ) { switch ( RedMessage( _LT( "Overwrite file?\n" ), destFs->Uri( destPath ).GetUtf8(), bOkAllNoCancel, destFs->StrError( ret_error ).GetUtf8() ) ) { case CMD_ALL: commitAll = true; //no break case CMD_OK: break; case CMD_NO: return 0; default: return -1; } } if ( destFs->Delete( destPath, &ret_error, Info() ) ) return RedMessage( _LT( "Can't delete the file:\n" ), destFs->Uri( destPath ).GetUtf8(), bSkipCancel, destFs->StrError( ret_error ).GetUtf8() ) == CMD_SKIP ? 0 : -1 ; } if ( srcFs->Rename( srcPath, destPath, &ret_error, Info() ) ) { if ( srcFs->IsEXDEV( ret_error ) ) { return 1; } return RedMessage( _LT( "Can't rename the file:\n" ), srcFs->Uri( srcPath ).GetUtf8(), "\nto\n", destFs->Uri( destPath ).GetUtf8(), bSkipCancel, srcFs->StrError( ret_error ).GetUtf8() ) == CMD_SKIP ? 0 : -1; } return 0; }
bool OperCFThread::DeleteDir( FS* fs, FSPath& path ) { if ( Info()->Stopped() ) { return false; } FSList list; while ( true ) { int ret_err; int ret = fs->ReadDir( &list, path, &ret_err, Info() ); if ( ret == -2 ) { return false; } if ( !ret ) { break; } switch ( RedMessage( _LT( "Can`t open directory:\n" ), fs->Uri( path ).GetUtf8(), bRetrySkipCancel, fs->StrError( ret_err ).GetUtf8() ) ) { case CMD_SKIP: return true; case CMD_RETRY: continue; default: return false; } } return DeleteList( fs, path, list ); }
bool OperCFThread::DeleteFile( FS* fs, FSPath& path ) //return true if not concelled { if ( Info()->Stopped() ) { return false; } if ( !commitAll ) { switch ( RedMessage( _LT( "Do you want to delete file?\n" ), fs->Uri( path ).GetUtf8(), bDeleteAllSkipCancel ) ) { case CMD_SKIP: return true; case CMD_ALL: commitAll = true; break; case CMD_OK: break; default: return false; } } return Unlink( fs, path ); //skip all??? }
bool OperCFThread::RmDir( FS* fs, FSPath& path, bool* skipAll ) { int ret_err; while ( fs->RmDir( path, &ret_err, Info() ) ) { if ( skipAll && *skipAll ) { return true; } switch ( RedMessage( _LT( "Can`t delete directory:\n" ) , fs->Uri( path ).GetUtf8(), skipAll ? bRetrySkipSkipallCancel : bRetrySkipCancel, fs->StrError( ret_err ).GetUtf8() ) ) { case CMD_SKIPALL: if ( skipAll ) { *skipAll = true; } //no break case CMD_SKIP: return true; case CMD_RETRY: continue; default: 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); }
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; }
bool OperCFThread::CopyFile( FS* srcFs, FSPath& srcPath, FSNode* srcNode, FS* destFs, FSPath& destPath, bool move ) { if ( !srcNode->st.IsReg() && !skipNonRegular ) switch ( RedMessage( _LT( "Can't copy the links or special file:\n" ), srcFs->Uri( srcPath ).GetUtf8(), bSkipSkipallCancel ) ) { case CMD_SKIPALL: skipNonRegular = true; // no break case CMD_SKIP: return true; default: return false; } if ( IsSameFile( srcFs, srcPath, &( srcNode->st ), destFs, destPath ) ) { RedMessage( _LT( "Can't copy file to itself:\n" ) , srcFs->Uri( srcPath ).GetUtf8() ); return false; } SendCopyNextFileInfo( srcFs->Uri( srcPath ), destFs->Uri( destPath ) ); SendProgressInfo( srcNode->st.size, 0, 0 ); bool stopped = false; int ret_err; int in = -1; if (destFs->Type() == FS::TYPES::TMP) { // copy and move to tmpfs work the same way. Should we yell on move op instead? FSTmp* destTmpFS = static_cast<FSTmp*>(destFs); if (!destTmpFS->BaseIsEqual(srcFs)) { RedMessage(_LT("Temporary panel can store only files from the same file system:\n")); return false; } if (srcFs->Type() == FS::TMP && srcNode->IsReg()) { FSString srcFullFSString(srcNode->name.GetUnicode()); FSPath srcFullFSPath(srcFullFSString); //srcFullFSPath.dbg_printf("OperCFThread::CopyFile srcFullFSPath="); //destPath.dbg_printf("OperCFThread::CopyFile destPath="); FSPath destDir(destPath); destDir.Pop(); return destTmpFS->AddNode(srcFullFSPath, destDir); } else return destTmpFS->AddNode(srcPath, srcNode, destPath); } while ( true ) { in = srcFs->OpenRead( srcPath, FS::SHARE_READ, &ret_err, Info() ); if ( in == -2 ) { return false; } if ( in >= 0 ) { break; } switch ( RedMessage( _LT( "Can't open file:\n" ) , srcFs->Uri( srcPath ).GetUtf8(), bRetrySkipCancel, srcFs->StrError( ret_err ).GetUtf8() ) ) { case CMD_CANCEL: return false; case CMD_SKIP: return true; } } int out = -1; out = destFs->OpenCreate( destPath, false | commitAll, srcNode->st.mode, 0, &ret_err, Info() ); if ( out < 0 && destFs->IsEEXIST( ret_err ) ) switch ( RedMessage( _LT( "Overwrite file?\n" ) , destFs->Uri( destPath ).GetUtf8(), bOkAllNoCancel ) ) { case CMD_ALL: commitAll = true; //no break case CMD_OK: out = destFs->OpenCreate( destPath, true, srcNode->st.mode, 0, &ret_err, Info() ); break; case CMD_NO: srcFs->Close( in, 0, Info() ); return true; default: srcFs->Close( in, 0, Info() ); return false; } if ( out < 0 ) { srcFs->Close( in, 0, Info() ); return RedMessage( _LT( "Can't create file:\n" ), destFs->Uri( destPath ).GetUtf8(), bSkipCancel, destFs->StrError( ret_err ).GetUtf8() ) == CMD_SKIP; } int bytes; //char buf[BUFSIZE]; int64_t doneBytes = 0; int blockSize = STARTSIZE; while ( true ) { if ( Info()->Stopped() ) { stopped = true; goto err; } time_t timeStart = time( 0 ); if ( ( bytes = srcFs->Read( in, _buffer, blockSize, &ret_err, Info() ) ) < 0 ) { if ( bytes == -2 || RedMessage( _LT( "Can't read the file:\n" ), srcFs->Uri( srcPath ).GetUtf8(), bSkipCancel, srcFs->StrError( ret_err ).GetUtf8() ) != CMD_SKIP ) { stopped = true; } goto err; } if ( !bytes ) { break; } int b; if ( ( b = destFs->Write( out, _buffer, bytes, &ret_err, Info() ) ) < 0 ) { if ( b == -2 || RedMessage( _LT( "Can't write the file:\n" ), destFs->Uri( destPath ).GetUtf8(), bSkipCancel, destFs->StrError( ret_err ).GetUtf8() ) != CMD_SKIP ) { stopped = true; } goto err; } if ( b != bytes ) { if ( RedMessage( "May be disk full \n(writed bytes != readed bytes)\nwhen write:\n", destFs->Uri( destPath ).GetUtf8(), bSkipCancel ) != CMD_SKIP ) { stopped = true; } goto err; } time_t timeStop = time( 0 ); if ( timeStart == timeStop && blockSize < BSIZE ) { blockSize = blockSize * 2; if ( blockSize > BSIZE ) { blockSize = BSIZE; } } doneBytes += bytes; SendProgressInfo( srcNode->st.size, doneBytes, bytes ); } srcFs->Close( in, 0, Info() ); in = -1; SendProgressInfo( srcNode->st.size, srcNode->st.size, 0 ); { int r = destFs->Close( out, &ret_err, Info() ); if ( r ) { if ( r == -2 || RedMessage( "Can't close the file:\n", destFs->Uri( destPath ).GetUtf8(), bSkipCancel, destFs->StrError( ret_err ).GetUtf8() ) != CMD_SKIP ) { stopped = true; } goto err; } else { out = -1; } } destFs->SetFileTime( destPath, srcNode->st.m_CreationTime, srcNode->st.m_LastWriteTime, srcNode->st.m_LastWriteTime, 0, Info() ); return !move || Unlink( srcFs, srcPath ); err: if ( in >= 0 ) { srcFs->Close( in, 0, Info() ); } if ( out >= 0 ) { destFs->Close( out, 0, Info() ); } Unlink( destFs, destPath ); return !stopped; }
bool OperCFThread::CopyFile(FS *srcFs, FSPath &srcPath, FSNode *srcNode, FS *destFs, FSPath &destPath, bool move) { if (!srcNode->st.IsReg() && !skipNonRegular) switch (RedMessage( _LT("Can't copy the links or special file:\n"), srcFs->Uri(srcPath).GetUtf8(), bSkipSkipallCancel)) { case CMD_SKIPALL: skipNonRegular = true; // no break case CMD_SKIP: return true; default: return false; } if (IsSameFile(srcFs, srcPath, &(srcNode->st), destFs, destPath)) { RedMessage( _LT("Can't copy file to itself:\n") , srcFs->Uri(srcPath).GetUtf8()); return false; } SendCopyNextFileInfo(srcFs->Uri(srcPath), destFs->Uri(destPath)); SendProgressInfo(srcNode->st.size, 0); bool stopped = false; int ret_err; int in = -1; while (true) { in = srcFs->OpenRead(srcPath, FS::SHARE_READ, &ret_err, Info()); if (in == -2) return false; if (in>=0) break; switch (RedMessage( _LT("Can't open file:\n") , srcFs->Uri(srcPath).GetUtf8(), bRetrySkipCancel, srcFs->StrError(ret_err).GetUtf8())) { case CMD_CANCEL: return false; case CMD_SKIP: return true; } } int out = -1; out = destFs->OpenCreate(destPath, false | commitAll, srcNode->st.mode, 0, &ret_err, Info()); if (out < 0 && destFs->IsEEXIST(ret_err)) switch (RedMessage( _LT("Owerwrite file?\n") , destFs->Uri(destPath).GetUtf8(), bOkAllNoCancel)) { case CMD_ALL: commitAll = true; //no break case CMD_OK: out = destFs->OpenCreate(destPath, true, srcNode->st.mode, 0, &ret_err, Info()); break; case CMD_NO: srcFs->Close(in, 0, Info()); return true; default: srcFs->Close(in, 0, Info()); return false; } if (out < 0) { srcFs->Close(in, 0, Info()); return RedMessage( _LT("Can't create file:\n"), destFs->Uri(destPath).GetUtf8(), bSkipCancel, destFs->StrError(ret_err).GetUtf8()) == CMD_SKIP; } int bytes; //char buf[BUFSIZE]; int64 doneBytes = 0; int blockSize = STARTSIZE; while (true) { if (Info()->Stopped()) { stopped = true; goto err; } time_t timeStart = time(0); if ((bytes = srcFs->Read(in, _buffer, blockSize, &ret_err, Info())) < 0) { if (bytes == -2 || RedMessage( _LT("Can't read the file:\n"), srcFs->Uri(srcPath).GetUtf8(), bSkipCancel, srcFs->StrError(ret_err).GetUtf8()) != CMD_SKIP) { stopped = true; } goto err; } if (!bytes) break; int b; if ((b = destFs->Write(out, _buffer, bytes, &ret_err, Info())) < 0) { if (b == -2 || RedMessage( _LT("Can't write the file:\n"), destFs->Uri(destPath).GetUtf8(), bSkipCancel, destFs->StrError(ret_err).GetUtf8()) != CMD_SKIP) stopped = true; goto err; } if (b != bytes) { if (RedMessage("May be disk full \n(writed bytes != readed bytes)\nwhen write:\n", destFs->Uri(destPath).GetUtf8(), bSkipCancel) != CMD_SKIP) stopped = true; goto err; } time_t timeStop = time(0); if (timeStart == timeStop && blockSize < BSIZE) { blockSize = blockSize*2; if (blockSize > BSIZE) blockSize = BSIZE; } doneBytes += bytes; SendProgressInfo(srcNode->st.size, doneBytes); } srcFs->Close(in, 0, Info()); in = -1; SendProgressInfo(srcNode->st.size, srcNode->st.size); { int r = destFs->Close(out, &ret_err, Info()); if (r) { if (r == -2 || RedMessage( "Can't close the file:\n", destFs->Uri(destPath).GetUtf8(), bSkipCancel, destFs->StrError(ret_err).GetUtf8()) != CMD_SKIP) stopped = true; goto err; } else out = -1; } destFs->SetFileTime(destPath, srcNode->st.mtime, srcNode->st.mtime, 0, Info()); return !move || Unlink(srcFs, srcPath); err: if (in >= 0) srcFs->Close(in, 0, Info()); if (out >= 0) destFs->Close(out, 0, Info()); Unlink(destFs, destPath); return !stopped; }
int OperThread::RedMessage( const char* s1, const char* s2, const char* s3, const char* s4, const char* s5, const char* s6, ButtonDataNode* buttons, const char* sysErr ) { return RedMessage( buttons, carray_cat<char>( s1, s2, s3, s5, s5, s6 ).data(), sysErr ); }
int OperThread::RedMessage( const char* s1, ButtonDataNode* buttons, const char* sysErr ) { return RedMessage( buttons, s1, sysErr ); }