/*
* ftp.h
*
* File Transfer Protocol Server/Client channel classes
* As per RFC 959 and RFC 1123
*
* Portable Windows Library
*
* Copyright (c) 1993-2002 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Contributor(s): ______________________________________.
*
* $Log: ftp.h,v $
* Revision 1.18 2005/11/30 12:47:37 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.17 2004/11/11 07:34:50 csoutheren
* Added #include <ptlib.h>
*
* Revision 1.16 2003/09/17 05:43:49 csoutheren
* Removed recursive includes
*
* Revision 1.15 2002/11/06 22:47:23 robertj
* Fixed header comment (copyright etc)
*
* Revision 1.14 2002/09/16 01:08:59 robertj
* Added #define so can select if #pragma interface/implementation is used on
* platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
*
* Revision 1.13 2001/09/10 00:28:21 robertj
* Fixed extra CR in comments.
*
* Revision 1.12 2000/06/21 01:01:21 robertj
* AIX port, thanks Wolfgang Platzer (wolfgang.platzer@infonova.at).
*
* Revision 1.11 1999/03/09 08:01:46 robertj
* Changed comments for doc++ support (more to come).
*
* Revision 1.10 1999/02/16 08:07:10 robertj
* MSVC 6.0 compatibility changes.
*
* Revision 1.9 1998/11/30 02:50:45 robertj
* New directory structure
*
* Revision 1.8 1998/09/23 06:19:26 robertj
* Added open source copyright license.
*
* Revision 1.7 1996/10/26 01:39:41 robertj
* Added check for security breach using 3 way FTP transfer or use of privileged PORT.
*
* Revision 1.6 1996/09/14 13:09:08 robertj
* Major upgrade:
* rearranged sockets to help support IPX.
* added indirect channel class and moved all protocols to descend from it,
* separating the protocol from the low level byte transport.
*
* Revision 1.5 1996/05/23 09:56:24 robertj
* Changed FTP so can do passive/active mode on all data transfers.
*
* Revision 1.4 1996/03/31 08:45:57 robertj
* Added QUIT command sent on FTP socket close.
*
* Revision 1.3 1996/03/26 00:50:28 robertj
* FTP Client Implementation.
*
* Revision 1.2 1996/03/18 13:33:10 robertj
* Fixed incompatibilities to GNU compiler where PINDEX != int.
*
* Revision 1.1 1996/03/04 12:14:18 robertj
* Initial revision
*
*/
#ifndef _PFTPSOCKET
#define _PFTPSOCKET
#ifdef P_USE_PRAGMA
#pragma interface
#endif
#include <ptclib/inetprot.h>
#include <ptlib/sockets.h>
/**
File Transfer Protocol base class.
*/
class PFTP : public PInternetProtocol
{
PCLASSINFO(PFTP, PInternetProtocol);
public:
/// FTP commands
enum Commands {
USER, PASS, ACCT, CWD, CDUP, SMNT, QUIT, REIN, PORT, PASV, TYPE,
STRU, MODE, RETR, STOR, STOU, APPE, ALLO, REST, RNFR, RNTO, ABOR,
DELE, RMD, MKD, PWD, LIST, NLST, SITE, SYST, STATcmd, HELP, NOOP,
NumCommands
};
/// Types for file transfer
enum RepresentationType {
ASCII,
EBCDIC,
Image
};
/// File transfer mode on data channel
enum DataChannelType {
NormalPort,
Passive
};
/// Listing types
enum NameTypes {
ShortNames,
DetailedNames
};
/** Send the PORT command for a transfer.
@return Boolean indicated PORT command was successful
*/
BOOL SendPORT(
const PIPSocket::Address & addr, ///< Address for PORT connection. IP address to connect back to
WORD port ///< Port number for PORT connection.
);
protected:
/// Construct an ineternal File Transfer Protocol channel.
PFTP();
};
/**
File Transfer Protocol client channel class.
*/
class PFTPClient : public PFTP
{
PCLASSINFO(PFTPClient, PFTP);
public:
/// Declare an FTP client socket.
PFTPClient();
/// Delete and close the socket.
~PFTPClient();
/**@name Overrides from class PSocket. */
//@{
/** Close the socket, and if connected as a client, QUITs from server.
@return
TRUE if the channel was closed and the QUIT accepted by the server.
*/
virtual BOOL Close();
//@}
/**@name New functions for class */
//@{
/** Log in to the remote host for FTP.
@return
TRUE if the log in was successfull.
*/
BOOL LogIn(
const PString & username, ///< User name for FTP log in.
const PString & password ///< Password for the specified user name.
);
/** Get the type of the remote FTP server system, eg Unix, WindowsNT etc.
@return
String for the type of system.
*/
PString GetSystemType();
/** Set the transfer type.
@return
TRUE if transfer type set.
*/
BOOL SetType(
RepresentationType type ///< RepresentationTypeof file to transfer
);
/** Change the current directory on the remote FTP host.
@return
TRUE if the log in was successfull.
*/
BOOL ChangeDirectory(
const PString & dirPath ///< New directory
);
/** Get the current working directory on the remote FTP host.
@return
String for the directory path, or empty string if an error occurred.
*/
PString GetCurrentDirectory();
/** Get a list of files from the current working directory on the remote
FTP host.
@return
String array for the files in the directory.
*/
PStringArray GetDirectoryNames(
NameTypes type = ShortNames, ///< Detail level on a directory entry.
DataChannelType channel = Passive ///< Data channel type.
);
/** Get a list of files from the current working directory on the remote
FTP host.
@return
String array for the files in the directory.
*/
PStringArray GetDirectoryNames(
const PString & path, ///< Name to get details for.
NameTypes type = ShortNames, ///< Detail level on a directory entry.
DataChannelType channel = Passive ///< Data channel type.
);
/** Get status information for the file path specified.
@return
String giving file status.
*/
PString GetFileStatus(
const PString & path, ///< Path to get status for.
DataChannelType channel = Passive ///< Data channel type.
);
/**Begin retreiving a file from the remote FTP server. The second
parameter indicates that the transfer is on a normal or passive data
channel. In short, a normal transfer the server connects to the
client and in passive mode the client connects to the server.
@return
Socket to read data from, or NULL if an error occurred.
*/
PTCPSocket * GetFile(
const PString & filename, ///< Name of file to get
DataChannelType channel = NormalPort ///< Data channel type.
);
/**Begin storing a file to the remote FTP server. The second parameter
indicates that the transfer is on a normal or passive data channel.
In short, a normal transfer the server connects to the client and in
passive mode the client connects to the server.
@return
Socket to write data to, or NULL if an error occurred.
*/
PTCPSocket * PutFile(
const PString & filename, ///< Name of file to get
DataChannelType channel = NormalPort ///< Data channel type.
);
//@}
protected:
/// Call back to verify open succeeded in an PInternetProtocol class
virtual BOOL OnOpen();
PTCPSocket * NormalClientTransfer(
Commands cmd,
const PString & args
);
PTCPSocket * PassiveClientTransfer(
Commands cmd,
const PString & args
);
/// Port number on remote system
WORD remotePort;
};
/**
File Transfer Protocol server channel class.
*/
class PFTPServer : public PFTP
{
PCLASSINFO(PFTPServer, PFTP);
public:
enum { MaxIllegalPasswords = 3 };
/// declare a server socket
PFTPServer();
PFTPServer(
const PString & readyString ///< Sign on string on connection ready.
);
/// Delete the server, cleaning up passive sockets.
~PFTPServer();
// New functions for class
/**
Get the string printed when a user logs in default value is a string
giving the user name
*/
virtual PString GetHelloString(const PString & user) const;
/// return the string printed just before exiting
virtual PString GetGoodbyeString(const PString & user) const;
/// return the string to be returned by the SYST command
virtual PString GetSystemTypeString() const;
/// return the thirdPartyPort flag, allowing 3 host put and get.
BOOL GetAllowThirdPartyPort() const { return thirdPartyPort; }
/// Set the thirdPartyPort flag.
void SetAllowThirdPartyPort(BOOL state) { thirdPartyPort = state; }
/** Process commands, dispatching to the appropriate virtual function. This
is used when the socket is acting as a server.
@return
TRUE if more processing may be done, FALSE if the QUIT command was
received or the #OnUnknown()# function returns FALSE.
*/
BOOL ProcessCommand();
/** Dispatching to the appropriate virtual function. This is used when the
socket is acting as a server.
@return
TRUE if more processing may be done, FALSE if the QUIT command was
received or the #OnUnknown()# function returns FALSE.
*/
virtual BOOL DispatchCommand(
PINDEX code, ///< Parsed command code.
const PString & args ///< Arguments to command.
);
/** Check to see if the command requires the server to be logged in before
it may be processed.
@return
TRUE if the command required the user to be logged in.
*/
virtual BOOL CheckLoginRequired(
PINDEX cmd ///< Command to check if log in required.
);
/** Validate the user name and password for access. After three invalid
attempts, the socket will close and FALSE is returned.
Default implementation returns TRUE for all strings.
@return
TRUE if user can access, otherwise FALSE
*/
virtual BOOL AuthoriseUser(
const PString & user, ///< User name to authorise.
const PString & password, ///< Password supplied for the user.
BOOL & replied ///< Indication that a reply was sent to client.
);
/** Handle an unknown command.
@return
TRUE if more processing may be done, FALSE if the
#ProcessCommand()# function is to return FALSE.
*/
virtual BOOL OnUnknown(
const PCaselessString & command ///< Complete command line received.
);
/** Handle an error in command.
@return
TRUE if more processing may be done, FALSE if the
#ProcessCommand()# function is to return FALSE.
*/
virtual void OnError(
PINDEX errorCode, ///< Error code to use
PINDEX cmdNum, ///< Command that had the error.
const char * msg ///< Error message.
);
/// Called for syntax errors in commands.
virtual void OnSyntaxError(
PINDEX cmdNum ///< Command that had the syntax error.
);
/// Called for unimplemented commands.
virtual void OnNotImplemented(
PINDEX cmdNum ///< Command that was not implemented.
);
/// Called for successful commands.
virtual void OnCommandSuccessful(
PINDEX cmdNum ///< Command that had was successful.
);
// the following commands must be implemented by all servers
// and can be performed without logging in
virtual BOOL OnUSER(const PCaselessString & args);
virtual BOOL OnPASS(const PCaselessString & args); // officially optional, but should be done
virtual BOOL OnQUIT(const PCaselessString & args);
virtual BOOL OnPORT(const PCaselessString & args);
virtual BOOL OnSTRU(const PCaselessString & args);
virtual BOOL OnMODE(const PCaselessString & args);
virtual BOOL OnTYPE(const PCaselessString & args);
virtual BOOL OnNOOP(const PCaselessString & args);
virtual BOOL OnSYST(const PCaselessString & args);
virtual BOOL OnSTAT(const PCaselessString & args);
// the following commands must be implemented by all servers
// and cannot be performed without logging in
virtual BOOL OnRETR(const PCaselessString & args);
virtual BOOL OnSTOR(const PCaselessString & args);
virtual BOOL OnACCT(const PCaselessString & args);
virtual BOOL OnAPPE(const PCaselessString & args);
virtual BOOL OnRNFR(const PCaselessString & args);
virtual BOOL OnRNTO(const PCaselessString & args);
virtual BOOL OnDELE(const PCaselessString & args);
virtual BOOL OnCWD(const PCaselessString & args);
virtual BOOL OnCDUP(const PCaselessString & args);
virtual BOOL OnRMD(const PCaselessString & args);
virtual BOOL OnMKD(const PCaselessString & args);
virtual BOOL OnPWD(const PCaselessString & args);
virtual BOOL OnLIST(const PCaselessString & args);
virtual BOOL OnNLST(const PCaselessString & args);
virtual BOOL OnPASV(const PCaselessString & args);
// the following commands are optional and can be performed without
// logging in
virtual BOOL OnHELP(const PCaselessString & args);
virtual BOOL OnSITE(const PCaselessString & args);
virtual BOOL OnABOR(const PCaselessString & args);
// the following commands are optional and cannot be performed
// without logging in
virtual BOOL OnSMNT(const PCaselessString & args);
virtual BOOL OnREIN(const PCaselessString & args);
virtual BOOL OnSTOU(const PCaselessString & args);
virtual BOOL OnALLO(const PCaselessString & args);
virtual BOOL OnREST(const PCaselessString & args);
/// Send the specified file to the client.
void SendToClient(
const PFilePath & filename ///< File name to send.
);
protected:
/// Call back to verify open succeeded in an PInternetProtocol class
BOOL OnOpen();
void Construct();
PString readyString;
BOOL thirdPartyPort;
enum {
NotConnected,
NeedUser,
NeedPassword,
Connected,
ClientConnect
} state;
PIPSocket::Address remoteHost;
WORD remotePort;
PTCPSocket * passiveSocket;
char type;
char structure;
char mode;
PString userName;
int illegalPasswordCount;
};
#endif
// End of File ///////////////////////////////////////////////////////////////
syntax highlighted by Code2HTML, v. 0.9.1