mirror of
https://github.com/SFML/CSFML.git
synced 2026-10-26 13:06:13 +01:00
Add sfSftp as a secure replacement for sfFtp
This commit is contained in:
8 files changed
+1519
No files matched your search
@@ -33,6 +33,7 @@
|
||||
#include <CSFML/Network/Http.h>
|
||||
#include <CSFML/Network/IpAddress.h>
|
||||
#include <CSFML/Network/Packet.h>
|
||||
#include <CSFML/Network/Sftp.h>
|
||||
#include <CSFML/Network/SocketSelector.h>
|
||||
#include <CSFML/Network/SocketStatus.h>
|
||||
#include <CSFML/Network/TcpListener.h>
|
||||
|
||||
@@ -0,0 +1,778 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2026 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <CSFML/Network/Export.h>
|
||||
|
||||
#include <CSFML/Network/IpAddress.h>
|
||||
#include <CSFML/Network/Types.h>
|
||||
#include <CSFML/System/TimeoutWithPredicate.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Values of a SFTP result
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
// General result values
|
||||
sfSftpSuccess, ///< Operation completed successfully
|
||||
sfSftpDisconnected, ///< The TCP socket has been disconnected
|
||||
sfSftpTimeout, ///< Operation timed out
|
||||
sfSftpRefused, ///< Connection refused
|
||||
sfSftpError, ///< Generic error
|
||||
|
||||
// SSH result values
|
||||
sfSftpBannerReceive, ///< Error during banner receive
|
||||
sfSftpBannerSend, ///< Error during banner send
|
||||
sfSftpInvalidMac, ///< Invalid message authentication code
|
||||
sfSftpAllocationFailure, ///< Allocation failure
|
||||
sfSftpSocketSend, ///< Error sending on socket
|
||||
sfSftpKeyExchangeFailure, ///< Key exchange failed
|
||||
sfSftpHostKeyInitialization, ///< Host key initialization failed
|
||||
sfSftpHostKeySign, ///< Host key signing failed
|
||||
sfSftpDecryptError, ///< Decryption failed
|
||||
sfSftpProtocolError, ///< SSH protocol error
|
||||
sfSftpPasswordExpired, ///< Password expired
|
||||
sfSftpFileError, ///< File error
|
||||
sfSftpMethodNone, ///< No method found
|
||||
sfSftpAuthenticationFailed, ///< Authentication failed
|
||||
sfSftpPublicKeyUnverified, ///< Public key unverified
|
||||
sfSftpChannelOutOfOrder, ///< Channel out of order
|
||||
sfSftpChannelFailure, ///< Channel failure
|
||||
sfSftpChannelRequestDenied, ///< Channel request denied
|
||||
sfSftpChannelUnknown, ///< Channel unknown
|
||||
sfSftpChannelWindowExceeded, ///< Channel window exceeded
|
||||
sfSftpChannelPacketExceeded, ///< Channel packet exceeded
|
||||
sfSftpChannelClosed, ///< Channel closed
|
||||
sfSftpChannelEofSent, ///< Channel EOF sent
|
||||
sfSftpScpProtocol, ///< SCP protocol error
|
||||
sfSftpZlibError, ///< Zlib error
|
||||
sfSftpRequestDenied, ///< Request denied
|
||||
sfSftpMethodNotSupported, ///< Method not supported
|
||||
sfSftpInvalidData, ///< Invalid data
|
||||
sfSftpPublicKeyProtocol, ///< Public key protocol error
|
||||
sfSftpBufferTooSmall, ///< Buffer too small
|
||||
sfSftpBadUse, ///< Bad usage
|
||||
sfSftpCompressError, ///< Compression error
|
||||
sfSftpOutOfBoundary, ///< Out of boundary
|
||||
sfSftpAgentProtocol, ///< Agent protocol error
|
||||
sfSftpSocketRecv, ///< Socket receive error
|
||||
sfSftpEncryptError, ///< Encryption failed
|
||||
sfSftpBadSocket, ///< Bad socket
|
||||
sfSftpKnownHosts, ///< Known hosts error
|
||||
sfSftpChannelWindowFull, ///< Channel window full
|
||||
sfSftpKeyFileAuthenticationFailed, ///< Key file authentication failed
|
||||
|
||||
// SFTP result values
|
||||
sfSftpEndOfFile, ///< End of file
|
||||
sfSftpNoSuchFile, ///< No such file
|
||||
sfSftpPermissionDenied, ///< Permission denied
|
||||
sfSftpFailure, ///< Failure
|
||||
sfSftpBadMessage, ///< Bad message
|
||||
sfSftpNoConnection, ///< No connection
|
||||
sfSftpConnectionLost, ///< Connection lost
|
||||
sfSftpOperationUnsupported, ///< Operation unsupported
|
||||
sfSftpInvalidHandle, ///< Invalid handle
|
||||
sfSftpNoSuchPath, ///< No such path
|
||||
sfSftpFileAlreadyExists, ///< File already exists
|
||||
sfSftpWriteProtect, ///< Write protect
|
||||
sfSftpNoMedia, ///< No media
|
||||
sfSftpNoSpaceOnFileSystem, ///< No space on filesystem
|
||||
sfSftpQuotaExceeded, ///< Quota exceeded
|
||||
sfSftpUnknownPrincipal, ///< Unknown principal
|
||||
sfSftpLockConflict, ///< Lock conflict
|
||||
sfSftpDirectoryNotEmpty, ///< Directory not empty
|
||||
sfSftpNotADirectory, ///< Not a directory
|
||||
sfSftpInvalidFilename, ///< Invalid filename
|
||||
sfSftpLinkLoop, ///< Link loop
|
||||
sfSftpSftpError ///< Generic SFTP error
|
||||
} sfSftpResultValue;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Type of a remote file system entry
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
sfSftpFileNone, ///< No type
|
||||
sfSftpFileNotFound, ///< The file does not exist
|
||||
sfSftpFileRegular, ///< Regular file
|
||||
sfSftpFileDirectory, ///< Directory
|
||||
sfSftpFileSymlink, ///< Symbolic link
|
||||
sfSftpFileBlock, ///< Block special file
|
||||
sfSftpFileCharacter, ///< Character special file
|
||||
sfSftpFileFifo, ///< FIFO or pipe
|
||||
sfSftpFileSocket, ///< Socket
|
||||
sfSftpFileUnknown ///< Unknown type
|
||||
} sfSftpFileType;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Attributes of a remote file system entry
|
||||
///
|
||||
/// Each attribute is only valid if the corresponding
|
||||
/// has-flag is set.
|
||||
///
|
||||
/// Permissions use the POSIX permission bits, e.g. 0755.
|
||||
/// Times are given in seconds since the Unix epoch.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef struct
|
||||
{
|
||||
const char* path; ///< Path to the entry, encoded in UTF-8
|
||||
uint64_t size; ///< Size of the entry
|
||||
uint64_t userId; ///< Owner user ID
|
||||
uint64_t groupId; ///< Group ID
|
||||
int64_t accessTime; ///< Last access time
|
||||
int64_t modificationTime; ///< Last modification time
|
||||
sfSftpFileType type; ///< Type of the entry
|
||||
uint32_t permissions; ///< Permissions
|
||||
bool hasType; ///< Whether the type is available
|
||||
bool hasSize; ///< Whether the size is available
|
||||
bool hasPermissions; ///< Whether the permissions are available
|
||||
bool hasUserId; ///< Whether the owner user ID is available
|
||||
bool hasGroupId; ///< Whether the group ID is available
|
||||
bool hasAccessTime; ///< Whether the last access time is available
|
||||
bool hasModificationTime; ///< Whether the last modification time is available
|
||||
} sfSftpAttributes;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Type of a SSH host key
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
sfSftpHostKeyUnknown, ///< Unknown key type
|
||||
sfSftpHostKeyRsa, ///< RSA
|
||||
sfSftpHostKeyDsa, ///< DSA
|
||||
sfSftpHostKeyEcdsa256, ///< NIST P-256 ECDSA
|
||||
sfSftpHostKeyEcdsa384, ///< NIST P-384 ECDSA
|
||||
sfSftpHostKeyEcdsa521, ///< NIST P-521 ECDSA
|
||||
sfSftpHostKeyEd25519 ///< ED25519
|
||||
} sfSftpHostKeyType;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief SSH session information
|
||||
///
|
||||
/// The algorithm identifiers follow the RFC 4253 specification.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef struct
|
||||
{
|
||||
sfSftpHostKeyType hostKeyType; ///< Host key type
|
||||
const uint8_t* hostKeyData; ///< Host key data
|
||||
size_t hostKeySize; ///< Size of the host key data
|
||||
uint8_t hostKeySha1[20]; ///< Host key SHA1 hash
|
||||
uint8_t hostKeySha256[32]; ///< Host key SHA256 hash
|
||||
const char* keyExchangeAlgorithm; ///< Key exchange algorithm used in the session
|
||||
const char* hostKeyAlgorithm; ///< Host key algorithm used in the session
|
||||
const char* clientToServerEncryptionAlgorithm; ///< Client to server encryption algorithm used in the session
|
||||
const char* serverToClientEncryptionAlgorithm; ///< Server to client encryption algorithm used in the session
|
||||
const char* clientToServerMacAlgorithm; ///< Client to server message authentication code algorithm used in the session
|
||||
const char* serverToClientMacAlgorithm; ///< Server to client message authentication code algorithm used in the session
|
||||
const char* clientToServerCompressionAlgorithm; ///< Client to server compression algorithm used in the session
|
||||
const char* serverToClientCompressionAlgorithm; ///< Server to client compression algorithm used in the session
|
||||
} sfSftpSessionInfo;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Callback receiving the data of a downloaded file
|
||||
///
|
||||
/// The data is transferred in sequential blocks. The size of
|
||||
/// the blocks can change over time.
|
||||
///
|
||||
/// \param data Pointer to the received data block
|
||||
/// \param size Size of the received data block
|
||||
/// \param userData User data passed to sfSftp_download
|
||||
///
|
||||
/// \return True to continue the transfer, false to abort it
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef bool (*sfSftpDownloadCallback)(const void* data, size_t size, void* userData);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Callback providing the data of a file to upload
|
||||
///
|
||||
/// Data to be sent should be copied into the data block and
|
||||
/// \a size set to the actual number of bytes copied. When
|
||||
/// called, \a size contains the size of the data block, which
|
||||
/// can change over time.
|
||||
///
|
||||
/// \param data Pointer to the data block to fill
|
||||
/// \param size Size of the data block, to be set to the number of bytes copied
|
||||
/// \param userData User data passed to sfSftp_upload
|
||||
///
|
||||
/// \return True to continue the transfer, false to stop it e.g. because there is no more data to send
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef bool (*sfSftpUploadCallback)(void* data, size_t* size, void* userData);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destroy a SFTP result
|
||||
///
|
||||
/// \param result SFTP result to destroy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API void sfSftpResult_destroy(const sfSftpResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a SFTP result is a success
|
||||
///
|
||||
/// \param result SFTP result
|
||||
///
|
||||
/// \return True if the result is sfSftpSuccess
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API bool sfSftpResult_isOk(const sfSftpResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the value of a SFTP result
|
||||
///
|
||||
/// \param result SFTP result
|
||||
///
|
||||
/// \return Result value
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResultValue sfSftpResult_getValue(const sfSftpResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the message of a SFTP result
|
||||
///
|
||||
/// \param result SFTP result
|
||||
///
|
||||
/// \return The result message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API const char* sfSftpResult_getMessage(const sfSftpResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destroy a SFTP path result
|
||||
///
|
||||
/// \param result SFTP path result to destroy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API void sfSftpPathResult_destroy(const sfSftpPathResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a SFTP path result is a success
|
||||
///
|
||||
/// \param result SFTP path result
|
||||
///
|
||||
/// \return True if the result is sfSftpSuccess
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API bool sfSftpPathResult_isOk(const sfSftpPathResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the value of a SFTP path result
|
||||
///
|
||||
/// \param result SFTP path result
|
||||
///
|
||||
/// \return Result value
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResultValue sfSftpPathResult_getValue(const sfSftpPathResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the message of a SFTP path result
|
||||
///
|
||||
/// \param result SFTP path result
|
||||
///
|
||||
/// \return The result message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API const char* sfSftpPathResult_getMessage(const sfSftpPathResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the path of a SFTP path result
|
||||
///
|
||||
/// \param result SFTP path result
|
||||
///
|
||||
/// \return The path, encoded in UTF-8
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API const char* sfSftpPathResult_getPath(const sfSftpPathResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destroy a SFTP attributes result
|
||||
///
|
||||
/// \param result SFTP attributes result to destroy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API void sfSftpAttributesResult_destroy(const sfSftpAttributesResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a SFTP attributes result is a success
|
||||
///
|
||||
/// \param result SFTP attributes result
|
||||
///
|
||||
/// \return True if the result is sfSftpSuccess
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API bool sfSftpAttributesResult_isOk(const sfSftpAttributesResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the value of a SFTP attributes result
|
||||
///
|
||||
/// \param result SFTP attributes result
|
||||
///
|
||||
/// \return Result value
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResultValue sfSftpAttributesResult_getValue(const sfSftpAttributesResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the message of a SFTP attributes result
|
||||
///
|
||||
/// \param result SFTP attributes result
|
||||
///
|
||||
/// \return The result message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API const char* sfSftpAttributesResult_getMessage(const sfSftpAttributesResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the attributes of a SFTP attributes result
|
||||
///
|
||||
/// The strings of the attributes stay valid until the
|
||||
/// result is destroyed.
|
||||
///
|
||||
/// \param result SFTP attributes result
|
||||
///
|
||||
/// \return The attributes
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpAttributes sfSftpAttributesResult_getAttributes(const sfSftpAttributesResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destroy a SFTP listing result
|
||||
///
|
||||
/// \param result SFTP listing result to destroy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API void sfSftpListingResult_destroy(const sfSftpListingResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if a SFTP listing result is a success
|
||||
///
|
||||
/// \param result SFTP listing result
|
||||
///
|
||||
/// \return True if the result is sfSftpSuccess
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API bool sfSftpListingResult_isOk(const sfSftpListingResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the value of a SFTP listing result
|
||||
///
|
||||
/// \param result SFTP listing result
|
||||
///
|
||||
/// \return Result value
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResultValue sfSftpListingResult_getValue(const sfSftpListingResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the message of a SFTP listing result
|
||||
///
|
||||
/// \param result SFTP listing result
|
||||
///
|
||||
/// \return The result message
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API const char* sfSftpListingResult_getMessage(const sfSftpListingResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the number of entries in a SFTP listing result
|
||||
///
|
||||
/// \param result SFTP listing result
|
||||
///
|
||||
/// \return Number of directory entries
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API size_t sfSftpListingResult_getCount(const sfSftpListingResult* result);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the attributes of an entry in a SFTP listing result
|
||||
///
|
||||
/// The strings of the attributes stay valid until the
|
||||
/// result is destroyed.
|
||||
///
|
||||
/// \param result SFTP listing result
|
||||
/// \param index Index of the entry to get
|
||||
///
|
||||
/// \return The attributes of the entry
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpAttributes sfSftpListingResult_getAttributes(const sfSftpListingResult* result, size_t index);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a new SFTP object
|
||||
///
|
||||
/// \return A new sfSftp object
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftp* sfSftp_create(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destroy an existing SFTP object
|
||||
///
|
||||
/// \param sftp SFTP object to destroy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API void sfSftp_destroy(const sfSftp* sftp);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Connect to the specified SFTP server
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param server Address of the server to connect to
|
||||
/// \param port Port used for the connection, the default SFTP port is 22
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of the connection attempt
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_connect(sfSftp* sftp, sfIpAddress server, unsigned short port, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Disconnect the connection with the server
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of disconnecting the connection with the server
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_disconnect(sfSftp* sftp, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get SSH session information
|
||||
///
|
||||
/// After connecting to the server and before actually
|
||||
/// logging in the SSH session information of the underlying
|
||||
/// connection will be available.
|
||||
///
|
||||
/// The session information contains among other things the
|
||||
/// public key identifying the remote host and the connection
|
||||
/// parameters such as encryption and compression used.
|
||||
///
|
||||
/// Relying on the user to check the authenticity of the host
|
||||
/// key is the typical method used to verify the connection
|
||||
/// to the legitimate host. If connection security is a high
|
||||
/// priority, examining the parameters and aborting the
|
||||
/// connection if any weak algorithms are used is also possible.
|
||||
///
|
||||
/// The pointers in the session information stay valid until
|
||||
/// the next call to this function or until the SFTP object
|
||||
/// is destroyed.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param info Session information to fill
|
||||
///
|
||||
/// \return True if the session information is available, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API bool sfSftp_getSessionInfo(const sfSftp* sftp, sfSftpSessionInfo* info);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Log in using a username and a password
|
||||
///
|
||||
/// Logging in is mandatory after connecting to the server.
|
||||
/// Users that are not logged in cannot perform any operation.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param name User name
|
||||
/// \param password Password
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of attempting to log in to the server
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_login(sfSftp* sftp, const char* name, const char* password, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Log in using a public/private key pair
|
||||
///
|
||||
/// Logging in is mandatory after connecting to the server.
|
||||
/// Users that are not logged in cannot perform any operation.
|
||||
///
|
||||
/// The public and private key data should be provided in PEM
|
||||
/// format. Even though it is technically possible to derive
|
||||
/// the public key from the private key, due to backend
|
||||
/// limitations, providing a pre-generated public key as well
|
||||
/// is necessary for this function to be able to succeed.
|
||||
///
|
||||
/// If the private key is not protected by a passphrase the
|
||||
/// passphrase should be set to the empty string or NULL.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param name User name
|
||||
/// \param publicKeyData Public key data
|
||||
/// \param publicKeyLength Public key data length
|
||||
/// \param privateKeyData Private key data
|
||||
/// \param privateKeyLength Private key data length
|
||||
/// \param privateKeyPassphrase Private key passphrase, NULL terminated
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of attempting to log in to the server
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_loginWithKey(
|
||||
sfSftp* sftp,
|
||||
const char* name,
|
||||
const char* publicKeyData,
|
||||
size_t publicKeyLength,
|
||||
const char* privateKeyData,
|
||||
size_t privateKeyLength,
|
||||
const char* privateKeyPassphrase,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Resolve a remote path into an absolute remote path
|
||||
///
|
||||
/// Paths can contain links and other reserved path identifiers
|
||||
/// such as . and .. referring to the current directory and
|
||||
/// parent directory respectively. This function determines
|
||||
/// the absolute path, which does not contain links or . or ..
|
||||
///
|
||||
/// Resolving "." will return the absolute path to the current
|
||||
/// working directory of the user after logging in to the SFTP
|
||||
/// server.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path to convert into an absolute path, encoded in UTF-8
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of converting the path into an absolute path
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpPathResult* sfSftp_resolvePath(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current working directory on the server
|
||||
///
|
||||
/// This is an alias for calling sfSftp_resolvePath with ".".
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of getting the current working directory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpPathResult* sfSftp_getWorkingDirectory(sfSftp* sftp, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the attributes of a remote file or directory
|
||||
///
|
||||
/// Depending on whether \a path refers to a file or directory,
|
||||
/// the attributes can contain e.g. the type of file, the file
|
||||
/// owner, group, file size, modification and access times.
|
||||
///
|
||||
/// If links are not to be followed, \a followLinks can be set
|
||||
/// to false. In this case the attributes of the link itself
|
||||
/// will be returned.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path to the remote file or directory whose attributes to get, encoded in UTF-8
|
||||
/// \param followLinks True to follow links, false to return attributes of the link itself
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of getting the attributes
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpAttributesResult* sfSftp_getAttributes(
|
||||
sfSftp* sftp,
|
||||
const char* path,
|
||||
bool followLinks,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the contents of the given directory
|
||||
///
|
||||
/// This function retrieves the sub-directories and files
|
||||
/// contained in the given directory. It is not recursive.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path of the directory whose contents to list, encoded in UTF-8
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of getting the contents of the given directory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpListingResult* sfSftp_getDirectoryListing(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a new directory
|
||||
///
|
||||
/// The new directory is created as a child of the current
|
||||
/// working directory.
|
||||
///
|
||||
/// A common permissions value is 0755 (rwxr-xr-x).
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path of the directory to create, encoded in UTF-8
|
||||
/// \param permissions POSIX permissions of the directory to create
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of creating the directory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_createDirectory(sfSftp* sftp,
|
||||
const char* path,
|
||||
uint32_t permissions,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Remove an existing directory
|
||||
///
|
||||
/// Use this function with caution, the directory will
|
||||
/// be removed permanently!
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path of the directory to remove, encoded in UTF-8
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of removing the directory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_deleteDirectory(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Rename an existing file or directory
|
||||
///
|
||||
/// In POSIX renaming and moving are synonymous. If you want
|
||||
/// to move a file or directory from one place to another
|
||||
/// you rename it from an old to a new path.
|
||||
///
|
||||
/// If a file exists at the specified new path, depending
|
||||
/// on whether \a overwrite is set to true, the rename operation
|
||||
/// will overwrite it or not. Non-empty directories cannot be
|
||||
/// overwritten by this operation.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param oldPath Old path to the file or directory, encoded in UTF-8
|
||||
/// \param newPath New path to the file or directory, encoded in UTF-8
|
||||
/// \param overwrite True to allow overwriting a file that exists at \a newPath
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of the operation
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_rename(
|
||||
sfSftp* sftp,
|
||||
const char* oldPath,
|
||||
const char* newPath,
|
||||
bool overwrite,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Remove an existing file
|
||||
///
|
||||
/// Use this function with caution, the file will be
|
||||
/// removed permanently!
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param path Path to the file to remove, encoded in UTF-8
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of removing the file
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_deleteFile(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Download a file from the server
|
||||
///
|
||||
/// The file data is transferred in sequential blocks. For
|
||||
/// every block of data transferred, the provided callback
|
||||
/// is called.
|
||||
///
|
||||
/// The function returns once all the data in the remote file
|
||||
/// has been transferred or an error occurs or the function
|
||||
/// times out.
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param remotePath Path of the remote file whose data to download, encoded in UTF-8
|
||||
/// \param callback Callback to be called for every available data block
|
||||
/// \param userData User data that will be passed to the callback
|
||||
/// \param offset Byte offset into the remote file at which reading should start
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of downloading the file
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_download(
|
||||
sfSftp* sftp,
|
||||
const char* remotePath,
|
||||
sfSftpDownloadCallback callback,
|
||||
void* userData,
|
||||
uint64_t offset,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Upload a file to the server
|
||||
///
|
||||
/// The file data is transferred in sequential blocks. Every
|
||||
/// time the function wants to send a new block of data the
|
||||
/// provided callback is called.
|
||||
///
|
||||
/// The function returns once all the data has been sent or
|
||||
/// an error occurs or the function times out.
|
||||
///
|
||||
/// If a file does not exist at the remote path yet, it will
|
||||
/// be created with the provided permissions. A common
|
||||
/// permissions value is 0644 (rw-r--r--).
|
||||
///
|
||||
/// \param sftp SFTP object
|
||||
/// \param remotePath Path of the remote file in which to upload the data, encoded in UTF-8
|
||||
/// \param callback Callback to be called for every data block to send
|
||||
/// \param userData User data that will be passed to the callback
|
||||
/// \param permissions POSIX permissions of the remote file if it has to be created
|
||||
/// \param truncate True to truncate the remote file if it already exists
|
||||
/// \param append True to append to the remote file if it already exists
|
||||
/// \param offset Byte offset into the remote file at which writing should start
|
||||
/// \param timeout Maximum time to wait, optionally a predicate can be provided for more fine-grained control
|
||||
///
|
||||
/// \return Result of uploading the file
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
CSFML_NETWORK_API sfSftpResult* sfSftp_upload(
|
||||
sfSftp* sftp,
|
||||
const char* remotePath,
|
||||
sfSftpUploadCallback callback,
|
||||
void* userData,
|
||||
uint32_t permissions,
|
||||
bool truncate,
|
||||
bool append,
|
||||
uint64_t offset,
|
||||
sfTimeoutWithPredicate timeout);
|
||||
@@ -37,6 +37,11 @@ typedef struct sfHttpRequest sfHttpRequest;
|
||||
typedef struct sfHttpResponse sfHttpResponse;
|
||||
typedef struct sfHttp sfHttp;
|
||||
typedef struct sfPacket sfPacket;
|
||||
typedef struct sfSftpAttributesResult sfSftpAttributesResult;
|
||||
typedef struct sfSftpListingResult sfSftpListingResult;
|
||||
typedef struct sfSftpPathResult sfSftpPathResult;
|
||||
typedef struct sfSftpResult sfSftpResult;
|
||||
typedef struct sfSftp sfSftp;
|
||||
typedef struct sfSocketSelector sfSocketSelector;
|
||||
typedef struct sfTcpListener sfTcpListener;
|
||||
typedef struct sfTcpSocket sfTcpSocket;
|
||||
|
||||
@@ -19,6 +19,9 @@ set(SRC
|
||||
${SRCROOT}/Packet.cpp
|
||||
${SRCROOT}/PacketStruct.hpp
|
||||
${INCROOT}/Packet.h
|
||||
${SRCROOT}/Sftp.cpp
|
||||
${SRCROOT}/SftpStruct.hpp
|
||||
${INCROOT}/Sftp.h
|
||||
${SRCROOT}/SocketSelector.cpp
|
||||
${SRCROOT}/SocketSelectorStruct.hpp
|
||||
${INCROOT}/SocketSelector.h
|
||||
|
||||
@@ -0,0 +1,547 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2026 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <CSFML/Network/ConvertIpAddress.hpp>
|
||||
#include <CSFML/Network/Sftp.h>
|
||||
#include <CSFML/Network/SftpStruct.hpp>
|
||||
#include <CSFML/System/ConvertTimeoutWithPredicate.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::filesystem::path toPath(const char* path)
|
||||
{
|
||||
return std::filesystem::u8path(path ? path : "");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::string fromPath(const std::filesystem::path& path)
|
||||
{
|
||||
const auto string = path.u8string();
|
||||
return {string.begin(), string.end()};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpFileType convertFileType(std::filesystem::file_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case std::filesystem::file_type::none:
|
||||
return sfSftpFileNone;
|
||||
case std::filesystem::file_type::not_found:
|
||||
return sfSftpFileNotFound;
|
||||
case std::filesystem::file_type::regular:
|
||||
return sfSftpFileRegular;
|
||||
case std::filesystem::file_type::directory:
|
||||
return sfSftpFileDirectory;
|
||||
case std::filesystem::file_type::symlink:
|
||||
return sfSftpFileSymlink;
|
||||
case std::filesystem::file_type::block:
|
||||
return sfSftpFileBlock;
|
||||
case std::filesystem::file_type::character:
|
||||
return sfSftpFileCharacter;
|
||||
case std::filesystem::file_type::fifo:
|
||||
return sfSftpFileFifo;
|
||||
case std::filesystem::file_type::socket:
|
||||
return sfSftpFileSocket;
|
||||
default:
|
||||
return sfSftpFileUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// SFML stores the seconds since the Unix epoch in the file time
|
||||
[[nodiscard]] std::int64_t convertFileTime(std::filesystem::file_time_type time)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpAttributes convertAttributes(const sf::Sftp::Attributes& attributes, const std::string& path)
|
||||
{
|
||||
sfSftpAttributes result{};
|
||||
result.path = path.c_str();
|
||||
|
||||
if (attributes.type)
|
||||
{
|
||||
result.hasType = true;
|
||||
result.type = convertFileType(*attributes.type);
|
||||
}
|
||||
|
||||
if (attributes.size)
|
||||
{
|
||||
result.hasSize = true;
|
||||
result.size = *attributes.size;
|
||||
}
|
||||
|
||||
if (attributes.permissions)
|
||||
{
|
||||
result.hasPermissions = true;
|
||||
result.permissions = static_cast<std::uint32_t>(*attributes.permissions);
|
||||
}
|
||||
|
||||
if (attributes.userId)
|
||||
{
|
||||
result.hasUserId = true;
|
||||
result.userId = *attributes.userId;
|
||||
}
|
||||
|
||||
if (attributes.groupId)
|
||||
{
|
||||
result.hasGroupId = true;
|
||||
result.groupId = *attributes.groupId;
|
||||
}
|
||||
|
||||
if (attributes.accessTime)
|
||||
{
|
||||
result.hasAccessTime = true;
|
||||
result.accessTime = convertFileTime(*attributes.accessTime);
|
||||
}
|
||||
|
||||
if (attributes.modificationTime)
|
||||
{
|
||||
result.hasModificationTime = true;
|
||||
result.modificationTime = convertFileTime(*attributes.modificationTime);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpResult* createResult(const sf::Sftp::Result& result)
|
||||
{
|
||||
return new sfSftpResult{result};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpPathResult* createResult(const sf::Sftp::PathResult& result)
|
||||
{
|
||||
return new sfSftpPathResult{result, fromPath(result.getPath())};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpAttributesResult* createResult(const sf::Sftp::AttributesResult& result)
|
||||
{
|
||||
return new sfSftpAttributesResult{result, fromPath(result.getAttributes().path)};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] sfSftpListingResult* createResult(const sf::Sftp::ListingResult& result)
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
paths.reserve(result.getListing().size());
|
||||
for (const auto& attributes : result.getListing())
|
||||
paths.push_back(fromPath(attributes.path));
|
||||
|
||||
return new sfSftpListingResult{result, std::move(paths)};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void sfSftpResult_destroy(const sfSftpResult* result)
|
||||
{
|
||||
delete result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool sfSftpResult_isOk(const sfSftpResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->isOk();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResultValue sfSftpResult_getValue(const sfSftpResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return static_cast<sfSftpResultValue>(result->getValue());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const char* sfSftpResult_getMessage(const sfSftpResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->getMessage().c_str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void sfSftpPathResult_destroy(const sfSftpPathResult* result)
|
||||
{
|
||||
delete result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool sfSftpPathResult_isOk(const sfSftpPathResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->isOk();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResultValue sfSftpPathResult_getValue(const sfSftpPathResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return static_cast<sfSftpResultValue>(result->getValue());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const char* sfSftpPathResult_getMessage(const sfSftpPathResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->getMessage().c_str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const char* sfSftpPathResult_getPath(const sfSftpPathResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->Path.c_str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void sfSftpAttributesResult_destroy(const sfSftpAttributesResult* result)
|
||||
{
|
||||
delete result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool sfSftpAttributesResult_isOk(const sfSftpAttributesResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->isOk();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResultValue sfSftpAttributesResult_getValue(const sfSftpAttributesResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return static_cast<sfSftpResultValue>(result->getValue());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const char* sfSftpAttributesResult_getMessage(const sfSftpAttributesResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->getMessage().c_str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpAttributes sfSftpAttributesResult_getAttributes(const sfSftpAttributesResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return convertAttributes(result->getAttributes(), result->Path);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void sfSftpListingResult_destroy(const sfSftpListingResult* result)
|
||||
{
|
||||
delete result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool sfSftpListingResult_isOk(const sfSftpListingResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->isOk();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResultValue sfSftpListingResult_getValue(const sfSftpListingResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return static_cast<sfSftpResultValue>(result->getValue());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const char* sfSftpListingResult_getMessage(const sfSftpListingResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->getMessage().c_str();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
size_t sfSftpListingResult_getCount(const sfSftpListingResult* result)
|
||||
{
|
||||
assert(result);
|
||||
return result->getListing().size();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpAttributes sfSftpListingResult_getAttributes(const sfSftpListingResult* result, size_t index)
|
||||
{
|
||||
assert(result);
|
||||
assert(index < result->getListing().size());
|
||||
return convertAttributes(result->getListing()[index], result->Paths[index]);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftp* sfSftp_create()
|
||||
{
|
||||
return new sfSftp;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void sfSftp_destroy(const sfSftp* sftp)
|
||||
{
|
||||
delete sftp;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_connect(sfSftp* sftp, sfIpAddress server, unsigned short port, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
|
||||
const auto address = convertIpAddress(server);
|
||||
if (!address)
|
||||
return createResult(sf::Sftp::Result(sf::Sftp::Result::Value::Error, "Invalid server address"));
|
||||
|
||||
return createResult(sftp->connect(*address, port, convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_disconnect(sfSftp* sftp, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->disconnect(convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool sfSftp_getSessionInfo(const sfSftp* sftp, sfSftpSessionInfo* info)
|
||||
{
|
||||
assert(sftp);
|
||||
assert(info);
|
||||
|
||||
sftp->SessionInfo = sftp->getSessionInfo();
|
||||
if (!sftp->SessionInfo)
|
||||
return false;
|
||||
|
||||
const auto& sessionInfo = *sftp->SessionInfo;
|
||||
const auto& hostKey = sessionInfo.hostKey;
|
||||
|
||||
*info = {};
|
||||
info->hostKeyType = static_cast<sfSftpHostKeyType>(hostKey.type);
|
||||
info->hostKeyData = reinterpret_cast<const std::uint8_t*>(hostKey.data.data());
|
||||
info->hostKeySize = hostKey.data.size();
|
||||
std::transform(hostKey.sha1.begin(),
|
||||
hostKey.sha1.end(),
|
||||
info->hostKeySha1,
|
||||
[](std::byte b) { return std::to_integer<std::uint8_t>(b); });
|
||||
std::transform(hostKey.sha256.begin(),
|
||||
hostKey.sha256.end(),
|
||||
info->hostKeySha256,
|
||||
[](std::byte b) { return std::to_integer<std::uint8_t>(b); });
|
||||
info->keyExchangeAlgorithm = sessionInfo.keyExchangeAlgorithm.c_str();
|
||||
info->hostKeyAlgorithm = sessionInfo.hostKeyAlgorithm.c_str();
|
||||
info->clientToServerEncryptionAlgorithm = sessionInfo.clientToServerEncryptionAlgorithm.c_str();
|
||||
info->serverToClientEncryptionAlgorithm = sessionInfo.serverToClientEncryptionAlgorithm.c_str();
|
||||
info->clientToServerMacAlgorithm = sessionInfo.clientToServerMacAlgorithm.c_str();
|
||||
info->serverToClientMacAlgorithm = sessionInfo.serverToClientMacAlgorithm.c_str();
|
||||
info->clientToServerCompressionAlgorithm = sessionInfo.clientToServerCompressionAlgorithm.c_str();
|
||||
info->serverToClientCompressionAlgorithm = sessionInfo.serverToClientCompressionAlgorithm.c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_login(sfSftp* sftp, const char* name, const char* password, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->login(name ? name : "", password ? password : "", convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_loginWithKey(
|
||||
sfSftp* sftp,
|
||||
const char* name,
|
||||
const char* publicKeyData,
|
||||
size_t publicKeyLength,
|
||||
const char* privateKeyData,
|
||||
size_t privateKeyLength,
|
||||
const char* privateKeyPassphrase,
|
||||
sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
assert(publicKeyData);
|
||||
assert(privateKeyData);
|
||||
return createResult(
|
||||
sftp->login(name ? name : "",
|
||||
publicKeyData,
|
||||
publicKeyLength,
|
||||
privateKeyData,
|
||||
privateKeyLength,
|
||||
privateKeyPassphrase ? privateKeyPassphrase : "",
|
||||
convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpPathResult* sfSftp_resolvePath(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->resolvePath(toPath(path), convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpPathResult* sfSftp_getWorkingDirectory(sfSftp* sftp, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->getWorkingDirectory(convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpAttributesResult* sfSftp_getAttributes(sfSftp* sftp, const char* path, bool followLinks, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->getAttributes(toPath(path), followLinks, convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpListingResult* sfSftp_getDirectoryListing(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->getDirectoryListing(toPath(path), convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_createDirectory(sfSftp* sftp, const char* path, uint32_t permissions, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->createDirectory(toPath(path),
|
||||
static_cast<std::filesystem::perms>(permissions),
|
||||
convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_deleteDirectory(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->deleteDirectory(toPath(path), convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_rename(sfSftp* sftp, const char* oldPath, const char* newPath, bool overwrite, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->rename(toPath(oldPath), toPath(newPath), overwrite, convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_deleteFile(sfSftp* sftp, const char* path, sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
return createResult(sftp->deleteFile(toPath(path), convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_download(sfSftp* sftp,
|
||||
const char* remotePath,
|
||||
sfSftpDownloadCallback callback,
|
||||
void* userData,
|
||||
uint64_t offset,
|
||||
sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
assert(callback);
|
||||
return createResult(sftp->download(
|
||||
toPath(remotePath),
|
||||
[callback, userData](const void* data, std::size_t size) { return callback(data, size, userData); },
|
||||
offset,
|
||||
convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
sfSftpResult* sfSftp_upload(
|
||||
sfSftp* sftp,
|
||||
const char* remotePath,
|
||||
sfSftpUploadCallback callback,
|
||||
void* userData,
|
||||
uint32_t permissions,
|
||||
bool truncate,
|
||||
bool append,
|
||||
uint64_t offset,
|
||||
sfTimeoutWithPredicate timeout)
|
||||
{
|
||||
assert(sftp);
|
||||
assert(callback);
|
||||
return createResult(sftp->upload(
|
||||
toPath(remotePath),
|
||||
[callback, userData](void* data, std::size_t& size) { return callback(data, &size, userData); },
|
||||
static_cast<std::filesystem::perms>(permissions),
|
||||
truncate,
|
||||
append,
|
||||
offset,
|
||||
convertTimeoutWithPredicate(timeout)));
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2026 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Network/Sftp.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Internal structure of sfSftp
|
||||
////////////////////////////////////////////////////////////
|
||||
struct sfSftp : sf::Sftp
|
||||
{
|
||||
mutable std::optional<sf::Sftp::SessionInfo> SessionInfo;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Internal structure of sfSftpResult
|
||||
////////////////////////////////////////////////////////////
|
||||
struct sfSftpResult : sf::Sftp::Result
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Internal structure of sfSftpPathResult
|
||||
////////////////////////////////////////////////////////////
|
||||
struct sfSftpPathResult : sf::Sftp::PathResult
|
||||
{
|
||||
std::string Path;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Internal structure of sfSftpAttributesResult
|
||||
////////////////////////////////////////////////////////////
|
||||
struct sfSftpAttributesResult : sf::Sftp::AttributesResult
|
||||
{
|
||||
std::string Path;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Internal structure of sfSftpListingResult
|
||||
////////////////////////////////////////////////////////////
|
||||
struct sfSftpListingResult : sf::Sftp::ListingResult
|
||||
{
|
||||
std::vector<std::string> Paths;
|
||||
};
|
||||
@@ -70,6 +70,7 @@ add_executable(test-csfml-network
|
||||
Network/Ftp.test.cpp
|
||||
Network/Http.test.cpp
|
||||
Network/IpAddress.test.cpp
|
||||
Network/Sftp.test.cpp
|
||||
Network/SocketSelector.test.cpp
|
||||
Network/SocketStatus.test.cpp
|
||||
Network/TcpSocket.test.cpp
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#include <CSFML/Network/Sftp.h>
|
||||
|
||||
#include <SFML/Network/Sftp.hpp>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("[Network] sfSftp")
|
||||
{
|
||||
SECTION("sfSftpResultValue")
|
||||
{
|
||||
STATIC_CHECK(sfSftpSuccess == static_cast<int>(sf::Sftp::Result::Value::Success));
|
||||
STATIC_CHECK(sfSftpDisconnected == static_cast<int>(sf::Sftp::Result::Value::Disconnected));
|
||||
STATIC_CHECK(sfSftpTimeout == static_cast<int>(sf::Sftp::Result::Value::Timeout));
|
||||
STATIC_CHECK(sfSftpRefused == static_cast<int>(sf::Sftp::Result::Value::Refused));
|
||||
STATIC_CHECK(sfSftpError == static_cast<int>(sf::Sftp::Result::Value::Error));
|
||||
STATIC_CHECK(sfSftpBannerReceive == static_cast<int>(sf::Sftp::Result::Value::BannerReceive));
|
||||
STATIC_CHECK(sfSftpBannerSend == static_cast<int>(sf::Sftp::Result::Value::BannerSend));
|
||||
STATIC_CHECK(sfSftpInvalidMac == static_cast<int>(sf::Sftp::Result::Value::InvalidMac));
|
||||
STATIC_CHECK(sfSftpAllocationFailure == static_cast<int>(sf::Sftp::Result::Value::AllocationFailure));
|
||||
STATIC_CHECK(sfSftpSocketSend == static_cast<int>(sf::Sftp::Result::Value::SocketSend));
|
||||
STATIC_CHECK(sfSftpKeyExchangeFailure == static_cast<int>(sf::Sftp::Result::Value::KeyExchangeFailure));
|
||||
STATIC_CHECK(sfSftpHostKeyInitialization == static_cast<int>(sf::Sftp::Result::Value::HostKeyInitialization));
|
||||
STATIC_CHECK(sfSftpHostKeySign == static_cast<int>(sf::Sftp::Result::Value::HostKeySign));
|
||||
STATIC_CHECK(sfSftpDecryptError == static_cast<int>(sf::Sftp::Result::Value::DecryptError));
|
||||
STATIC_CHECK(sfSftpProtocolError == static_cast<int>(sf::Sftp::Result::Value::ProtocolError));
|
||||
STATIC_CHECK(sfSftpPasswordExpired == static_cast<int>(sf::Sftp::Result::Value::PasswordExpired));
|
||||
STATIC_CHECK(sfSftpFileError == static_cast<int>(sf::Sftp::Result::Value::FileError));
|
||||
STATIC_CHECK(sfSftpMethodNone == static_cast<int>(sf::Sftp::Result::Value::MethodNone));
|
||||
STATIC_CHECK(sfSftpAuthenticationFailed == static_cast<int>(sf::Sftp::Result::Value::AuthenticationFailed));
|
||||
STATIC_CHECK(sfSftpPublicKeyUnverified == static_cast<int>(sf::Sftp::Result::Value::PublicKeyUnverified));
|
||||
STATIC_CHECK(sfSftpChannelOutOfOrder == static_cast<int>(sf::Sftp::Result::Value::ChannelOutOfOrder));
|
||||
STATIC_CHECK(sfSftpChannelFailure == static_cast<int>(sf::Sftp::Result::Value::ChannelFailure));
|
||||
STATIC_CHECK(sfSftpChannelRequestDenied == static_cast<int>(sf::Sftp::Result::Value::ChannelRequestDenied));
|
||||
STATIC_CHECK(sfSftpChannelUnknown == static_cast<int>(sf::Sftp::Result::Value::ChannelUnknown));
|
||||
STATIC_CHECK(sfSftpChannelWindowExceeded == static_cast<int>(sf::Sftp::Result::Value::ChannelWindowExceeded));
|
||||
STATIC_CHECK(sfSftpChannelPacketExceeded == static_cast<int>(sf::Sftp::Result::Value::ChannelPacketExceeded));
|
||||
STATIC_CHECK(sfSftpChannelClosed == static_cast<int>(sf::Sftp::Result::Value::ChannelClosed));
|
||||
STATIC_CHECK(sfSftpChannelEofSent == static_cast<int>(sf::Sftp::Result::Value::ChannelEofSent));
|
||||
STATIC_CHECK(sfSftpScpProtocol == static_cast<int>(sf::Sftp::Result::Value::ScpProtocol));
|
||||
STATIC_CHECK(sfSftpZlibError == static_cast<int>(sf::Sftp::Result::Value::ZlibError));
|
||||
STATIC_CHECK(sfSftpRequestDenied == static_cast<int>(sf::Sftp::Result::Value::RequestDenied));
|
||||
STATIC_CHECK(sfSftpMethodNotSupported == static_cast<int>(sf::Sftp::Result::Value::MethodNotSupported));
|
||||
STATIC_CHECK(sfSftpInvalidData == static_cast<int>(sf::Sftp::Result::Value::InvalidData));
|
||||
STATIC_CHECK(sfSftpPublicKeyProtocol == static_cast<int>(sf::Sftp::Result::Value::PublicKeyProtocol));
|
||||
STATIC_CHECK(sfSftpBufferTooSmall == static_cast<int>(sf::Sftp::Result::Value::BufferTooSmall));
|
||||
STATIC_CHECK(sfSftpBadUse == static_cast<int>(sf::Sftp::Result::Value::BadUse));
|
||||
STATIC_CHECK(sfSftpCompressError == static_cast<int>(sf::Sftp::Result::Value::CompressError));
|
||||
STATIC_CHECK(sfSftpOutOfBoundary == static_cast<int>(sf::Sftp::Result::Value::OutOfBoundary));
|
||||
STATIC_CHECK(sfSftpAgentProtocol == static_cast<int>(sf::Sftp::Result::Value::AgentProtocol));
|
||||
STATIC_CHECK(sfSftpSocketRecv == static_cast<int>(sf::Sftp::Result::Value::SocketRecv));
|
||||
STATIC_CHECK(sfSftpEncryptError == static_cast<int>(sf::Sftp::Result::Value::EncryptError));
|
||||
STATIC_CHECK(sfSftpBadSocket == static_cast<int>(sf::Sftp::Result::Value::BadSocket));
|
||||
STATIC_CHECK(sfSftpKnownHosts == static_cast<int>(sf::Sftp::Result::Value::KnownHosts));
|
||||
STATIC_CHECK(sfSftpChannelWindowFull == static_cast<int>(sf::Sftp::Result::Value::ChannelWindowFull));
|
||||
STATIC_CHECK(sfSftpKeyFileAuthenticationFailed ==
|
||||
static_cast<int>(sf::Sftp::Result::Value::KeyFileAuthenticationFailed));
|
||||
STATIC_CHECK(sfSftpEndOfFile == static_cast<int>(sf::Sftp::Result::Value::EndOfFile));
|
||||
STATIC_CHECK(sfSftpNoSuchFile == static_cast<int>(sf::Sftp::Result::Value::NoSuchFile));
|
||||
STATIC_CHECK(sfSftpPermissionDenied == static_cast<int>(sf::Sftp::Result::Value::PermissionDenied));
|
||||
STATIC_CHECK(sfSftpFailure == static_cast<int>(sf::Sftp::Result::Value::Failure));
|
||||
STATIC_CHECK(sfSftpBadMessage == static_cast<int>(sf::Sftp::Result::Value::BadMessage));
|
||||
STATIC_CHECK(sfSftpNoConnection == static_cast<int>(sf::Sftp::Result::Value::NoConnection));
|
||||
STATIC_CHECK(sfSftpConnectionLost == static_cast<int>(sf::Sftp::Result::Value::ConnectionLost));
|
||||
STATIC_CHECK(sfSftpOperationUnsupported == static_cast<int>(sf::Sftp::Result::Value::OperationUnsupported));
|
||||
STATIC_CHECK(sfSftpInvalidHandle == static_cast<int>(sf::Sftp::Result::Value::InvalidHandle));
|
||||
STATIC_CHECK(sfSftpNoSuchPath == static_cast<int>(sf::Sftp::Result::Value::NoSuchPath));
|
||||
STATIC_CHECK(sfSftpFileAlreadyExists == static_cast<int>(sf::Sftp::Result::Value::FileAlreadyExists));
|
||||
STATIC_CHECK(sfSftpWriteProtect == static_cast<int>(sf::Sftp::Result::Value::WriteProtect));
|
||||
STATIC_CHECK(sfSftpNoMedia == static_cast<int>(sf::Sftp::Result::Value::NoMedia));
|
||||
STATIC_CHECK(sfSftpNoSpaceOnFileSystem == static_cast<int>(sf::Sftp::Result::Value::NoSpaceOnFileSystem));
|
||||
STATIC_CHECK(sfSftpQuotaExceeded == static_cast<int>(sf::Sftp::Result::Value::QuotaExceeded));
|
||||
STATIC_CHECK(sfSftpUnknownPrincipal == static_cast<int>(sf::Sftp::Result::Value::UnknownPrincipal));
|
||||
STATIC_CHECK(sfSftpLockConflict == static_cast<int>(sf::Sftp::Result::Value::LockConflict));
|
||||
STATIC_CHECK(sfSftpDirectoryNotEmpty == static_cast<int>(sf::Sftp::Result::Value::DirectoryNotEmpty));
|
||||
STATIC_CHECK(sfSftpNotADirectory == static_cast<int>(sf::Sftp::Result::Value::NotADirectory));
|
||||
STATIC_CHECK(sfSftpInvalidFilename == static_cast<int>(sf::Sftp::Result::Value::InvalidFilename));
|
||||
STATIC_CHECK(sfSftpLinkLoop == static_cast<int>(sf::Sftp::Result::Value::LinkLoop));
|
||||
STATIC_CHECK(sfSftpSftpError == static_cast<int>(sf::Sftp::Result::Value::SftpError));
|
||||
}
|
||||
|
||||
SECTION("sfSftpHostKeyType")
|
||||
{
|
||||
using HostKeyType = sf::Sftp::SessionInfo::HostKey::Type;
|
||||
STATIC_CHECK(sfSftpHostKeyUnknown == static_cast<int>(HostKeyType::Unknown));
|
||||
STATIC_CHECK(sfSftpHostKeyRsa == static_cast<int>(HostKeyType::Rsa));
|
||||
STATIC_CHECK(sfSftpHostKeyDsa == static_cast<int>(HostKeyType::Dsa));
|
||||
STATIC_CHECK(sfSftpHostKeyEcdsa256 == static_cast<int>(HostKeyType::Ecdsa256));
|
||||
STATIC_CHECK(sfSftpHostKeyEcdsa384 == static_cast<int>(HostKeyType::Ecdsa384));
|
||||
STATIC_CHECK(sfSftpHostKeyEcdsa521 == static_cast<int>(HostKeyType::Ecdsa521));
|
||||
STATIC_CHECK(sfSftpHostKeyEd25519 == static_cast<int>(HostKeyType::Ed25519));
|
||||
}
|
||||
|
||||
SECTION("Unconnected")
|
||||
{
|
||||
sfSftp* sftp = sfSftp_create();
|
||||
sfSftpSessionInfo info{};
|
||||
CHECK(!sfSftp_getSessionInfo(sftp, &info));
|
||||
|
||||
sfSftpResult* result = sfSftp_connect(sftp, sfIpAddress_None, 22, {});
|
||||
CHECK(!sfSftpResult_isOk(result));
|
||||
CHECK(sfSftpResult_getValue(result) == sfSftpError);
|
||||
sfSftpResult_destroy(result);
|
||||
|
||||
sfSftp_destroy(sftp);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user