Skip to content

Commit

Permalink
Bug 2233: Consistent behavior across protocols and protocol capabilit…
Browse files Browse the repository at this point in the history
…ies when duplicating remote files

https://winscp.net/tracker/2233

Source commit: 2e8369131ae6d964b6d454036c2b79472142e06e
  • Loading branch information
martinprikryl committed Oct 25, 2023
1 parent 700baf4 commit d7ceff3
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 50 deletions.
4 changes: 2 additions & 2 deletions source/core/Script.cpp
Expand Up @@ -1387,13 +1387,13 @@ void __fastcall TScript::DoMvOrCp(TScriptProcParams * Parameters, TFSCapability

Target = UnixIncludeTrailingBackslash(TargetDirectory) + FileMask;
CheckMultiFilesToOne(FileList, Target, true);
bool DontOverwrite = true; // might use FConfirm eventually, but that would be breaking change
if (Cp)
{
FTerminal->CopyFiles(FileList, TargetDirectory, FileMask);
FTerminal->CopyFiles(FileList, TargetDirectory, FileMask, DontOverwrite);
}
else
{
bool DontOverwrite = true; // might use FConfirm eventually, but that would be breaking change
FTerminal->MoveFiles(FileList, TargetDirectory, FileMask, DontOverwrite);
}
}
Expand Down
101 changes: 56 additions & 45 deletions source/core/Terminal.cpp
Expand Up @@ -4828,12 +4828,11 @@ void __fastcall TTerminal::RenameFile(const TRemoteFile * File, const UnicodeStr
}
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::DoRenameFile(
const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName, bool Move, bool DontOverwrite)
bool TTerminal::DoRenameOrCopyFile(
bool Rename, const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName,
bool Move, bool DontOverwrite, bool IsBatchOperation)
{
// Can be foDelete when recycling (and overwrite should not happen in this case)
bool IsBatchMove = (OperationProgress != NULL) && (OperationProgress->Operation == foRemoteMove);
TBatchOverwrite BatchOverwrite = (IsBatchMove ? OperationProgress->BatchOverwrite : boNo);
TBatchOverwrite BatchOverwrite = (IsBatchOperation ? OperationProgress->BatchOverwrite : boNo);
UnicodeString AbsoluteNewName = AbsolutePath(NewName, true);
bool Result = true;
bool ExistenceKnown = false;
Expand Down Expand Up @@ -4871,7 +4870,7 @@ bool __fastcall TTerminal::DoRenameFile(
}
TQueryParams Params(qpNeverAskAgainCheck);
UnicodeString Question = FORMAT(QuestionFmt, (NewName));
unsigned int Answers = qaYes | qaNo | FLAGMASK(OperationProgress != NULL, qaCancel) | FLAGMASK(IsBatchMove, qaYesToAll | qaNoToAll);
unsigned int Answers = qaYes | qaNo | FLAGMASK(OperationProgress != NULL, qaCancel) | FLAGMASK(IsBatchOperation, qaYesToAll | qaNoToAll);
unsigned int Answer = QueryUser(Question, NULL, Answers, &Params, QueryType);
switch (Answer)
{
Expand All @@ -4890,15 +4889,15 @@ bool __fastcall TTerminal::DoRenameFile(

case qaYesToAll:
Result = true;
if (DebugAlwaysTrue(IsBatchMove))
if (DebugAlwaysTrue(IsBatchOperation))
{
OperationProgress->SetBatchOverwrite(boAll);
}
break;

case qaNoToAll:
Result = false;
if (DebugAlwaysTrue(IsBatchMove))
if (DebugAlwaysTrue(IsBatchOperation))
{
OperationProgress->SetBatchOverwrite(boNone);
}
Expand Down Expand Up @@ -4939,16 +4938,44 @@ bool __fastcall TTerminal::DoRenameFile(
TRetryOperationLoop RetryLoop(this);
do
{
TMvSessionAction Action(ActionLog, AbsolutePath(FileName, true), AbsoluteNewName);
try
UnicodeString AbsoluteFileName = AbsolutePath(FileName, true);
DebugAssert(FFileSystem != NULL);
if (Rename)
{
DebugAssert(FFileSystem);
FFileSystem->RenameFile(FileName, File, NewName, !DontOverwrite);
TMvSessionAction Action(ActionLog, AbsoluteFileName, AbsoluteNewName);
try
{
FFileSystem->RenameFile(FileName, File, NewName, !DontOverwrite);
}
catch (Exception & E)
{
UnicodeString Message = FMTLOAD(Move ? MOVE_FILE_ERROR : RENAME_FILE_ERROR, (FileName, NewName));
RetryLoop.Error(E, Action, Message);
}
}
catch(Exception & E)
else
{
UnicodeString Message = FMTLOAD(Move ? MOVE_FILE_ERROR : RENAME_FILE_ERROR, (FileName, NewName));
RetryLoop.Error(E, Action, Message);
TCpSessionAction Action(ActionLog, AbsoluteFileName, AbsoluteNewName);
try
{
bool CopyDirsOnSecondarySession = IsCapable[fcSecondaryShell];
TCustomFileSystem * FileSystem;
if (CopyDirsOnSecondarySession && File->IsDirectory &&
(FCommandSession != NULL)) // Won't be in scripting, there we let it fail later
{
PrepareCommandSession();
FileSystem = FCommandSession->FFileSystem;
}
else
{
FileSystem = GetFileSystemForCapability(fcRemoteCopy);
}
FileSystem->CopyFile(FileName, File, NewName, !DontOverwrite);
}
catch (Exception & E)
{
RetryLoop.Error(E, Action, FMTLOAD(COPY_FILE_ERROR, (FileName, NewName)));
}
}
}
while (RetryLoop.Retry());
Expand All @@ -4962,6 +4989,14 @@ bool __fastcall TTerminal::DoRenameFile(
return Result;
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::DoRenameFile(
const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName, bool Move, bool DontOverwrite)
{
// Can be foDelete when recycling (and overwrite should not happen in this case)
bool IsBatchOperation = (OperationProgress != NULL) && (OperationProgress->Operation == foRemoteMove);
return DoRenameOrCopyFile(true, FileName, File, NewName, Move, DontOverwrite, IsBatchOperation);
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::DoMoveFile(const UnicodeString & FileName, const TRemoteFile * File, /*const TMoveFileParams*/ void * Param)
{
StartOperationWithFile(FileName, foRemoteMove, foDelete);
Expand Down Expand Up @@ -5047,33 +5082,9 @@ bool __fastcall TTerminal::MoveFiles(
void __fastcall TTerminal::DoCopyFile(
const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName, bool DontOverwrite)
{
TRetryOperationLoop RetryLoop(this);
do
{
TCpSessionAction Action(ActionLog, AbsolutePath(FileName, true), AbsolutePath(NewName, true));
try
{
DebugAssert(FFileSystem);
bool CopyDirsOnSecondarySession = IsCapable[fcSecondaryShell];
TCustomFileSystem * FileSystem;
if (CopyDirsOnSecondarySession && File->IsDirectory &&
(FCommandSession != NULL)) // Won't be in scripting, there we let is fail later
{
PrepareCommandSession();
FileSystem = FCommandSession->FFileSystem;
}
else
{
FileSystem = GetFileSystemForCapability(fcRemoteCopy);
}
FileSystem->CopyFile(FileName, File, NewName, !DontOverwrite);
}
catch(Exception & E)
{
RetryLoop.Error(E, Action, FMTLOAD(COPY_FILE_ERROR, (FileName, NewName)));
}
}
while (RetryLoop.Retry());
bool IsBatchOperation = DebugAlwaysTrue(OperationProgress != NULL);
bool Move = false; // not used
DoRenameOrCopyFile(false, FileName, File, NewName, Move, DontOverwrite, IsBatchOperation);
}
//---------------------------------------------------------------------------
void __fastcall TTerminal::CopyFile(const UnicodeString FileName,
Expand All @@ -5089,13 +5100,13 @@ void __fastcall TTerminal::CopyFile(const UnicodeString FileName,
ReactOnCommand(fsCopyFile);
}
//---------------------------------------------------------------------------
bool __fastcall TTerminal::CopyFiles(TStrings * FileList, const UnicodeString Target,
const UnicodeString FileMask)
bool __fastcall TTerminal::CopyFiles(
TStrings * FileList, const UnicodeString & Target, const UnicodeString & FileMask, bool DontOverwrite)
{
TMoveFileParams Params;
Params.Target = Target;
Params.FileMask = FileMask;
Params.DontOverwrite = true; // not used
Params.DontOverwrite = DontOverwrite;
DirectoryModified(Target, true);
return ProcessFiles(FileList, foRemoteCopy, CopyFile, &Params);
}
Expand Down
7 changes: 5 additions & 2 deletions source/core/Terminal.h
Expand Up @@ -279,6 +279,9 @@ friend class TParallelOperation;
int Params);
void __fastcall DoCustomCommandOnFile(UnicodeString FileName,
const TRemoteFile * File, UnicodeString Command, int Params, TCaptureOutputEvent OutputEvent);
bool DoRenameOrCopyFile(
bool Rename, const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName,
bool Move, bool DontOverwrite, bool IsBatchOperation);
bool __fastcall DoRenameFile(
const UnicodeString & FileName, const TRemoteFile * File, const UnicodeString & NewName, bool Move, bool DontOverwrite);
bool __fastcall DoMoveFile(const UnicodeString & FileName, const TRemoteFile * File, /*const TMoveFileParams*/ void * Param);
Expand Down Expand Up @@ -586,8 +589,8 @@ friend class TParallelOperation;
TStrings * FileList, const UnicodeString & Target, const UnicodeString & FileMask, bool DontOverwrite);
void __fastcall CopyFile(const UnicodeString FileName, const TRemoteFile * File,
/*const TMoveFileParams*/ void * Param);
bool __fastcall CopyFiles(TStrings * FileList, const UnicodeString Target,
const UnicodeString FileMask);
bool __fastcall CopyFiles(
TStrings * FileList, const UnicodeString & Target, const UnicodeString & FileMask, bool DontOverwrite);
bool CalculateFilesSize(TStrings * FileList, __int64 & Size, TCalculateSizeParams & Params);
bool __fastcall CalculateLocalFilesSize(TStrings * FileList, __int64 & Size,
const TCopyParamType * CopyParam, bool AllowDirs, TStrings * Files, TCalculatedSizes * CalculatedSizes);
Expand Down
2 changes: 1 addition & 1 deletion source/forms/CustomScpExplorer.cpp
Expand Up @@ -4677,7 +4677,7 @@ bool __fastcall TCustomScpExplorerForm::RemoteTransferFiles(
Terminal->CommandSessionOpened ||
CommandSessionFallback())
{
Terminal->CopyFiles(FileList, Target, FileMask);
Terminal->CopyFiles(FileList, Target, FileMask, false);
}
}
}
Expand Down

0 comments on commit d7ceff3

Please sign in to comment.