+////////////////////////////////////////////////////////////\r
+//\r
+// SFML - Simple and Fast Multimedia Library\r
+// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)\r
+//\r
+// This software is provided 'as-is', without any express or implied warranty.\r
+// In no event will the authors be held liable for any damages arising from the use of this software.\r
+//\r
+// Permission is granted to anyone to use this software for any purpose,\r
+// including commercial applications, and to alter it and redistribute it freely,\r
+// subject to the following restrictions:\r
+//\r
+// 1. The origin of this software must not be misrepresented;\r
+// you must not claim that you wrote the original software.\r
+// If you use this software in a product, an acknowledgment\r
+// in the product documentation would be appreciated but is not required.\r
+//\r
+// 2. Altered source versions must be plainly marked as such,\r
+// and must not be misrepresented as being the original software.\r
+//\r
+// 3. This notice may not be removed or altered from any source distribution.\r
+//\r
+////////////////////////////////////////////////////////////\r
+\r
+#ifndef SFML_FTP_HPP\r
+#define SFML_FTP_HPP\r
+\r
+////////////////////////////////////////////////////////////\r
+// Headers\r
+////////////////////////////////////////////////////////////\r
+#include <SFML/System/NonCopyable.hpp>\r
+#include <SFML/Network/SocketTCP.hpp>\r
+#include <string>\r
+#include <vector>\r
+\r
+\r
+namespace sf\r
+{\r
+class IPAddress;\r
+\r
+////////////////////////////////////////////////////////////\r
+/// This class provides methods for manipulating the FTP\r
+/// protocol (described in RFC 959).\r
+/// It provides easy access and transfers to remote\r
+/// directories and files on a FTP server\r
+////////////////////////////////////////////////////////////\r
+class SFML_API Ftp : NonCopyable\r
+{\r
+public :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Enumeration of transfer modes\r
+ ////////////////////////////////////////////////////////////\r
+ enum TransferMode\r
+ {\r
+ Binary, ///< Binary mode (file is transfered as a sequence of bytes)\r
+ Ascii, ///< Text mode using ASCII encoding\r
+ Ebcdic ///< Text mode using EBCDIC encoding\r
+ };\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// This class wraps a FTP response, which is basically :\r
+ /// - a status code\r
+ /// - a message\r
+ ////////////////////////////////////////////////////////////\r
+ class SFML_API Response\r
+ {\r
+ public :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Enumerate all the valid status codes returned in\r
+ /// a FTP response\r
+ ////////////////////////////////////////////////////////////\r
+ enum Status\r
+ {\r
+ // 1xx: the requested action is being initiated,\r
+ // expect another reply before proceeding with a new command\r
+ RestartMarkerReply = 110, ///< Restart marker reply\r
+ ServiceReadySoon = 120, ///< Service ready in N minutes\r
+ DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting\r
+ OpeningDataConnection = 150, ///< File status ok, about to open data connection\r
+\r
+ // 2xx: the requested action has been successfully completed\r
+ Ok = 200, ///< Command ok\r
+ PointlessCommand = 202, ///< Command not implemented\r
+ SystemStatus = 211, ///< System status, or system help reply\r
+ DirectoryStatus = 212, ///< Directory status\r
+ FileStatus = 213, ///< File status\r
+ HelpMessage = 214, ///< Help message\r
+ SystemType = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document\r
+ ServiceReady = 220, ///< Service ready for new user\r
+ ClosingConnection = 221, ///< Service closing control connection\r
+ DataConnectionOpened = 225, ///< Data connection open, no transfer in progress\r
+ ClosingDataConnection = 226, ///< Closing data connection, requested file action successful\r
+ EnteringPassiveMode = 227, ///< Entering passive mode\r
+ LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate\r
+ FileActionOk = 250, ///< Requested file action ok\r
+ DirectoryOk = 257, ///< PATHNAME created\r
+\r
+ // 3xx: the command has been accepted, but the requested action\r
+ // is dormant, pending receipt of further information\r
+ NeedPassword = 331, ///< User name ok, need password\r
+ NeedAccountToLogIn = 332, ///< Need account for login\r
+ NeedInformation = 350, ///< Requested file action pending further information\r
+\r
+ // 4xx: the command was not accepted and the requested action did not take place,\r
+ // but the error condition is temporary and the action may be requested again\r
+ ServiceUnavailable = 421, ///< Service not available, closing control connection\r
+ DataConnectionUnavailable = 425, ///< Can't open data connection\r
+ TransferAborted = 426, ///< Connection closed, transfer aborted\r
+ FileActionAborted = 450, ///< Requested file action not taken\r
+ LocalError = 451, ///< Requested action aborted, local error in processing\r
+ InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable\r
+\r
+ // 5xx: the command was not accepted and\r
+ // the requested action did not take place\r
+ CommandUnknown = 500, ///< Syntax error, command unrecognized\r
+ ParametersUnknown = 501, ///< Syntax error in parameters or arguments\r
+ CommandNotImplemented = 502, ///< Command not implemented\r
+ BadCommandSequence = 503, ///< Bad sequence of commands\r
+ ParameterNotImplemented = 504, ///< Command not implemented for that parameter\r
+ NotLoggedIn = 530, ///< Not logged in\r
+ NeedAccountToStore = 532, ///< Need account for storing files\r
+ FileUnavailable = 550, ///< Requested action not taken, file unavailable\r
+ PageTypeUnknown = 551, ///< Requested action aborted, page type unknown\r
+ NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation\r
+ FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed\r
+\r
+ // 10xx: SFML custom codes\r
+ InvalidResponse = 1000, ///< Response is not a valid FTP one\r
+ ConnectionFailed = 1001, ///< Connection with server failed\r
+ ConnectionClosed = 1002, ///< Connection with server closed\r
+ InvalidFile = 1003 ///< Invalid file to upload / download\r
+ };\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Default constructor\r
+ ///\r
+ /// \param Code : Response status code (InvalidResponse by default)\r
+ /// \param Message : Response message (empty by default)\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response(Status Code = InvalidResponse, const std::string& Message = "");\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Convenience function to check if the response status code\r
+ /// means a success\r
+ ///\r
+ /// \return True if status is success (code < 400)\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ bool IsOk() const;\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the response status code\r
+ ///\r
+ /// \return Status code\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Status GetStatus() const;\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the full message contained in the response\r
+ ///\r
+ /// \return The response message\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ const std::string& GetMessage() const;\r
+\r
+ private :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ // Member data\r
+ ////////////////////////////////////////////////////////////\r
+ Status myStatus; ///< Status code returned from the server\r
+ std::string myMessage; ///< Last message received from the server\r
+ };\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Specialization of FTP response returning a directory\r
+ ////////////////////////////////////////////////////////////\r
+ class SFML_API DirectoryResponse : public Response\r
+ {\r
+ public :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Default constructor\r
+ ///\r
+ /// \param Resp : Source response\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ DirectoryResponse(Response Resp);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the directory returned in the response\r
+ ///\r
+ /// \return Directory name\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ const std::string& GetDirectory() const;\r
+\r
+ private :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ // Member data\r
+ ////////////////////////////////////////////////////////////\r
+ std::string myDirectory; ///< Directory extracted from the response message\r
+ };\r
+\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Specialization of FTP response returning a filename lisiting\r
+ ////////////////////////////////////////////////////////////\r
+ class SFML_API ListingResponse : public Response\r
+ {\r
+ public :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Default constructor\r
+ ///\r
+ /// \param Resp : Source response\r
+ /// \param Data : Data containing the raw listing\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ ListingResponse(Response Resp, const std::vector<char>& Data);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the number of filenames in the listing\r
+ ///\r
+ /// \return Total number of filenames\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ std::size_t GetCount() const;\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the Index-th filename in the directory\r
+ ///\r
+ /// \param Index : Index of the filename to get\r
+ ///\r
+ /// \return Index-th filename\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ const std::string& GetFilename(std::size_t Index) const;\r
+\r
+ private :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ // Member data\r
+ ////////////////////////////////////////////////////////////\r
+ std::vector<std::string> myFilenames; ///< Filenames extracted from the data\r
+ };\r
+\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Destructor -- close the connection with the server\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ ~Ftp();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Connect to the specified FTP server\r
+ ///\r
+ /// \param Server : FTP server to connect to\r
+ /// \param Port : Port used for connection (21 by default, standard FTP port)\r
+ /// \param Timeout : Maximum time to wait, in seconds (0 by default, means no timeout)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Connect(const IPAddress& Server, unsigned short Port = 21, float Timeout = 0.f);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Log in using anonymous account\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Login();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Log in using a username and a password\r
+ ///\r
+ /// \param UserName : User name\r
+ /// \param Password : Password\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Login(const std::string& UserName, const std::string& Password);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Close the connection with FTP server\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Disconnect();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Send a null command just to prevent from being disconnected\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response KeepAlive();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the current working directory\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ DirectoryResponse GetWorkingDirectory();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Get the contents of the given directory\r
+ /// (subdirectories and files)\r
+ ///\r
+ /// \param Directory : Directory to list ("" by default, the current one)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ ListingResponse GetDirectoryListing(const std::string& Directory = "");\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Change the current working directory\r
+ ///\r
+ /// \param Directory : New directory, relative to the current one\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response ChangeDirectory(const std::string& Directory);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Go to the parent directory of the current one\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response ParentDirectory();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Create a new directory\r
+ ///\r
+ /// \param Name : Name of the directory to create\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response MakeDirectory(const std::string& Name);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Remove an existing directory\r
+ ///\r
+ /// \param Name : Name of the directory to remove\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response DeleteDirectory(const std::string& Name);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Rename a file\r
+ ///\r
+ /// \param File : File to rename\r
+ /// \param NewName : New name\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response RenameFile(const std::string& File, const std::string& NewName);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Remove an existing file\r
+ ///\r
+ /// \param Name : File to remove\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response DeleteFile(const std::string& Name);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Download a file from the server\r
+ ///\r
+ /// \param DistantFile : Path of the distant file to download\r
+ /// \param DestPath : Where to put to file on the local computer\r
+ /// \param Mode : Transfer mode (binary by default)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode = Binary);\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Upload a file to the server\r
+ ///\r
+ /// \param LocalFile : Path of the local file to upload\r
+ /// \param DestPath : Where to put to file on the server\r
+ /// \param Mode : Transfer mode (binary by default)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode = Binary);\r
+\r
+private :\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Send a command to the FTP server\r
+ ///\r
+ /// \param Command : Command to send\r
+ /// \param Parameter : Command parameter ("" by default)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response SendCommand(const std::string& Command, const std::string& Parameter = "");\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Receive a response from the server\r
+ /// (usually after a command has been sent)\r
+ ///\r
+ /// \return Server response to the request\r
+ ///\r
+ ////////////////////////////////////////////////////////////\r
+ Response GetResponse();\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ /// Utility class for exchanging datas with the server\r
+ /// on the data channel\r
+ ////////////////////////////////////////////////////////////\r
+ class DataChannel;\r
+\r
+ friend class DataChannel;\r
+\r
+ ////////////////////////////////////////////////////////////\r
+ // Member data\r
+ ////////////////////////////////////////////////////////////\r
+ SocketTCP myCommandSocket; ///< Socket holding the control connection with the server\r
+};\r
+\r
+} // namespace sf\r
+\r
+\r
+#endif // SFML_FTP_HPP\r