1
0
Эх сурвалжийг харах

Preparing for Issue 2231 – Support for [email protected] SFTP extension

https://winscp.net/tracker/2231

Source commit: 4772cb75a566c3b93d175950806028a1ba56e9aa
Martin Prikryl 1 жил өмнө
parent
commit
3be9a70b6d

+ 9 - 0
source/core/SessionData.cpp

@@ -308,6 +308,7 @@ void __fastcall TSessionData::DefaultSettings()
   SFTPMaxVersion = ::SFTPMaxVersion;
   SFTPMaxPacketSize = 0;
   SFTPRealPath = asAuto;
+  UsePosixRename = false;
 
   for (unsigned int Index = 0; Index < LENOF(FSFTPBugs); Index++)
   {
@@ -490,6 +491,7 @@ void __fastcall TSessionData::NonPersistant()
   PROPERTY(SFTPMaxVersion); \
   PROPERTY(SFTPMaxPacketSize); \
   PROPERTY(SFTPRealPath); \
+  PROPERTY(UsePosixRename); \
   \
   for (unsigned int Index = 0; Index < LENOF(FSFTPBugs); Index++) \
   { \
@@ -884,6 +886,7 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
   SFTPUploadQueue = Storage->ReadInteger(L"SFTPUploadQueue", SFTPUploadQueue);
   SFTPListingQueue = Storage->ReadInteger(L"SFTPListingQueue", SFTPListingQueue);
   SFTPRealPath = Storage->ReadEnum(L"SFTPRealPath", SFTPRealPath, AutoSwitchMapping);
+  UsePosixRename = Storage->ReadBool(L"UsePosixRename", UsePosixRename);
 
   Color = Storage->ReadInteger(L"Color", Color);
 
@@ -1207,6 +1210,7 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
     WRITE_DATA(Integer, SFTPUploadQueue);
     WRITE_DATA(Integer, SFTPListingQueue);
     WRITE_DATA(Integer, SFTPRealPath);
+    WRITE_DATA(Bool, UsePosixRename);
 
     WRITE_DATA(Integer, Color);
 
@@ -4317,6 +4321,11 @@ void __fastcall TSessionData::SetSFTPRealPath(TAutoSwitch value)
   SET_SESSION_PROPERTY(SFTPRealPath);
 }
 //---------------------------------------------------------------------
+void TSessionData::SetUsePosixRename(bool value)
+{
+  SET_SESSION_PROPERTY(UsePosixRename);
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::SetSFTPBug(TSftpBug Bug, TAutoSwitch value)
 {
   DebugAssert(Bug >= 0 && static_cast<unsigned int>(Bug) < LENOF(FSFTPBugs));

+ 3 - 0
source/core/SessionData.h

@@ -191,6 +191,7 @@ private:
   int FSFTPMaxVersion;
   unsigned long FSFTPMaxPacketSize;
   TAutoSwitch FSFTPRealPath;
+  bool FUsePosixRename;
   TDSTMode FDSTMode;
   TAutoSwitch FSFTPBugs[SFTP_BUG_COUNT];
   bool FDeleteToRecycleBin;
@@ -378,6 +379,7 @@ private:
   void __fastcall SetSFTPMaxVersion(int value);
   void __fastcall SetSFTPMaxPacketSize(unsigned long value);
   void __fastcall SetSFTPRealPath(TAutoSwitch value);
+  void SetUsePosixRename(bool value);
   void __fastcall SetSFTPBug(TSftpBug Bug, TAutoSwitch value);
   TAutoSwitch __fastcall GetSFTPBug(TSftpBug Bug) const;
   void __fastcall SetSCPLsFullTime(TAutoSwitch value);
@@ -668,6 +670,7 @@ public:
   __property int SFTPMaxVersion = { read = FSFTPMaxVersion, write = SetSFTPMaxVersion };
   __property unsigned long SFTPMaxPacketSize = { read = FSFTPMaxPacketSize, write = SetSFTPMaxPacketSize };
   __property TAutoSwitch SFTPRealPath = { read = FSFTPRealPath, write = SetSFTPRealPath };
+  __property bool UsePosixRename = { read = FUsePosixRename, write = SetUsePosixRename };
   __property TAutoSwitch SFTPBug[TSftpBug Bug]  = { read=GetSFTPBug, write=SetSFTPBug };
   __property TAutoSwitch SCPLsFullTime = { read = FSCPLsFullTime, write = SetSCPLsFullTime };
   __property TAutoSwitch FtpListAll = { read = FFtpListAll, write = SetFtpListAll };

+ 5 - 1
source/core/SessionInfo.cpp

@@ -1358,7 +1358,11 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
       ADF(L"SFTP Server: %s", ((Data->SftpServer.IsEmpty()? UnicodeString(L"default") : Data->SftpServer)));
       if (Data->SFTPRealPath != asAuto)
       {
-        ADF(L"SFTP Real Path: %s", (EnumName(Data->SFTPRealPath, AutoSwitchNames)));
+        ADF(L"SFTP Real path: %s", (EnumName(Data->SFTPRealPath, AutoSwitchNames)));
+      }
+      if (Data->UsePosixRename)
+      {
+        ADF(L"Use POSIX rename: %s", (BooleanToEngStr(Data->UsePosixRename)));
       }
     }
     bool FtpsOn = false;

+ 10 - 3
source/core/SftpFileSystem.cpp

@@ -155,6 +155,7 @@
 #define SFTP_EXT_COPY_DATA L"copy-data"
 #define SFTP_EXT_LIMITS L"[email protected]"
 #define SFTP_EXT_LIMITS_VALUE_V1 L"1"
+#define SFTP_EXT_POSIX_RENAME L"[email protected]"
 //---------------------------------------------------------------------------
 #define OGQ_LIST_OWNERS 0x01
 #define OGQ_LIST_GROUPS 0x02
@@ -3246,7 +3247,8 @@ void __fastcall TSFTPFileSystem::DoStartup()
       else if ((ExtensionName == SFTP_EXT_COPY_FILE) ||
                (ExtensionName == SFTP_EXT_COPY_DATA) ||
                (ExtensionName == SFTP_EXT_SPACE_AVAILABLE) ||
-               (ExtensionName == SFTP_EXT_CHECK_FILE))
+               (ExtensionName == SFTP_EXT_CHECK_FILE) ||
+               (ExtensionName == SFTP_EXT_POSIX_RENAME))
       {
         FTerminal->LogEvent(FORMAT(L"Supports extension %s=%s", (ExtensionName, ExtensionDisplayData)));
       }
@@ -3852,7 +3854,12 @@ void __fastcall TSFTPFileSystem::DeleteFile(const UnicodeString FileName,
 void __fastcall TSFTPFileSystem::RenameFile(
   const UnicodeString & FileName, const TRemoteFile *, const UnicodeString & NewName, bool DebugUsedArg(Overwrite))
 {
-  TSFTPPacket Packet(SSH_FXP_RENAME);
+  bool UsePosixRename = FTerminal->SessionData->UsePosixRename;
+  TSFTPPacket Packet(UsePosixRename ? SSH_FXP_EXTENDED : SSH_FXP_RENAME);
+  if (UsePosixRename)
+  {
+    Packet.AddString(SFTP_EXT_POSIX_RENAME);
+  }
   UnicodeString RealName = LocalCanonify(FileName);
   bool Encrypted = FTerminal->IsFileEncrypted(RealName);
   AddPathString(Packet, RealName);
@@ -3867,7 +3874,7 @@ void __fastcall TSFTPFileSystem::RenameFile(
     TargetName = LocalCanonify(NewName);
   }
   AddPathString(Packet, TargetName, Encrypted);
-  if (FVersion >= 5)
+  if (UsePosixRename && (FVersion >= 5))
   {
     Packet.AddCardinal(0);
   }

+ 2 - 0
source/forms/SiteAdvanced.cpp

@@ -197,6 +197,7 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
     // hide selection, which is wrongly shown initially even when the box has not focus
     SftpServerEdit->SelLength = 0;
     AllowScpFallbackCheck->Checked = (FSessionData->FSProtocol == fsSFTP);
+    UsePosixRenameCheck->Checked = FSessionData->UsePosixRename;
 
     SFTPMaxVersionCombo->ItemIndex = FSessionData->SFTPMaxVersion;
 
@@ -627,6 +628,7 @@ void __fastcall TSiteAdvancedDialog::SaveSession(TSessionData * SessionData)
       SessionData->FSProtocol = fsSFTPonly;
     }
   }
+  FSessionData->UsePosixRename = UsePosixRenameCheck->Checked;
 
   FSessionData->SFTPRealPath = ComboAutoSwitchSave(SFTPRealPathCombo);
   #define SAVE_SFTP_BUG_COMBO(BUG) SessionData->SFTPBug[sb ## BUG] = ComboAutoSwitchSave(SFTPBug ## BUG ## Combo);

+ 13 - 3
source/forms/SiteAdvanced.dfm

@@ -556,7 +556,7 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           382)
         object SFTPBugsGroupBox: TGroupBox
           Left = 0
-          Top = 130
+          Top = 153
           Width = 393
           Height = 70
           Anchors = [akLeft, akTop, akRight]
@@ -604,13 +604,13 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
           Left = 0
           Top = 6
           Width = 393
-          Height = 118
+          Height = 141
           Anchors = [akLeft, akTop, akRight]
           Caption = 'Protocol options'
           TabOrder = 0
           DesignSize = (
             393
-            118)
+            141)
           object Label34: TLabel
             Left = 12
             Top = 44
@@ -687,6 +687,16 @@ object SiteAdvancedDialog: TSiteAdvancedDialog
             Anchors = [akTop, akRight]
             TabOrder = 2
           end
+          object UsePosixRenameCheck: TCheckBox
+            Left = 12
+            Top = 113
+            Width = 369
+            Height = 17
+            Anchors = [akLeft, akTop, akRight]
+            Caption = '&Use POSIX rename'
+            TabOrder = 4
+            OnClick = DataChange
+          end
         end
       end
       object ScpSheet: TTabSheet

+ 1 - 0
source/forms/SiteAdvanced.h

@@ -284,6 +284,7 @@ __published:
   TFilenameEdit *DetachedCertificateEdit;
   TCheckBox *S3RequesterPaysCheck;
   TRadioButton *FtpPingDirectoryListingButton;
+  TCheckBox *UsePosixRenameCheck;
   void __fastcall DataChange(TObject *Sender);
   void __fastcall FormShow(TObject *Sender);
   void __fastcall PageControlChange(TObject *Sender);