|
|
|||
File indexing completed on 2026-06-02 08:58:14
0001 //////////////////////////////////////////////////////////// 0002 // 0003 // SFML - Simple and Fast Multimedia Library 0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) 0005 // 0006 // This software is provided 'as-is', without any express or implied warranty. 0007 // In no event will the authors be held liable for any damages arising from the use of this software. 0008 // 0009 // Permission is granted to anyone to use this software for any purpose, 0010 // including commercial applications, and to alter it and redistribute it freely, 0011 // subject to the following restrictions: 0012 // 0013 // 1. The origin of this software must not be misrepresented; 0014 // you must not claim that you wrote the original software. 0015 // If you use this software in a product, an acknowledgment 0016 // in the product documentation would be appreciated but is not required. 0017 // 0018 // 2. Altered source versions must be plainly marked as such, 0019 // and must not be misrepresented as being the original software. 0020 // 0021 // 3. This notice may not be removed or altered from any source distribution. 0022 // 0023 //////////////////////////////////////////////////////////// 0024 0025 #ifndef SFML_FTP_HPP 0026 #define SFML_FTP_HPP 0027 0028 //////////////////////////////////////////////////////////// 0029 // Headers 0030 //////////////////////////////////////////////////////////// 0031 #include <SFML/Network/Export.hpp> 0032 #include <SFML/Network/TcpSocket.hpp> 0033 #include <SFML/System/NonCopyable.hpp> 0034 #include <SFML/System/Time.hpp> 0035 #include <string> 0036 #include <vector> 0037 0038 0039 namespace sf 0040 { 0041 class IpAddress; 0042 0043 //////////////////////////////////////////////////////////// 0044 /// \brief A FTP client 0045 /// 0046 //////////////////////////////////////////////////////////// 0047 class SFML_NETWORK_API Ftp : NonCopyable 0048 { 0049 public: 0050 0051 //////////////////////////////////////////////////////////// 0052 /// \brief Enumeration of transfer modes 0053 /// 0054 //////////////////////////////////////////////////////////// 0055 enum TransferMode 0056 { 0057 Binary, //!< Binary mode (file is transfered as a sequence of bytes) 0058 Ascii, //!< Text mode using ASCII encoding 0059 Ebcdic //!< Text mode using EBCDIC encoding 0060 }; 0061 0062 //////////////////////////////////////////////////////////// 0063 /// \brief Define a FTP response 0064 /// 0065 //////////////////////////////////////////////////////////// 0066 class SFML_NETWORK_API Response 0067 { 0068 public: 0069 0070 //////////////////////////////////////////////////////////// 0071 /// \brief Status codes possibly returned by a FTP response 0072 /// 0073 //////////////////////////////////////////////////////////// 0074 enum Status 0075 { 0076 // 1xx: the requested action is being initiated, 0077 // expect another reply before proceeding with a new command 0078 RestartMarkerReply = 110, //!< Restart marker reply 0079 ServiceReadySoon = 120, //!< Service ready in N minutes 0080 DataConnectionAlreadyOpened = 125, //!< Data connection already opened, transfer starting 0081 OpeningDataConnection = 150, //!< File status ok, about to open data connection 0082 0083 // 2xx: the requested action has been successfully completed 0084 Ok = 200, //!< Command ok 0085 PointlessCommand = 202, //!< Command not implemented 0086 SystemStatus = 211, //!< System status, or system help reply 0087 DirectoryStatus = 212, //!< Directory status 0088 FileStatus = 213, //!< File status 0089 HelpMessage = 214, //!< Help message 0090 SystemType = 215, //!< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document 0091 ServiceReady = 220, //!< Service ready for new user 0092 ClosingConnection = 221, //!< Service closing control connection 0093 DataConnectionOpened = 225, //!< Data connection open, no transfer in progress 0094 ClosingDataConnection = 226, //!< Closing data connection, requested file action successful 0095 EnteringPassiveMode = 227, //!< Entering passive mode 0096 LoggedIn = 230, //!< User logged in, proceed. Logged out if appropriate 0097 FileActionOk = 250, //!< Requested file action ok 0098 DirectoryOk = 257, //!< PATHNAME created 0099 0100 // 3xx: the command has been accepted, but the requested action 0101 // is dormant, pending receipt of further information 0102 NeedPassword = 331, //!< User name ok, need password 0103 NeedAccountToLogIn = 332, //!< Need account for login 0104 NeedInformation = 350, //!< Requested file action pending further information 0105 0106 // 4xx: the command was not accepted and the requested action did not take place, 0107 // but the error condition is temporary and the action may be requested again 0108 ServiceUnavailable = 421, //!< Service not available, closing control connection 0109 DataConnectionUnavailable = 425, //!< Can't open data connection 0110 TransferAborted = 426, //!< Connection closed, transfer aborted 0111 FileActionAborted = 450, //!< Requested file action not taken 0112 LocalError = 451, //!< Requested action aborted, local error in processing 0113 InsufficientStorageSpace = 452, //!< Requested action not taken; insufficient storage space in system, file unavailable 0114 0115 // 5xx: the command was not accepted and 0116 // the requested action did not take place 0117 CommandUnknown = 500, //!< Syntax error, command unrecognized 0118 ParametersUnknown = 501, //!< Syntax error in parameters or arguments 0119 CommandNotImplemented = 502, //!< Command not implemented 0120 BadCommandSequence = 503, //!< Bad sequence of commands 0121 ParameterNotImplemented = 504, //!< Command not implemented for that parameter 0122 NotLoggedIn = 530, //!< Not logged in 0123 NeedAccountToStore = 532, //!< Need account for storing files 0124 FileUnavailable = 550, //!< Requested action not taken, file unavailable 0125 PageTypeUnknown = 551, //!< Requested action aborted, page type unknown 0126 NotEnoughMemory = 552, //!< Requested file action aborted, exceeded storage allocation 0127 FilenameNotAllowed = 553, //!< Requested action not taken, file name not allowed 0128 0129 // 10xx: SFML custom codes 0130 InvalidResponse = 1000, //!< Not part of the FTP standard, generated by SFML when a received response cannot be parsed 0131 ConnectionFailed = 1001, //!< Not part of the FTP standard, generated by SFML when the low-level socket connection with the server fails 0132 ConnectionClosed = 1002, //!< Not part of the FTP standard, generated by SFML when the low-level socket connection is unexpectedly closed 0133 InvalidFile = 1003 //!< Not part of the FTP standard, generated by SFML when a local file cannot be read or written 0134 }; 0135 0136 //////////////////////////////////////////////////////////// 0137 /// \brief Default constructor 0138 /// 0139 /// This constructor is used by the FTP client to build 0140 /// the response. 0141 /// 0142 /// \param code Response status code 0143 /// \param message Response message 0144 /// 0145 //////////////////////////////////////////////////////////// 0146 explicit Response(Status code = InvalidResponse, const std::string& message = ""); 0147 0148 //////////////////////////////////////////////////////////// 0149 /// \brief Check if the status code means a success 0150 /// 0151 /// This function is defined for convenience, it is 0152 /// equivalent to testing if the status code is < 400. 0153 /// 0154 /// \return True if the status is a success, false if it is a failure 0155 /// 0156 //////////////////////////////////////////////////////////// 0157 bool isOk() const; 0158 0159 //////////////////////////////////////////////////////////// 0160 /// \brief Get the status code of the response 0161 /// 0162 /// \return Status code 0163 /// 0164 //////////////////////////////////////////////////////////// 0165 Status getStatus() const; 0166 0167 //////////////////////////////////////////////////////////// 0168 /// \brief Get the full message contained in the response 0169 /// 0170 /// \return The response message 0171 /// 0172 //////////////////////////////////////////////////////////// 0173 const std::string& getMessage() const; 0174 0175 private: 0176 0177 //////////////////////////////////////////////////////////// 0178 // Member data 0179 //////////////////////////////////////////////////////////// 0180 Status m_status; //!< Status code returned from the server 0181 std::string m_message; //!< Last message received from the server 0182 }; 0183 0184 //////////////////////////////////////////////////////////// 0185 /// \brief Specialization of FTP response returning a directory 0186 /// 0187 //////////////////////////////////////////////////////////// 0188 class SFML_NETWORK_API DirectoryResponse : public Response 0189 { 0190 public: 0191 0192 //////////////////////////////////////////////////////////// 0193 /// \brief Default constructor 0194 /// 0195 /// \param response Source response 0196 /// 0197 //////////////////////////////////////////////////////////// 0198 DirectoryResponse(const Response& response); 0199 0200 //////////////////////////////////////////////////////////// 0201 /// \brief Get the directory returned in the response 0202 /// 0203 /// \return Directory name 0204 /// 0205 //////////////////////////////////////////////////////////// 0206 const std::string& getDirectory() const; 0207 0208 private: 0209 0210 //////////////////////////////////////////////////////////// 0211 // Member data 0212 //////////////////////////////////////////////////////////// 0213 std::string m_directory; //!< Directory extracted from the response message 0214 }; 0215 0216 0217 //////////////////////////////////////////////////////////// 0218 /// \brief Specialization of FTP response returning a 0219 /// filename listing 0220 //////////////////////////////////////////////////////////// 0221 class SFML_NETWORK_API ListingResponse : public Response 0222 { 0223 public: 0224 0225 //////////////////////////////////////////////////////////// 0226 /// \brief Default constructor 0227 /// 0228 /// \param response Source response 0229 /// \param data Data containing the raw listing 0230 /// 0231 //////////////////////////////////////////////////////////// 0232 ListingResponse(const Response& response, const std::string& data); 0233 0234 //////////////////////////////////////////////////////////// 0235 /// \brief Return the array of directory/file names 0236 /// 0237 /// \return Array containing the requested listing 0238 /// 0239 //////////////////////////////////////////////////////////// 0240 const std::vector<std::string>& getListing() const; 0241 0242 private: 0243 0244 //////////////////////////////////////////////////////////// 0245 // Member data 0246 //////////////////////////////////////////////////////////// 0247 std::vector<std::string> m_listing; //!< Directory/file names extracted from the data 0248 }; 0249 0250 0251 //////////////////////////////////////////////////////////// 0252 /// \brief Destructor 0253 /// 0254 /// Automatically closes the connection with the server if 0255 /// it is still opened. 0256 /// 0257 //////////////////////////////////////////////////////////// 0258 ~Ftp(); 0259 0260 //////////////////////////////////////////////////////////// 0261 /// \brief Connect to the specified FTP server 0262 /// 0263 /// The port has a default value of 21, which is the standard 0264 /// port used by the FTP protocol. You shouldn't use a different 0265 /// value, unless you really know what you do. 0266 /// This function tries to connect to the server so it may take 0267 /// a while to complete, especially if the server is not 0268 /// reachable. To avoid blocking your application for too long, 0269 /// you can use a timeout. The default value, Time::Zero, means that the 0270 /// system timeout will be used (which is usually pretty long). 0271 /// 0272 /// \param server Name or address of the FTP server to connect to 0273 /// \param port Port used for the connection 0274 /// \param timeout Maximum time to wait 0275 /// 0276 /// \return Server response to the request 0277 /// 0278 /// \see disconnect 0279 /// 0280 //////////////////////////////////////////////////////////// 0281 Response connect(const IpAddress& server, unsigned short port = 21, Time timeout = Time::Zero); 0282 0283 //////////////////////////////////////////////////////////// 0284 /// \brief Close the connection with the server 0285 /// 0286 /// \return Server response to the request 0287 /// 0288 /// \see connect 0289 /// 0290 //////////////////////////////////////////////////////////// 0291 Response disconnect(); 0292 0293 //////////////////////////////////////////////////////////// 0294 /// \brief Log in using an anonymous account 0295 /// 0296 /// Logging in is mandatory after connecting to the server. 0297 /// Users that are not logged in cannot perform any operation. 0298 /// 0299 /// \return Server response to the request 0300 /// 0301 //////////////////////////////////////////////////////////// 0302 Response login(); 0303 0304 //////////////////////////////////////////////////////////// 0305 /// \brief Log in using a username and a password 0306 /// 0307 /// Logging in is mandatory after connecting to the server. 0308 /// Users that are not logged in cannot perform any operation. 0309 /// 0310 /// \param name User name 0311 /// \param password Password 0312 /// 0313 /// \return Server response to the request 0314 /// 0315 //////////////////////////////////////////////////////////// 0316 Response login(const std::string& name, const std::string& password); 0317 0318 //////////////////////////////////////////////////////////// 0319 /// \brief Send a null command to keep the connection alive 0320 /// 0321 /// This command is useful because the server may close the 0322 /// connection automatically if no command is sent. 0323 /// 0324 /// \return Server response to the request 0325 /// 0326 //////////////////////////////////////////////////////////// 0327 Response keepAlive(); 0328 0329 //////////////////////////////////////////////////////////// 0330 /// \brief Get the current working directory 0331 /// 0332 /// The working directory is the root path for subsequent 0333 /// operations involving directories and/or filenames. 0334 /// 0335 /// \return Server response to the request 0336 /// 0337 /// \see getDirectoryListing, changeDirectory, parentDirectory 0338 /// 0339 //////////////////////////////////////////////////////////// 0340 DirectoryResponse getWorkingDirectory(); 0341 0342 //////////////////////////////////////////////////////////// 0343 /// \brief Get the contents of the given directory 0344 /// 0345 /// This function retrieves the sub-directories and files 0346 /// contained in the given directory. It is not recursive. 0347 /// The \a directory parameter is relative to the current 0348 /// working directory. 0349 /// 0350 /// \param directory Directory to list 0351 /// 0352 /// \return Server response to the request 0353 /// 0354 /// \see getWorkingDirectory, changeDirectory, parentDirectory 0355 /// 0356 //////////////////////////////////////////////////////////// 0357 ListingResponse getDirectoryListing(const std::string& directory = ""); 0358 0359 //////////////////////////////////////////////////////////// 0360 /// \brief Change the current working directory 0361 /// 0362 /// The new directory must be relative to the current one. 0363 /// 0364 /// \param directory New working directory 0365 /// 0366 /// \return Server response to the request 0367 /// 0368 /// \see getWorkingDirectory, getDirectoryListing, parentDirectory 0369 /// 0370 //////////////////////////////////////////////////////////// 0371 Response changeDirectory(const std::string& directory); 0372 0373 //////////////////////////////////////////////////////////// 0374 /// \brief Go to the parent directory of the current one 0375 /// 0376 /// \return Server response to the request 0377 /// 0378 /// \see getWorkingDirectory, getDirectoryListing, changeDirectory 0379 /// 0380 //////////////////////////////////////////////////////////// 0381 Response parentDirectory(); 0382 0383 //////////////////////////////////////////////////////////// 0384 /// \brief Create a new directory 0385 /// 0386 /// The new directory is created as a child of the current 0387 /// working directory. 0388 /// 0389 /// \param name Name of the directory to create 0390 /// 0391 /// \return Server response to the request 0392 /// 0393 /// \see deleteDirectory 0394 /// 0395 //////////////////////////////////////////////////////////// 0396 Response createDirectory(const std::string& name); 0397 0398 //////////////////////////////////////////////////////////// 0399 /// \brief Remove an existing directory 0400 /// 0401 /// The directory to remove must be relative to the 0402 /// current working directory. 0403 /// Use this function with caution, the directory will 0404 /// be removed permanently! 0405 /// 0406 /// \param name Name of the directory to remove 0407 /// 0408 /// \return Server response to the request 0409 /// 0410 /// \see createDirectory 0411 /// 0412 //////////////////////////////////////////////////////////// 0413 Response deleteDirectory(const std::string& name); 0414 0415 //////////////////////////////////////////////////////////// 0416 /// \brief Rename an existing file 0417 /// 0418 /// The filenames must be relative to the current working 0419 /// directory. 0420 /// 0421 /// \param file File to rename 0422 /// \param newName New name of the file 0423 /// 0424 /// \return Server response to the request 0425 /// 0426 /// \see deleteFile 0427 /// 0428 //////////////////////////////////////////////////////////// 0429 Response renameFile(const std::string& file, const std::string& newName); 0430 0431 //////////////////////////////////////////////////////////// 0432 /// \brief Remove an existing file 0433 /// 0434 /// The file name must be relative to the current working 0435 /// directory. 0436 /// Use this function with caution, the file will be 0437 /// removed permanently! 0438 /// 0439 /// \param name File to remove 0440 /// 0441 /// \return Server response to the request 0442 /// 0443 /// \see renameFile 0444 /// 0445 //////////////////////////////////////////////////////////// 0446 Response deleteFile(const std::string& name); 0447 0448 //////////////////////////////////////////////////////////// 0449 /// \brief Download a file from the server 0450 /// 0451 /// The filename of the distant file is relative to the 0452 /// current working directory of the server, and the local 0453 /// destination path is relative to the current directory 0454 /// of your application. 0455 /// If a file with the same filename as the distant file 0456 /// already exists in the local destination path, it will 0457 /// be overwritten. 0458 /// 0459 /// \param remoteFile Filename of the distant file to download 0460 /// \param localPath The directory in which to put the file on the local computer 0461 /// \param mode Transfer mode 0462 /// 0463 /// \return Server response to the request 0464 /// 0465 /// \see upload 0466 /// 0467 //////////////////////////////////////////////////////////// 0468 Response download(const std::string& remoteFile, const std::string& localPath, TransferMode mode = Binary); 0469 0470 //////////////////////////////////////////////////////////// 0471 /// \brief Upload a file to the server 0472 /// 0473 /// The name of the local file is relative to the current 0474 /// working directory of your application, and the 0475 /// remote path is relative to the current directory of the 0476 /// FTP server. 0477 /// 0478 /// The append parameter controls whether the remote file is 0479 /// appended to or overwritten if it already exists. 0480 /// 0481 /// \param localFile Path of the local file to upload 0482 /// \param remotePath The directory in which to put the file on the server 0483 /// \param mode Transfer mode 0484 /// \param append Pass true to append to or false to overwrite the remote file if it already exists 0485 /// 0486 /// \return Server response to the request 0487 /// 0488 /// \see download 0489 /// 0490 //////////////////////////////////////////////////////////// 0491 Response upload(const std::string& localFile, const std::string& remotePath, TransferMode mode = Binary, bool append = false); 0492 0493 //////////////////////////////////////////////////////////// 0494 /// \brief Send a command to the FTP server 0495 /// 0496 /// While the most often used commands are provided as member 0497 /// functions in the sf::Ftp class, this method can be used 0498 /// to send any FTP command to the server. If the command 0499 /// requires one or more parameters, they can be specified 0500 /// in \a parameter. If the server returns information, you 0501 /// can extract it from the response using Response::getMessage(). 0502 /// 0503 /// \param command Command to send 0504 /// \param parameter Command parameter 0505 /// 0506 /// \return Server response to the request 0507 /// 0508 //////////////////////////////////////////////////////////// 0509 Response sendCommand(const std::string& command, const std::string& parameter = ""); 0510 0511 private: 0512 0513 //////////////////////////////////////////////////////////// 0514 /// \brief Receive a response from the server 0515 /// 0516 /// This function must be called after each call to 0517 /// sendCommand that expects a response. 0518 /// 0519 /// \return Server response to the request 0520 /// 0521 //////////////////////////////////////////////////////////// 0522 Response getResponse(); 0523 0524 //////////////////////////////////////////////////////////// 0525 /// \brief Utility class for exchanging datas with the server 0526 /// on the data channel 0527 /// 0528 //////////////////////////////////////////////////////////// 0529 class DataChannel; 0530 0531 friend class DataChannel; 0532 0533 //////////////////////////////////////////////////////////// 0534 // Member data 0535 //////////////////////////////////////////////////////////// 0536 TcpSocket m_commandSocket; //!< Socket holding the control connection with the server 0537 std::string m_receiveBuffer; //!< Received command data that is yet to be processed 0538 }; 0539 0540 } // namespace sf 0541 0542 0543 #endif // SFML_FTP_HPP 0544 0545 0546 //////////////////////////////////////////////////////////// 0547 /// \class sf::Ftp 0548 /// \ingroup network 0549 /// 0550 /// sf::Ftp is a very simple FTP client that allows you 0551 /// to communicate with a FTP server. The FTP protocol allows 0552 /// you to manipulate a remote file system (list files, 0553 /// upload, download, create, remove, ...). 0554 /// 0555 /// Using the FTP client consists of 4 parts: 0556 /// \li Connecting to the FTP server 0557 /// \li Logging in (either as a registered user or anonymously) 0558 /// \li Sending commands to the server 0559 /// \li Disconnecting (this part can be done implicitly by the destructor) 0560 /// 0561 /// Every command returns a FTP response, which contains the 0562 /// status code as well as a message from the server. Some 0563 /// commands such as getWorkingDirectory() and getDirectoryListing() 0564 /// return additional data, and use a class derived from 0565 /// sf::Ftp::Response to provide this data. The most often used 0566 /// commands are directly provided as member functions, but it is 0567 /// also possible to use specific commands with the sendCommand() function. 0568 /// 0569 /// Note that response statuses >= 1000 are not part of the FTP standard, 0570 /// they are generated by SFML when an internal error occurs. 0571 /// 0572 /// All commands, especially upload and download, may take some 0573 /// time to complete. This is important to know if you don't want 0574 /// to block your application while the server is completing 0575 /// the task. 0576 /// 0577 /// Usage example: 0578 /// \code 0579 /// // Create a new FTP client 0580 /// sf::Ftp ftp; 0581 /// 0582 /// // Connect to the server 0583 /// sf::Ftp::Response response = ftp.connect("ftp://ftp.myserver.com"); 0584 /// if (response.isOk()) 0585 /// std::cout << "Connected" << std::endl; 0586 /// 0587 /// // Log in 0588 /// response = ftp.login("laurent", "dF6Zm89D"); 0589 /// if (response.isOk()) 0590 /// std::cout << "Logged in" << std::endl; 0591 /// 0592 /// // Print the working directory 0593 /// sf::Ftp::DirectoryResponse directory = ftp.getWorkingDirectory(); 0594 /// if (directory.isOk()) 0595 /// std::cout << "Working directory: " << directory.getDirectory() << std::endl; 0596 /// 0597 /// // Create a new directory 0598 /// response = ftp.createDirectory("files"); 0599 /// if (response.isOk()) 0600 /// std::cout << "Created new directory" << std::endl; 0601 /// 0602 /// // Upload a file to this new directory 0603 /// response = ftp.upload("local-path/file.txt", "files", sf::Ftp::Ascii); 0604 /// if (response.isOk()) 0605 /// std::cout << "File uploaded" << std::endl; 0606 /// 0607 /// // Send specific commands (here: FEAT to list supported FTP features) 0608 /// response = ftp.sendCommand("FEAT"); 0609 /// if (response.isOk()) 0610 /// std::cout << "Feature list:\n" << response.getMessage() << std::endl; 0611 /// 0612 /// // Disconnect from the server (optional) 0613 /// ftp.disconnect(); 0614 /// \endcode 0615 /// 0616 ////////////////////////////////////////////////////////////
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|