A comprehensive FTP client library for Ring with support for FTP/FTPS file transfers, directory management, and progress tracking.
- Full FTP client functionality (upload, download, list, delete, rename, etc.)
- Support for both passive and active transfer modes
- SSL/TLS support for secure FTPS connections
- Progress callbacks for tracking file transfers
- Directory management (create, remove, list)
- Custom FTP command execution
- Configurable timeouts and verbose debugging
- Cross-platform support (Windows, Linux, macOS, FreeBSD)
This package can be installed using the Ring Package Manager (RingPM):
ringpm install ftp from ysdragon
First, load the library in your Ring script:
load "ftp.ring"To connect to an FTP server and upload a file:
ftp = new FTP()
try
ftp {
setHost("ftp.example.com", 21)
setCredentials("username", "password")
connect()
upload("local_file.txt", "remote_file.txt")
close()
}
? "Upload successful!"
catch
? "Error: " + ftp.getError()
endTo download a file from an FTP server:
ftp = new FTP()
try
ftp {
setHost("ftp.example.com", 21)
setCredentials("username", "password")
connect()
download("remote_file.txt", "local_file.txt")
close()
}
? "Download complete!"
catch
? "Error: " + ftp.getError()
endftp = new FTP()
try
ftp {
setHost("ftp.example.com", 21)
setCredentials("username", "password")
connect()
# List directory contents
listing = listDir("/")
? listing
# Create a directory
mkdir("/new_folder")
# Remove a directory
rmdir("/old_folder")
# Delete a file
delete("/unwanted_file.txt")
# Rename a file
rename("/old_name.txt", "/new_name.txt")
# Get file size
size = getFileSize("/remote_file.txt")
? "File size: " + size + " bytes"
close()
}
catch
? "Error: " + ftp.getError()
endTrack upload/download progress with callbacks:
ftp = new FTP()
try
ftp {
setHost("ftp.example.com", 21)
setCredentials("username", "password")
setProgressCallback(:myProgressCallback)
connect()
upload("large_file.zip", "large_file.zip")
close()
}
catch
? "Error: " + ftp.getError()
end
func myProgressCallback(download_total, download_now, upload_total, upload_now)
if upload_total > 0
percent = (upload_now / upload_total) * 100
? "Upload Progress: " + percent + "%"
ok
if download_total > 0
percent = (download_now / download_total) * 100
? "Download Progress: " + percent + "%"
okftp = new FTP()
try
ftp {
setHost("ftp.example.com", 21)
setCredentials("username", "password")
# Set passive mode (default)
setMode(FTP_MODE_PASSIVE)
# Enable SSL/TLS for secure transfers
setSSL(FTP_SSL_ALL, 1) # Verify SSL certificate
# Set timeouts (transfer timeout, connection timeout in seconds)
setTimeout(60, 30)
# Enable verbose debugging output
setVerbose(1)
connect()
# Execute custom FTP command
response = executeCommand("PWD")
? "Current directory: " + response
close()
}
catch
? "Error: " + ftp.getError()
end- FTP_MODE_PASSIVE: Passive mode (default, recommended for most firewalls)
- FTP_MODE_ACTIVE: Active mode
- FTP_SSL_NONE: No SSL/TLS (plain FTP)
- FTP_SSL_TRY: Try SSL/TLS, fallback to plain FTP if unavailable
- FTP_SSL_CONTROL: SSL/TLS for control connection only
- FTP_SSL_ALL: SSL/TLS for both control and data connections (FTPS)
- Configure both transfer and connection timeouts using
setTimeout(transfer_seconds, connect_seconds) - Default timeout values are used if not specified
Sets the FTP server host and port.
Parameters:
host(string): The FTP server hostname or IP addressport(number): The FTP server port (usually 21)
Returns: self (for method chaining)
Example:
ftp.setHost("ftp.example.com", 21)Sets the username and password for authentication.
Parameters:
username(string): FTP usernamepassword(string): FTP password
Returns: self (for method chaining)
Example:
ftp.setCredentials("myuser", "mypass")Sets the transfer mode (passive or active).
Parameters:
mode(number): FTP_MODE_PASSIVE or FTP_MODE_ACTIVE
Returns: self (for method chaining)
Example:
ftp.setMode(FTP_MODE_PASSIVE)Configures SSL/TLS settings.
Parameters:
sslMode(number): FTP_SSL_NONE, FTP_SSL_TRY, FTP_SSL_CONTROL, or FTP_SSL_ALLverify(number): 1 to verify SSL certificate, 0 to skip verification
Returns: self (for method chaining)
Example:
ftp.setSSL(FTP_SSL_ALL, 1)Sets operation and connection timeouts.
Parameters:
timeout(number): Transfer timeout in secondsconnectTimeout(number): Connection timeout in seconds
Returns: self (for method chaining)
Example:
ftp.setTimeout(60, 30)Enables or disables verbose debugging output.
Parameters:
verbose(number): 1 to enable, 0 to disable
Returns: self (for method chaining)
Example:
ftp.setVerbose(1)Sets a function to track transfer progress.
Parameters:
callbackFuncName(string): Name of the callback function
Returns: self (for method chaining)
Example:
ftp.setProgressCallback(:myProgressCallback)
func myProgressCallback(download_total, download_now, upload_total, upload_now)
# Your progress handling codeRemoves the active progress callback.
Returns: self (for method chaining)
Connects to the configured FTP server.
Returns: self (for method chaining)
Example:
ftp.connect()Uploads a local file to the remote server.
Parameters:
localPath(string): Path to the local fileremotePath(string): Destination path on the remote server
Returns: self (for method chaining)
Example:
ftp.upload("local.txt", "/remote.txt")Downloads a remote file to a local path.
Parameters:
remotePath(string): Path to the remote filelocalPath(string): Destination path on the local system
Returns: self (for method chaining)
Example:
ftp.download("/remote.txt", "local.txt")Lists the contents of a remote directory.
Parameters:
remotePath(string): Path to the remote directory
Returns: String containing directory listing
Example:
listing = ftp.listDir("/")
? listingCreates a directory on the remote server.
Parameters:
remotePath(string): Path for the new directory
Returns: self (for method chaining)
Example:
ftp.mkdir("/new_folder")Removes a directory from the remote server.
Parameters:
remotePath(string): Path to the directory to remove
Returns: self (for method chaining)
Example:
ftp.rmdir("/old_folder")Deletes a file from the remote server.
Parameters:
remotePath(string): Path to the file to delete
Returns: self (for method chaining)
Example:
ftp.delete("/unwanted.txt")Renames a file or directory on the remote server.
Parameters:
oldPath(string): Current pathnewPath(string): New path
Returns: self (for method chaining)
Example:
ftp.rename("/old.txt", "/new.txt")Gets the size of a remote file in bytes.
Parameters:
remotePath(string): Path to the remote file
Returns: File size in bytes (number)
Example:
size = ftp.getFileSize("/file.txt")Executes a custom FTP command.
Parameters:
command(string): FTP command to execute
Returns: Server response string
Example:
response = ftp.executeCommand("PWD")Returns the last error message from the client.
Returns: Error message string
Example:
? ftp.getError()Disconnects and cleans up the client instance.
Example:
ftp.close()FTP_OK: Operation successfulFTP_ERROR_INIT: Initialization errorFTP_ERROR_CONNECTION: Connection errorFTP_ERROR_AUTH: Authentication errorFTP_ERROR_TRANSFER: Transfer errorFTP_ERROR_FILE_NOT_FOUND: File not foundFTP_ERROR_MEMORY: Memory allocation errorFTP_ERROR_INVALID_PARAM: Invalid parameterFTP_ERROR_CURL: libcurl errorFTP_ERROR_FILE_IO: File I/O errorFTP_ERROR_TIMEOUT: Timeout error
If you wish to contribute to the development of Ring FTP or build it from the source, follow these steps.
- CMake: Version 3.16 or higher.
- C Compiler: A C compiler compatible with your platform (e.g., GCC, Clang, MSVC).
- libcurl: libcurl development libraries with SSL/TLS support.
- Ring Source Code: You will need to have the Ring language source code available on your machine.
-
Clone the Repository:
git clone https://github.com/ysdragon/ftp.git --recursive
Note If you installed the library via RingPM, you can skip this step.
-
Set the
RINGEnvironment Variable: This variable must point to the root directory of the Ring language source code.- Windows (Command Prompt):
set RING=X:\path\to\ring
- Windows (PowerShell):
$env:RING = "X:\path\to\ring"
- Unix-like Systems (Linux, macOS or FreeBSD):
export RING=/path/to/ring
- Windows (Command Prompt):
-
Configure with CMake: Create a build directory and run CMake from within it.
mkdir build cd build cmake .. -
Build the Project: Compile the source code using the build toolchain configured by CMake.
cmake --build .The compiled library will be available in the
lib/<os>/<arch>directory.
Contributions are always welcome! If you have suggestions for improvements or have identified a bug, please feel free to open an issue or submit a pull request.
This project is licensed under the MIT License. See the LICENSE file for more details.