home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / mimelib / nntp.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-05-14  |  18.0 KB  |  377 lines

  1. //=============================================================================
  2. // File:       nntp.h
  3. // Contents:   Declarations for DwNntpClient
  4. // Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
  5. // WWW:        http://www.fwb.gulf.net/~dwsauder/mimepp.html
  6. //
  7. // Copyright (c) 1996, 1997 Douglas W. Sauder
  8. // All rights reserved.
  9. // 
  10. // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
  11. // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  12. // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
  13. // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. //
  15. // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  16. // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  17. // PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
  18. // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  19. // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20. //
  21. //=============================================================================
  22.  
  23. #ifndef DW_NNTP_H
  24. #define DW_NNTP_H
  25.  
  26. #include <stdio.h>
  27.  
  28. #ifndef DW_CONFIG_H
  29. #include <mimelib/config.h>
  30. #endif
  31.  
  32. #ifndef DW_PROTOCOL_H
  33. #include <mimelib/protocol.h>
  34. #endif
  35.  
  36. #ifndef DW_STRING_H
  37. #include <mimelib/string.h>
  38. #endif
  39.  
  40.  
  41. //=============================================================================
  42. //+ Name DwNntpClient -- Class for handling the client side of an NNTP session
  43. //+ Description
  44. //. {\tt DwNntpClient} is a class that handles the client side of an NNTP
  45. //. session.  Specifically, {\tt DwNntpClient} provides facilities for
  46. //. opening a connection to an NNTP server, sending commands and data to
  47. //. the server, receiving responses and data from the server, and closing
  48. //. the connection.  The protocol implemented is the Network News Transport
  49. //. Protocol, as specified in RFC-977.
  50. //.
  51. //. {\tt DwNntpClient} is derived from {\tt DwProtocolClient}.  For information
  52. //. about inherited member functions, especially member functions for detecting
  53. //. failures or errors, see the man page for {\tt DwProtocolClient}.
  54. //.
  55. //. In an NNTP session, the client sends commands to the server and receives
  56. //. responses from the server.  A client command consists of a command word
  57. //. and zero or more argument words.  A server response consists of a status
  58. //. line and possibly some additional lines of text.  The status line consists
  59. //. of a three-digit numeric reply code followed by additional information.
  60. //. The reply code indicates a success or failure condition.  In some cases,
  61. //. the server sends lines of text immediately after the status line.
  62. //. {\tt DwNntpClient} provides facilities for you to send commands to the
  63. //. server and receive responses from the server.
  64. //.
  65. //. {\tt DwNntpClient} has only a default constructor. On Win32 platforms,
  66. //. it is possible for the constructor to fail. (It calls WSAStartup().)
  67. //. You should verify that the constructor succeeded by calling the inherited
  68. //. member function {\tt DwProtocolClient::LastError()} and checking for a zero
  69. //. return value.
  70. //.
  71. //. To open a connection to the server, call the member function {\tt Open()}
  72. //. with the name of the server as an argument. {\tt Open()} accepts an
  73. //. optional argument that specifies the TCP port that the server listens to.
  74. //. The default port is the standard NNTP port (119). {\tt Open()} may fail,
  75. //. so you should check the return value to verify that it succeeded. To
  76. //. close the connection, call the inherited member function
  77. //. {\tt DwProtocolClient::Close()}. To check if a connection is open, call
  78. //. the inherited member function {\tt DwProtocolClient::IsOpen()}.
  79. //. {\tt IsOpen()} returns a boolean value that indicates whether or not
  80. //. a call to {\tt Open()} was successful; it will not detect failure in
  81. //. the network or a close operation by the remote host.
  82. //.
  83. //. For each NNTP command, {\tt DwNntpClient} has a member function that sends
  84. //. that command and receives the server's response. If the command takes any
  85. //. arguments, then those arguments are passed as function arguments to the
  86. //. command function. The command functions return the numeric value of the
  87. //. three-digit reply code returned by the server. Your program must check
  88. //. the reply code to determine whether or not the command was accepted and
  89. //. performed by the server.
  90. //. In some cases, because of a communications error or some other error,
  91. //. it is not possible for the command function to send the command or
  92. //. receive the response.  When this happens, the command function will
  93. //. return 0.  You can determine the precise error or failure by calling
  94. //. the inherited member functions {\tt DwProtocolClient::LastError()} or
  95. //. {\tt DwProtocolClient::LastFailure()}.
  96. //.
  97. //. After each command is sent, {\tt DwNntpClient} receives the server's
  98. //. response and remembers it. The member function {\tt ReplyCode()}
  99. //. returns the numeric value of the reply code received in response to
  100. //. the last command. {\tt StatusResponse()} returns the entire status
  101. //. response from the server, including the reply code. If no status
  102. //. response is received, possibly because of a communications error
  103. //. or failure, {\tt ReplyCode()} returns zero and {\tt StatusResponse()}
  104. //. returns an empty string.
  105. //.
  106. //. The server sends a status response, including a reply code, for all
  107. //. all NNTP commands. For some commands, such as when the client requests
  108. //. an article body, the server sends a multi-line text response immediately
  109. //. following the status response. Multi-line text responses
  110. //. can be received in either of two ways. The simplest way is to call the
  111. //. member function {\tt TextResponse()} after a command completes
  112. //. successfully. This simple method works fine for non-interactive
  113. //. applications. It can be a problem in interactive applications, however,
  114. //. because there is no data to display to a user until the entire text
  115. //. response is retrieved. An alternative method allows your program to
  116. //. retrieve the text response one line at a time as it is received.
  117. //. To use this method, you must define a subclass of {\tt DwObserver}
  118. //. and assign an object of that class to the {\tt DwNntpClient} object
  119. //. using the member function {\tt SetObserver()}. {\tt DwObserver} is an
  120. //. abstract class, declared in protocol.h, that has just one pure virtual
  121. //. member function {\tt Notify()}. After each line of the text response
  122. //. is received, {\tt DwNntpClient} will call the {\tt Notify()} member
  123. //. function of its assigned {\tt DwObserver} object. Each invocation of
  124. //. {\tt Notify()} should call the {\tt DwNntpClient} member function
  125. //. {\tt TextResponse()} to retrieve the next line of the text response.
  126. //. Note that you cannot use both of these methods at the same time: if
  127. //. an observer is assigned, {\tt TextResponse()} returns only the last
  128. //. line received, not the entire multi-line text response.
  129. //.
  130. //. Certain NNTP commands, such as the POST command, require the NNTP client
  131. //. to send multiple lines of text to the server. To perform this bulk data
  132. //. transfer, {\tt DwNntpClient} provides the member function
  133. //. {\tt SendData()}.  In the current implementation, {\tt SendData()} does
  134. //. not convert end of line characters, so it is your responsibility to
  135. //. convert the end of line characters to CR LF, if necessary.  (You may
  136. //. use the utility function {\tt DwToCrLfEol()} to do the conversion.)
  137. //. {\tt SendData()} will perform the character stuffing to protect '.' at
  138. //. the beginning of a line, and it will append the final [CR LF] '.' CR LF.
  139. //. It is possible to divide data and make multiple calls to {\tt SendData()};
  140. //. however, if you do so, please note the following paragraph.
  141. //.
  142. //. Note: Because of a feature (some might say bug) in the current
  143. //. implementation, {\tt SendData()} will not detect a '.' at the beginning
  144. //. of a line if the CR LF '.' sequence is split between two calls to
  145. //. {\tt SendData()}.  This problem will probably be resolved in a future
  146. //. version, but be aware that such a change will require a change in
  147. //. {\tt DwNntpClient}'s interface.
  148. //=============================================================================
  149.  
  150. //+ Noentry ~DwNntpClient
  151.  
  152.  
  153. class DW_EXPORT DwNntpClient : public DwProtocolClient {
  154.  
  155. friend class NNTP;
  156. friend class NNTPObserver;
  157.     
  158. public:
  159.  
  160.     enum {
  161.         kCmdNoCommand=0,
  162.         kCmdArticle,
  163.         kCmdBody,
  164.         kCmdHead,
  165.         kCmdStat,
  166.         kCmdGroup,
  167.         kCmdHelp,
  168.         kCmdIhave,
  169.         kCmdLast,
  170.         kCmdList,
  171.         kCmdNewgroups,
  172.         kCmdNewnews,
  173.         kCmdNext,
  174.         kCmdPost,
  175.         kCmdQuit,
  176.         kCmdSlave
  177.     };
  178.  
  179.     DwNntpClient();
  180.     //. Initializes the {\tt DwNntpClient} object.
  181.     //. It is possible for the constructor to fail.  To verify that the
  182.     //. constructor succeeded, call the member function {\tt LastError()}
  183.     //. and check that it returns zero.  (In the Win32 implementation, the
  184.     //. constructor calls the Winsock function {\tt WSAStartup()}, which
  185.     //. may fail.)
  186.  
  187.     virtual ~DwNntpClient();
  188.  
  189.     virtual int Open(const char* aServer, DwUint16 aPort=119);
  190.     //. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}.
  191.     //. {\tt aServer} may be either a host name, such as "news.acme.com" or
  192.     //. an IP number in dotted decimal format, such as "147.81.64.60".  The
  193.     //. default value for {\tt aPort} is 119, the well-known port for NNTP
  194.     //. assigned by the Internet Assigned Numbers Authority (IANA).
  195.     //.
  196.     //. If the connection attempt succeeds, the server sends a response.
  197.     //. {\tt Open()} returns the server's numeric reply code.  The full
  198.     //. response from the server can be retrieved by calling
  199.     //. {\tt StatusResponse()}.
  200.     //.
  201.     //. If the connection attempt fails, {\tt Open()} returns 0.  To determine
  202.     //. what error occurred when a connection attempt fails, call the inherited
  203.     //. member function {\tt DwProtocolClient::LastError()}.  To determine if
  204.     //. a failure also occurred, call the inherited member function
  205.     //. {\tt DwProtocolClient::LastFailure()}.
  206.  
  207.     DwObserver* SetObserver(DwObserver* aObserver);
  208.     //. Sets the observer object that interacts with the {\tt DwNntpClient}
  209.     //. object to retrieve a multi-line text response.  If an observer is set,
  210.     //. {\tt DwNntpClient} will call the observer's {\tt Notify()} method
  211.     //. after each line of the text response is received.  To remove
  212.     //. an observer, call {\tt SetObserver()} with a NULL argument.
  213.     //. {\tt SetObserver()} returns the previously set observer, or NULL if
  214.     //. no observer was previously set.
  215.  
  216.     int ReplyCode() const;
  217.     //. Returns the numeric value of the three-digit reply code received
  218.     //. from the server in response to the last client command.  If no
  219.     //. response was received, {\tt ReplyCode()} returns zero.
  220.  
  221.     const DwString& StatusResponse() const;
  222.     //. Returns the entire status response last received from the server.
  223.     //. If no response was received, perhaps because of a communications
  224.     //. failure, {\tt StatusResponse()} returns an empty string.
  225.  
  226.     const DwString& TextResponse() const;
  227.     //. If no observer is set for this object, {\tt TextResponse()} returns
  228.     //. a string that comprises the entire sequence of lines received from
  229.     //. the server.  Otherwise, if an observer {\tt is} set for this object,
  230.     //. {\tt TextResponse()} returns only the most recent line received.
  231.  
  232.     int Article(int aNumber=(-1));
  233.     int Article(const char* aMsgid);
  234.     //. Sends the NNTP ARTICLE command and returns the reply code received
  235.     //. from the server. If no response is received, the function returns
  236.     //. zero.
  237.     //. The optional argument {\tt aNumber} specifies the number of an
  238.     //. article to retrieve. If {\tt Article()} is called with the default
  239.     //. argument, the ARTICLE command is sent to the server with no argument.
  240.     //. {\tt aMsgId} specifies the message id of an article to retrieve.
  241.  
  242.     int Body(int aNumber=(-1));
  243.     int Body(const char* aMsgid);
  244.     //. Sends the NNTP BODY command and returns the reply code received
  245.     //. from the server. If no response is received, the function returns
  246.     //. zero.
  247.     //. The optional argument {\tt aNumber} specifies the number of an
  248.     //. article whose body should be retrieved. If {\tt Body()} is called
  249.     //. with the default argument, the BODY command is sent to the server
  250.     //. with no argument. {\tt aMsgId} specifies the message id of the
  251.     //. article to access.
  252.  
  253.     int Head(int aNumber=(-1));
  254.     int Head(const char* aMsgid);
  255.     //. Sends the NNTP HEAD command and returns the reply code received
  256.     //. from the server. If no response is received, the function returns
  257.     //. zero.
  258.     //. The optional argument {\tt aNumber} specifies the number of an
  259.     //. article whose header lines should be retrieved. If {\tt Head()}
  260.     //. is called with the default argument, the HEAD command is sent to
  261.     //. the server with no argument. {\tt aMsgId} specifies the message id
  262.     //. of the article to access.
  263.  
  264.     int Stat(int aNumber=(-1));
  265.     int Stat(const char* aMsgid);
  266.     //. Sends the NNTP STAT command and returns the reply code received
  267.     //. from the server. If no response is received, the function returns
  268.     //. zero.
  269.     //. The optional argument {\tt aNumber} specifies the number of an
  270.     //. article to access. If {\tt Stat()} is called with the default
  271.     //. argument, the STAT command is sent to the server with no argument.
  272.     //. {\tt aMsgId} specifies the message id of the article to access.
  273.  
  274.     int Group(const char* aNewsgroupName);
  275.     //. Sends the NNTP GROUP command and returns the reply code received from
  276.     //. the server.  The argument {\tt aNewsgroupName} specifies the newgroup
  277.     //. to be selected. If no response is received, the function returns zero.
  278.  
  279.     int Help();
  280.     //. Sends the NNTP HELP command and returns the reply code received from
  281.     //. the server.  If no response is received, the function returns zero.
  282.  
  283.     int Ihave(const char* aMsgId);
  284.     //. Sends the NNTP IHAVE command and returns the reply code received from
  285.     //. the server.  {\tt aMsgId} specifies the message id of the article
  286.     //. to be sent.  If no response is received, the function returns zero.
  287.  
  288.     int Last();
  289.     //. Sends the NNTP LAST command and returns the reply code received from
  290.     //. the server.  If no response is received, the function returns zero.
  291.  
  292.     int List();
  293.     //. Sends the NNTP LIST command and returns the reply code received from
  294.     //. the server.  If no response is received, the function returns zero.
  295.  
  296.     int Newgroups(const char* aDate, const char* aTime,
  297.         DwBool aIsGmt=DwFalse, const char* aDistributions=0);
  298.     //. Sends the NNTP NEWGROUPS command and returns the reply code received
  299.     //. from the server.  If no response is received, the function returns
  300.     //. zero.
  301.     //. {\tt aDate} is the date in the form YYMMDD, where YY is the two
  302.     //. digit year, MM is the month, and DD is the day of the month.
  303.     //. {\tt aTime} is the time in the form HHMMSS, where HH is hours,
  304.     //. MM is minutes, and SS is seconds. If {\tt aIsGmt} is true,
  305.     //. the optional GMT argument will be sent. {\tt aDistributions}
  306.     //. specifies the optional list of distribution groups.
  307.  
  308.     int Newnews(const char* aNewsgroups, const char* aDate,
  309.         const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistribution=0);
  310.     //. Sends the NNTP NEWNEWS command and returns the reply code received
  311.     //. from the server.  If no response is received, the function returns
  312.     //. zero.
  313.     //. {\tt aNewsgroups} is the newsgroups argument for the command.
  314.     //. {\tt aDate} is the date in the form YYMMDD, where YY is the two
  315.     //. digit year, MM is the month, and DD is the day of the month.
  316.     //. {\tt aTime} is the time in the form HHMMSS, where HH is hours,
  317.     //. MM is minutes, and SS is seconds. If {\tt aIsGmt} is true,
  318.     //. the optional GMT argument will be sent. {\tt aDistributions}
  319.     //. specifies the optional list of distribution groups.
  320.  
  321.     int Next();
  322.     //. Sends the NNTP NEXT command and returns the reply code received from
  323.     //. the server.  If no response is received, perhaps because of an error,
  324.     //. the function returns zero.
  325.  
  326.     int Post();
  327.     //. Sends the NNTP POST command and returns the reply code received from
  328.     //. the server.  If no response is received, perhaps because of an error,
  329.     //. the function returns zero.
  330.  
  331.     int Quit();
  332.     //. Sends the NNTP QUIT command and returns the reply code received from
  333.     //. the server.  If no response is received, perhaps because of an error,
  334.     //. the function returns zero.
  335.  
  336.     int Slave();
  337.     //. Sends the NNTP SLAVE command and returns the reply code received from
  338.     //. the server.  If no response is received, perhaps because of an error,
  339.     //. the function returns zero.
  340.  
  341.     int SendData(const DwString& aStr);
  342.     int SendData(const char* aBuf, int aBufLen);
  343.     //. Sends bulk data to the server and returns the reply code received.
  344.     //. A bulk data transfer follows a POST or IHAVE command and is used to
  345.     //. send a complete article to the server.
  346.     //.
  347.     //. In the current implementation, {\tt SendData()} does not convert end
  348.     //. of line characters, so it is your responsibility to convert the end
  349.     //. of line characters to CR LF, if necessary.  (You may use the utility
  350.     //. function {\tt DwToCrLfEol()} to do the conversion.)  {\tt SendData()}
  351.     //. will perform the character stuffing to protect '.' at the beginning of
  352.     //. a line, and it will append the final [CR LF] '.' CR LF.  It is possible
  353.     //. to divide the data and make multiple calls to {\tt SendData()}; however,
  354.     //. this may cause problems in the current implementation if a CR LF '.'
  355.     //. sequence is split between calls.
  356.  
  357. private:
  358.  
  359.     char*       mSendBuffer;
  360.     char*       mRecvBuffer;
  361.     int         mLastChar;
  362.     int         mLastLastChar;
  363.     int         mNumRecvBufferChars;
  364.     int         mRecvBufferPos;
  365.     int         mReplyCode;
  366.     DwString    mStatusResponse;
  367.     DwString    mTextResponse;
  368.     DwObserver* mObserver;
  369.  
  370.     virtual int PGetLine(char** aPtr, int* aLen);
  371.     virtual void PGetStatusResponse();
  372.     virtual void PGetTextResponse();
  373.  
  374. };
  375.  
  376. #endif
  377.