ftp.h~
上传用户:hbyfgg
上传日期:2015-04-03
资源大小:74k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. // -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*-
  2. /*  This file is part of the KDE libraries
  3.     Copyright (C) 2000 David Faure <faure@kde.org>
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public License
  13.     along with this library; see the file COPYING.LIB.  If not, write to
  14.     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15.     Boston, MA 02110-1301, USA.
  16. */
  17. #ifndef KDELIBS_FTP_H
  18. #define KDELIBS_FTP_H
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <QtCore/QByteRef>
  22. #include <kurl.h>
  23. #include <kio/slavebase.h>
  24. #include <QtNetwork/QSslSocket>
  25. #include <QtNetwork/QTcpServer>
  26. struct FtpEntry
  27. {
  28.   QString name;
  29.   QString owner;
  30.   QString group;
  31.   QString link;
  32.   KIO::filesize_t size;
  33.   mode_t type;
  34.   mode_t access;
  35.   time_t date;
  36. };
  37. class SslServer : public QTcpServer
  38. {
  39.   private: 
  40.     void incomingConnection(int socketDescriptor);
  41.     QSslSocket *m_socket;
  42.   public:
  43.     QSslSocket *socket() { return m_socket; };
  44. };
  45. //===============================================================================
  46. // Ftp
  47. //===============================================================================
  48. class Ftp : public KIO::SlaveBase
  49. {
  50.   // Ftp() {}
  51. public:
  52.   Ftp( const QByteArray &pool, const QByteArray &app );
  53.   virtual ~Ftp();
  54.   virtual void setHost( const QString& host, quint16 port, const QString& user, const QString& pass );
  55.   /**
  56.    * Connects to a ftp server and logs us in
  57.    * m_bLoggedOn is set to true if logging on was successful.
  58.    * It is set to false if the connection becomes closed.
  59.    *
  60.    */
  61.   virtual void openConnection();
  62.   /**
  63.    * Closes the connection
  64.    */
  65.   virtual void closeConnection();
  66.   virtual void stat( const KUrl &url );
  67.   virtual void listDir( const KUrl & url );
  68.   virtual void mkdir( const KUrl & url, int permissions );
  69.   virtual void rename( const KUrl & src, const KUrl & dst, KIO::JobFlags flags );
  70.   virtual void del( const KUrl & url, bool isfile );
  71.   virtual void chmod( const KUrl & url, int permissions );
  72.   virtual void get( const KUrl& url );
  73.   virtual void put( const KUrl& url, int permissions, KIO::JobFlags flags );
  74.   //virtual void mimetype( const KUrl& url );
  75.   virtual void slave_status();
  76.   /**
  77.    * Handles the case that one side of the job is a local file
  78.    */
  79.   virtual void copy( const KUrl &src, const KUrl &dest, int permissions, KIO::JobFlags flags );
  80. private:
  81.   // ------------------------------------------------------------------------
  82.   // All the methods named ftpXyz are lowlevel methods that are not exported.
  83.   // The implement functionality used by the public high-level methods. Some
  84.   // low-level methods still use error() to emit errors. This behaviour is not
  85.   // recommended - please return a boolean status or an error code instead!
  86.   // ------------------------------------------------------------------------
  87.   QSslSocket* convertToSslSocket(QTcpSocket *tcpsocket);
  88.   bool requestDataEncryption();
  89.   int encryptDataChannel();
  90.   /**
  91.    * Status Code returned from ftpPut() and ftpGet(), used to select
  92.    * source or destination url for error messages
  93.    */
  94.   typedef enum {
  95.     statusSuccess,
  96.     statusClientError,
  97.     statusServerError
  98.   } StatusCode;
  99.   /**
  100.    * Login Mode for ftpOpenConnection
  101.    */
  102.   typedef enum {
  103.     loginDefered,
  104.     loginExplicit,
  105.     loginImplicit
  106.   } LoginMode;
  107.   /**
  108.    * Connect and login to the FTP server.
  109.    *
  110.    * @param loginMode controls if login info should be sent<br>
  111.    *  loginDefered  - must not be logged on, no login info is sent<br>
  112.    *  loginExplicit - must not be logged on, login info is sent<br>
  113.    *  loginImplicit - login info is sent if not logged on
  114.    *
  115.    * @return true on success (a login failure would return false).
  116.    */
  117.   bool ftpOpenConnection (LoginMode loginMode);
  118.   /**
  119.    * Executes any auto login macro's as specified in a .netrc file.
  120.    */
  121.   void ftpAutoLoginMacro ();
  122.   /**
  123.    * Called by openConnection. It logs us in.
  124.    * m_initialPath is set to the current working directory
  125.    * if logging on was successful.
  126.    *
  127.    * @return true on success.
  128.    */
  129.   bool ftpLogin();
  130.   /**
  131.    * ftpSendCmd - send a command (@p cmd) and read response
  132.    *
  133.    * @param maxretries number of time it should retry. Since it recursively
  134.    * calls itself if it can't read the answer (this happens especially after
  135.    * timeouts), we need to limit the recursiveness ;-)
  136.    *
  137.    * return true if any response received, false on error
  138.    */
  139.   bool ftpSendCmd( const QByteArray& cmd, int maxretries = 1 );
  140.   /**
  141.    * Use the SIZE command to get the file size.
  142.    * @param mode the size depends on the transfer mode, hence this arg.
  143.    * @return true on success
  144.    * Gets the size into m_size.
  145.    */
  146.   bool ftpSize( const QString & path, char mode );
  147.   /**
  148.    * Set the current working directory, but only if not yet current
  149.    */
  150.   bool ftpFolder(const QString& path, bool bReportError);
  151.   /**
  152.    * Runs a command on the ftp server like "list" or "retr". In contrast to
  153.    * ftpSendCmd a data connection is opened. The corresponding socket
  154.    * sData is available for reading/writing on success.
  155.    * The connection must be closed afterwards with ftpCloseCommand.
  156.    *
  157.    * @param mode is 'A' or 'I'. 'A' means ASCII transfer, 'I' means binary transfer.
  158.    * @param errorcode the command-dependent error code to emit on error
  159.    *
  160.    * @return true if the command was accepted by the server.
  161.    */
  162.   bool ftpOpenCommand( const char *command, const QString & path, char mode,
  163.                        int errorcode, KIO::fileoffset_t offset = 0 );
  164.   /**
  165.    * The counterpart to openCommand.
  166.    * Closes data sockets and then reads line sent by server at
  167.    * end of command.
  168.    * @return false on error (line doesn't start with '2')
  169.    */
  170.   bool ftpCloseCommand();
  171.   /**
  172.    * Send "TYPE I" or "TYPE A" only if required, see m_cDataMode.
  173.    *
  174.    * Use 'A' to select ASCII and 'I' to select BINARY mode.  If
  175.    * cMode is '?' the m_bTextMode flag is used to choose a mode.
  176.    */
  177.   bool ftpDataMode(char cMode);
  178.   //void ftpAbortTransfer();
  179.   /**
  180.    * Used by ftpOpenCommand, return 0 on success or an error code
  181.    */
  182.   int ftpOpenDataConnection();
  183.   /**
  184.    * closes a data connection, see ftpOpenDataConnection()
  185.    */
  186.   void ftpCloseDataConnection();
  187.   /**
  188.    * Helper for ftpOpenDataConnection
  189.    */
  190.   int ftpOpenPASVDataConnection();
  191.   /**
  192.    * Helper for ftpOpenDataConnection
  193.    */
  194.   int ftpOpenEPSVDataConnection();
  195.   /**
  196.    * Helper for ftpOpenDataConnection
  197.    */
  198.   int ftpOpenEPRTDataConnection();
  199.   /**
  200.    * Helper for ftpOpenDataConnection
  201.    */
  202.   int ftpOpenPortDataConnection();
  203.   /**
  204.    * ftpAcceptConnect - wait for incoming connection
  205.    *
  206.    * return -2 on error or timeout
  207.    * otherwise returns socket descriptor
  208.    */
  209.   int ftpAcceptConnect();
  210.   bool ftpChmod( const QString & path, int permissions );
  211.   // used by listDir
  212.   bool ftpOpenDir( const QString & path );
  213.   /**
  214.     * Called to parse directory listings, call this until it returns false
  215.     */
  216.   bool ftpReadDir(FtpEntry& ftpEnt);
  217.   /**
  218.     * Helper to fill an UDSEntry
  219.     */
  220.   void ftpCreateUDSEntry( const QString & filename, FtpEntry& ftpEnt, KIO::UDSEntry& entry, bool isDir );
  221.   void ftpShortStatAnswer( const QString& filename, bool isDir );
  222.   void ftpStatAnswerNotFound( const QString & path, const QString & filename );
  223.   /**
  224.    * This is the internal implementation of rename() - set put().
  225.    *
  226.    * @return true on success.
  227.    */
  228.   bool ftpRename( const QString & src, const QString & dst, KIO::JobFlags flags );
  229.   /**
  230.    * Called by openConnection. It opens the control connection to the ftp server.
  231.    *
  232.    * @return true on success.
  233.    */
  234.   bool ftpOpenControlConnection( const QString & host, int port, bool ignoreSslErrors = false );
  235.   /**
  236.    * closes the socket holding the control connection (see ftpOpenControlConnection)
  237.    */
  238.   void ftpCloseControlConnection();
  239.   /**
  240.    * read a response from the server (a trailing CR gets stripped)
  241.    * @param iOffset -1 to read a new line from the server<br>
  242.    *                 0 to return the whole response string
  243.    *                >0 to return the response with iOffset chars skipped
  244.    * @return the reponse message with iOffset chars skipped (or "" if iOffset points
  245.    *         behind the available data)
  246.    */
  247.   const char* ftpResponse(int iOffset);
  248.   /**
  249.    * This is the internal implementation of get() - see copy().
  250.    *
  251.    * IMPORTANT: the caller should call ftpCloseCommand() on return.
  252.    * The function does not call error(), the caller should do this.
  253.    *
  254.    * @param iError      set to an ERR_xxxx code on error
  255.    * @param iCopyFile   -1 -or- handle of a local destination file
  256.    * @param hCopyOffset local file only: non-zero for resume
  257.    * @return 0 for success, -1 for server error, -2 for client error
  258.    */
  259.   StatusCode ftpGet(int& iError, int iCopyFile, const KUrl& url, KIO::fileoffset_t hCopyOffset);
  260.   /**
  261.    * This is the internal implementation of put() - see copy().
  262.    *
  263.    * IMPORTANT: the caller should call ftpCloseCommand() on return.
  264.    * The function does not call error(), the caller should do this.
  265.    *
  266.    * @param iError      set to an ERR_xxxx code on error
  267.    * @param iCopyFile   -1 -or- handle of a local source file
  268.    * @return 0 for success, -1 for server error, -2 for client error
  269.    */
  270.   StatusCode ftpPut(int& iError, int iCopyFile, const KUrl& url, int permissions, KIO::JobFlags flags);
  271.   /**
  272.    * helper called from copy() to implement FILE -> FTP transfers
  273.    *
  274.    * @param iError      set to an ERR_xxxx code on error
  275.    * @param iCopyFile   [out] handle of a local source file
  276.    * @param sCopyFile   path of the local source file
  277.    * @return 0 for success, -1 for server error, -2 for client error
  278.    */
  279.   StatusCode ftpCopyPut(int& iError, int& iCopyFile, const QString &sCopyFile, const KUrl& url, int permissions, KIO::JobFlags flags);
  280.   /**
  281.    * helper called from copy() to implement FTP -> FILE transfers
  282.    *
  283.    * @param iError      set to an ERR_xxxx code on error
  284.    * @param iCopyFile   [out] handle of a local source file
  285.    * @param sCopyFile   path of the local destination file
  286.    * @return 0 for success, -1 for server error, -2 for client error
  287.    */
  288.   StatusCode ftpCopyGet(int& iError, int& iCopyFile, const QString &sCopyFile, const KUrl& url, int permissions, KIO::JobFlags flags);
  289. private: // data members
  290.   QString m_host;
  291.   int m_port;
  292.   QString m_user;
  293.   QString m_pass;
  294.   /**
  295.    * Where we end up after connecting
  296.    */
  297.   QString m_initialPath;
  298.   KUrl m_proxyURL;
  299.  /**
  300.    * the current working directory - see ftpFolder
  301.    */
  302.   QString m_currentPath;
  303.   /**
  304.    * the status returned by the FTP protocol, set in ftpResponse()
  305.    */
  306.   int  m_iRespCode;
  307.   /**
  308.    * the status/100 returned by the FTP protocol, set in ftpResponse()
  309.    */
  310.   int  m_iRespType;
  311.   /**
  312.    * This flag is maintained by ftpDataMode() and contains I or A after
  313.    * ftpDataMode() has successfully set the mode.
  314.    */
  315.   char m_cDataMode;
  316.   /**
  317.    * true if logged on (m_control should also be non-NULL)
  318.    */
  319.   bool m_bLoggedOn;
  320.   /**
  321.    * true if a "textmode" metadata key was found by ftpLogin(). This
  322.    * switches the ftp data transfer mode from binary to ASCII.
  323.    */
  324.   bool m_bTextMode;
  325.   /**
  326.    * true if a data stream is open, used in closeConnection().
  327.    *
  328.    * When the user cancels a get or put command the Ftp dtor will be called,
  329.    * which in turn calls closeConnection(). The later would try to send QUIT
  330.    * which won't work until timeout. ftpOpenCommand sets the m_bBusy flag so
  331.    * that the sockets will be closed immedeately - the server should be
  332.    * capable of handling this and return an error code on thru the control
  333.    * connection. The m_bBusy gets cleared by the ftpCloseCommand() routine.
  334.    */
  335.   bool m_bBusy;
  336.   bool m_bPasv;
  337.   bool m_bUseProxy;
  338.   KIO::filesize_t m_size;
  339.   static KIO::filesize_t UnknownSize;
  340.   enum
  341.   {
  342.     epsvUnknown = 0x01,
  343.     epsvAllUnknown = 0x02,
  344.     eprtUnknown = 0x04,
  345.     epsvAllSent = 0x10,
  346.     pasvUnknown = 0x20,
  347.     chmodUnknown = 0x100
  348.   };
  349.   int m_extControl;
  350.   /**
  351.    * control connection socket, only set if openControl() succeeded
  352.    */
  353.   QSslSocket *m_control;
  354.   QByteArray m_lastControlLine;
  355.   /**
  356.    * data connection socket
  357.    */
  358.   QSslSocket *m_data;
  359.   //QTcpSocket *m_data;
  360.   bool m_bIgnoreSslErrors;
  361.   SslServer *m_testserver;
  362. };
  363. #endif // KDELIBS_FTP_H