206 lines
7.0 KiB
C++
206 lines
7.0 KiB
C++
|
|
||
|
////////////////////////////////////////////////////////////
|
||
|
// Headers
|
||
|
////////////////////////////////////////////////////////////
|
||
|
#include <SFML/Network.hpp>
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////
|
||
|
/// Print a FTP response into a standard output stream
|
||
|
///
|
||
|
////////////////////////////////////////////////////////////
|
||
|
std::ostream& operator <<(std::ostream& Stream, const sf::Ftp::Response& Response)
|
||
|
{
|
||
|
return Stream << Response.GetStatus() << Response.GetMessage();
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////
|
||
|
/// Entry point of application
|
||
|
///
|
||
|
/// \return Application exit code
|
||
|
///
|
||
|
////////////////////////////////////////////////////////////
|
||
|
int main()
|
||
|
{
|
||
|
// Choose the server address
|
||
|
sf::IPAddress Address;
|
||
|
do
|
||
|
{
|
||
|
std::cout << "Enter the FTP server address : ";
|
||
|
std::cin >> Address;
|
||
|
}
|
||
|
while (!Address.IsValid());
|
||
|
|
||
|
// Connect to the server
|
||
|
sf::Ftp Server;
|
||
|
sf::Ftp::Response ConnectResponse = Server.Connect(Address);
|
||
|
std::cout << ConnectResponse << std::endl;
|
||
|
if (!ConnectResponse.IsOk())
|
||
|
return EXIT_FAILURE;
|
||
|
|
||
|
// Ask for user name and password
|
||
|
std::string UserName, Password;
|
||
|
std::cout << "User name : ";
|
||
|
std::cin >> UserName;
|
||
|
std::cout << "Password : ";
|
||
|
std::cin >> Password;
|
||
|
|
||
|
// Login to the server
|
||
|
sf::Ftp::Response LoginResponse = Server.Login(UserName, Password);
|
||
|
std::cout << LoginResponse << std::endl;
|
||
|
if (!LoginResponse.IsOk())
|
||
|
return EXIT_FAILURE;
|
||
|
|
||
|
// Main menu
|
||
|
int Choice = 0;
|
||
|
do
|
||
|
{
|
||
|
// Main FTP menu
|
||
|
std::cout << std::endl;
|
||
|
std::cout << "Choose an action:" << std::endl;
|
||
|
std::cout << "1. Print working directory" << std::endl;
|
||
|
std::cout << "2. Print contents of working directory" << std::endl;
|
||
|
std::cout << "3. Change directory" << std::endl;
|
||
|
std::cout << "4. Create directory" << std::endl;
|
||
|
std::cout << "5. Delete directory" << std::endl;
|
||
|
std::cout << "6. Rename file" << std::endl;
|
||
|
std::cout << "7. Remove file" << std::endl;
|
||
|
std::cout << "8. Download file" << std::endl;
|
||
|
std::cout << "9. Upload file" << std::endl;
|
||
|
std::cout << "0. Disconnect" << std::endl;
|
||
|
std::cout << std::endl;
|
||
|
|
||
|
std::cout << "Your choice: ";
|
||
|
std::cin >> Choice;
|
||
|
std::cout << std::endl;
|
||
|
|
||
|
switch (Choice)
|
||
|
{
|
||
|
default :
|
||
|
{
|
||
|
// Wrong choice
|
||
|
std::cout << "Invalid choice!" << std::endl;
|
||
|
std::cin.clear();
|
||
|
std::cin.ignore(10000, '\n');
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 1 :
|
||
|
{
|
||
|
// Print current server directory
|
||
|
sf::Ftp::DirectoryResponse Response = Server.GetWorkingDirectory();
|
||
|
std::cout << Response << std::endl;
|
||
|
std::cout << "Current directory is " << Response.GetDirectory() << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 2 :
|
||
|
{
|
||
|
// Print content of current server directory
|
||
|
sf::Ftp::ListingResponse Response = Server.GetDirectoryListing();
|
||
|
std::cout << Response << std::endl;
|
||
|
for (std::size_t i = 0; i < Response.GetCount(); ++i)
|
||
|
std::cout << Response.GetFilename(i) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 3 :
|
||
|
{
|
||
|
// Change the current directory
|
||
|
std::string Directory;
|
||
|
std::cout << "Choose a directory: ";
|
||
|
std::cin >> Directory;
|
||
|
std::cout << Server.ChangeDirectory(Directory) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 4 :
|
||
|
{
|
||
|
// Create a new directory
|
||
|
std::string Directory;
|
||
|
std::cout << "Name of the directory to create: ";
|
||
|
std::cin >> Directory;
|
||
|
std::cout << Server.MakeDirectory(Directory) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 5 :
|
||
|
{
|
||
|
// Remove an existing directory
|
||
|
std::string Directory;
|
||
|
std::cout << "Name of the directory to remove: ";
|
||
|
std::cin >> Directory;
|
||
|
std::cout << Server.DeleteDirectory(Directory) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 6 :
|
||
|
{
|
||
|
// Rename a file
|
||
|
std::string SrcFilename, DstFilename;
|
||
|
std::cout << "Name of the file to rename: ";
|
||
|
std::cin >> SrcFilename;
|
||
|
std::cout << "New name: ";
|
||
|
std::cin >> DstFilename;
|
||
|
std::cout << Server.RenameFile(SrcFilename, DstFilename) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 7 :
|
||
|
{
|
||
|
// Remove an existing directory
|
||
|
std::string Filename;
|
||
|
std::cout << "Name of the file to remove: ";
|
||
|
std::cin >> Filename;
|
||
|
std::cout << Server.DeleteFile(Filename) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 8 :
|
||
|
{
|
||
|
// Download a file from server
|
||
|
std::string Filename, Directory;
|
||
|
std::cout << "Path of the file to download (relative to current directory): ";
|
||
|
std::cin >> Filename;
|
||
|
std::cout << "Directory to download the file to: ";
|
||
|
std::cin >> Directory;
|
||
|
std::cout << Server.Download(Filename, Directory) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 9 :
|
||
|
{
|
||
|
// Upload a file to server
|
||
|
std::string Filename, Directory;
|
||
|
std::cout << "Path of the file to upload (absolute or relative to working directory): ";
|
||
|
std::cin >> Filename;
|
||
|
std::cout << "Directory to upload the file to (relative to current directory): ";
|
||
|
std::cin >> Directory;
|
||
|
std::cout << Server.Upload(Filename, Directory) << std::endl;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 0 :
|
||
|
{
|
||
|
// Disconnect
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} while (Choice != 0);
|
||
|
|
||
|
// Disconnect from the server
|
||
|
std::cout << "Disconnecting from server..." << std::endl;
|
||
|
std::cout << Server.Disconnect() << std::endl;
|
||
|
|
||
|
// Wait until the user presses 'enter' key
|
||
|
std::cout << "Press enter to exit..." << std::endl;
|
||
|
std::cin.ignore(10000, '\n');
|
||
|
std::cin.ignore(10000, '\n');
|
||
|
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|