You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/mimelib/mimelib/protocol.h

270 lines
11 KiB

//=============================================================================
// File: proto_un.h
// Contents: Declarations for DwClientProtocol
// Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
// WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html
//
// Copyright (c) 1996, 1997 Douglas W. Sauder
// All rights reserved.
//
// IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
// THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
// BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
//=============================================================================
#ifndef DW_PROTOCOL_H
#define DW_PROTOCOL_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef DW_CONFIG_H
#include <mimelib/config.h>
#endif
#ifndef DW_STRING_H
#include <mimelib/string.h>
#endif
class DwObserver {
public:
virtual ~DwObserver(){}
virtual void Notify()=0;
};
//=============================================================================
//+ Name DwProtocolClient -- Base class for all protocol clients
//+ Description
//. {\tt DwProtocolClient} is the base class for other classes that implement
//. specific protocols, such as SMTP, POP, and NNTP. {\tt DwProtocolClient}
//. serves two purposes. First, It combines operations common to all its
//. derived classes, such as opening a TCP connection to the server. Second,
//. it provides a platform-independent interface to the network services
//. required by its subclasses.
//.
//. There are two separate implementations of {\tt DwProtocolClient}: one for
//. Berkeley sockets under UNIX, and one for Winsock under Win32. The
//. interface is the same for both implementations, thus providing platform
//. independence.
//.
//. There are two platform-specific details that you should be aware of.
//. First, if you are writing a UNIX program, you should be sure to handle
//. the SIGPIPE signal. This signal is raised when a program tries to write
//. to a TCP connection that was shutdown by the remote host. The default
//. action for this signal is to terminate the program. To prevent this
//. from happening in your program, you should either catch the signal or
//. tell the operating system to ignore it. Second, if you are writing a
//. Win32 application for Windows NT or Windows95, you should be aware of
//. the fact that the constructor calls the Winsock function
//. {\tt WSAStartup()} to initialize the Winsock DLL. (The destructor
//. calls {\tt WSACleanup()}.) Because it is possible for {\tt WSAStartup()}
//. to fail, it is also possible that the constructor may fail. To verify
//. that the constructor has succeeded, call the member function
//. {\tt LastError()} and check that it returns zero.
//.
//. To open a connection to a server, call {\tt Open()} with the server name
//. and TCP port number as arguments. {\tt Open()} is declared virtual;
//. derived classes may override this member function. {\tt Open()} may fail,
//. so you should check the return value to verify that it succeeded. To close
//. the connection, call {\tt Close()}. To check if a connection is open,
//. call {\tt IsOpen()}. {\tt IsOpen()} returns a value that indicates whether
//. or not a call to {\tt Open()} was successful; it will not detect failure
//. in the network or a close operation by the remote host.
//.
//. {\tt DwProtocolClient} sets a timeout on receive operations on the TCP
//. connection. The default value of the timeout period is 90 seconds. To
//. change the default value, call {\tt SetReceiveTimeout()} and pass the
//. new value as an argument.
//.
//. Whenever {\tt DwProtocolClient} cannot complete an operation, it is because
//. an error has occurred. Most member functions indicate that an error has
//. occurred via their return values. For most member functions, a return
//. value of -1 indicates an error. To get the specific error that has
//. occurred, call {\tt LastError()}, which returns either the system error
//. code or a MIME++ defined error code. To get a text string that describes
//. the error, call {\tt LastErrorStr()}.
//.
//. Some errors are also considered "failures." A failure occurs when an
//. operation cannot be completed because of conditions external to the
//. program. For example, a failure occurs when the network is down or
//. when an application's user enters bad input. Errors that occur because
//. of programmer error are not considered failures. If an error occurs,
//. you should call {\tt LastError()} to determine the error, but you should
//. also call {\tt LastFailure()} to determine if a failure occurred. In
//. interactive applications, failures should always be reported to the
//. application's user. To get a text string that describes a failure,
//. call {\tt LastFailureStr()}.
//.
//. It is possible to translate the error and failure message strings to a
//. language other than English. To do this, you may override the virtual
//. function {\tt HandleError()}.
//=============================================================================
//+ Noentry mFailureCode mFailureStr mErrorCode mErrorStr mLastCommand
//+ Noentry mIsDllOpen mIsOpen mSocket mPort mServerName mReceiveTimeout
class DwProtocolClient {
public:
enum Failure {
kFailNoFailure = 0, // No failure
kFailNoWinsock = 1, // A usable Winsock DLL could not be found
kFailNetDown = 2, // The network is down
kFailHostNotFound = 3, // The server was not found
kFailConnReset = 4, // The connection was reset
kFailNetUnreachable = 5, // The network is unreachable
kFailTimedOut = 6, // Timed out while waiting for an operation
// to complete
kFailConnDropped = 7,
kFailConnRefused = 8,
kFailNoResources = 9
};
//. Enumerated values for failures.
enum Error {
kErrNoError = 0,
kErrUnknownError = 0x4000,
kErrBadParameter = 0x4001,
kErrBadUsage = 0x4002,
kErrNoWinsock = 0x4003, // Win32
kErrHostNotFound = 0x5000, // UNIX
kErrTryAgain = 0x5001, // UNIX
kErrNoRecovery = 0x5002, // UNIX
kErrNoData = 0x5003, // UNIX
kErrNoAddress = 0x5004 // UNIX
};
//. MIME++-defined error codes.
protected:
DwProtocolClient();
//. Initializes the {\tt DwProtocolClient} object.
//. In a Win32 environment, this constructor calls {\tt WSAStartup()}
//. to initialize the Winsock DLL. To verify that the DLL was initialized
//. successfully, call the member function {\tt LastError()} and verify
//. that it returns zero.
public:
virtual ~DwProtocolClient();
//. Frees the resources used by this object.
//. In a Win32 environment, the destructor calls {\tt WSACleanup()}.
virtual int Open(const char* aServer, DwUint16 aPort);
//. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}.
//. {\tt aServer} may be either a host name, such as "smtp.acme.com" or an
//. IP number in dotted decimal format, such as "147.81.64.59". If the
//. connection attempt succeeds, {\tt Open()} returns 0; othewise, it
//. returns -1. To determine what error occurred when the connection
//. attempt fails, call the member function {\tt LastError()}. To
//. determine if a failure also occurred, call the member function
//. {\tt LastFailure()}.
DwBool IsOpen() const;
//. Returns true value if a connection to the server is open.
//. {\tt IsOpen()} will return a true value if a call to {\tt Open()} was
//. successful; it will not detect failure in the network or a close
//. operation by the remote host.
int Close();
//. Closes the connection to the server. Returns 0 if successful, or
//. returns -1 if unsuccessful.
int SetReceiveTimeout(int aSecs);
//. Changes the default timeout for receive operations on the socket to
//. {\tt aSecs} seconds.
//. The default value is 90 seconds.
int LastCommand() const;
//. Returns an enumerated value indicating the last command sent to
//. the server. Enumerated values are defined in subclasses of
//. {\tt DwProtocolClient}.
int LastFailure() const;
//. Returns an enumerated value indicating what failure last occurred.
const char* LastFailureStr() const;
//. Returns a failure message string associated with the failure code
//. returned by {\tt LastFailure()}.
int LastError() const;
//. Returns an error code for the last error that occurred. Normally, the
//. error code returned is an error code returned by a system call;
//. {\tt DwProtocolClient} does no translation of error codes returned
//. by system calls. In some cases, an error code defined by MIME++ may
//. returned to indicate improper use of the {\tt DwProtocolClient} class.
const char* LastErrorStr() const;
//. Returns an error message string associated with the error code returned
//. by {\tt LastError()}.
protected:
enum {
kWSAStartup=1, // Win32
kgethostbyname,
tdesocket,
ksetsockopt,
kconnect,
ksend,
krecv,
kclose, // UNIX
kclosesocket, // Win32
tdeselect
};
// Enumerated values that indicate the system call that detected
// an error
DwBool mIsDllOpen;
DwBool mIsOpen;
int mSocket;
DwUint16 mPort;
char* mServerName;
int mReceiveTimeout;
int mLastCommand;
int mFailureCode;
const char* mFailureStr;
int mErrorCode;
const char* mErrorStr;
virtual void HandleError(int aErrorCode, int aSystemCall);
//. Interprets error codes. {\tt aErrorCode} is an error code,
//. which may be a system error code, or an error code defined by
//. {\tt DwProtocolClient}. {\tt aSystemCall} is an enumerated value
//. defined by {\tt DwProtocolClient} that indicates the last system
//. call made, which should be the system call that set the error code.
//. {\tt HandleError()} sets values for {\tt mErrorStr},
//. {\tt mFailureCode}, and {\tt mFailureStr}.
int PSend(const char* aBuf, int aBufLen);
//. Sends {\tt aBufLen} characters from the buffer {\tt aBuf}. Returns
//. the number of characters sent. If the number of characters sent
//. is less than the number of characters specified in {\tt aBufLen},
//. the caller should call {\tt LastError()} to determine what, if any,
//. error occurred. To determine if a failure also occurred, call the
//. member function {\tt LastFailure()}.
int PReceive(char* aBuf, int aBufSize);
//. Receives up to {\tt aBufSize} characters into the buffer {\tt aBuf}.
//. Returns the number of characters received. If zero is returned, the
//. caller should call the member function {\tt LastError()} to determine
//. what, if any, error occurred. To determine if a failure also occurred,
//. call the member function {\tt LastFailure()}.
};
#endif