1 //
2 // HtNNTP.cc
3 //
4 // HtNNTP: Interface classes for NNTP messaging
5 //
6 // Gabriele Bartolini - Prato - Italia
7 // started: 01.08.2000
8 //
9 // Including:
10 // 	 -  Generic class
11 // 	 -  Response message class
12 //
13 // Part of the ht://Dig package   <http://www.htdig.org/>
14 // Copyright (c) 2000-2004 The ht://Dig Group
15 // For copyright details, see the file COPYING in your distribution
16 // or the GNU Library General Public License (LGPL) version 2 or later
17 // <http://www.gnu.org/copyleft/lgpl.html>
18 //
19 // $Id: HtNNTP.cc,v 1.5 2004/05/28 13:15:23 lha Exp $
20 //
21 
22 #ifdef HAVE_CONFIG_H
23 #include "htconfig.h"
24 #endif /* HAVE_CONFIG_H */
25 
26 #include "lib.h"
27 #include "Transport.h"
28 #include "HtNNTP.h"
29 
30 #include <signal.h>
31 #include <sys/types.h>
32 #include <ctype.h>
33 #include <stdio.h>      // for sscanf
34 
35 // for setw()
36 #ifdef HAVE_STD
37 #include <iomanip>
38 #ifdef HAVE_NAMESPACES
39 using namespace std;
40 #endif
41 #else
42 #include <iomanip.h>
43 #endif /* HAVE_STD */
44 
45 #if 1
46 typedef void (*SIGNAL_HANDLER) (...);
47 #else
48 typedef SIG_PF SIGNAL_HANDLER;
49 #endif
50 
51    // Stats information
52    	 int HtNNTP::_tot_seconds = 0;
53    	 int HtNNTP::_tot_requests = 0;
54    	 int HtNNTP::_tot_bytes = 0;
55 
56 ///////
57    //    HtNNTP_Response class
58    //
59    //    Response message sent by the remote NNTP server
60 ///////
61 
62 
63 // Construction
64 
HtNNTP_Response()65 HtNNTP_Response::HtNNTP_Response()
66 {
67 
68 }
69 
70 
71 // Destruction
72 
~HtNNTP_Response()73 HtNNTP_Response::~HtNNTP_Response()
74 {
75 }
76 
77 
Reset()78 void HtNNTP_Response::Reset()
79 {
80 
81    // Call the base class method in order to reset
82    // the base class attributes
83 
84    Transport_Response::Reset();
85 
86 }
87 
88 
89 
90 
91 ///////
92    //    HtNNTP generic class
93    //
94    //
95 ///////
96 
97 
98 // Construction
99 
HtNNTP()100 HtNNTP::HtNNTP()
101 : Transport(new Connection()),
102    _bytes_read(0),
103    _useproxy(0)
104 {
105 }
106 
107 // Destruction
108 
~HtNNTP()109 HtNNTP::~HtNNTP()
110 {
111   // Free the connection
112   //
113   CloseConnection();
114   if (_connection)
115     delete _connection;
116   _connection = 0;
117 }
118 
119 
120 ///////
121    //    Manages the requesting process
122 ///////
123 
Request()124 Transport::DocStatus HtNNTP::Request()
125 {
126 
127    DocStatus result = Document_ok;
128    _response.Reset();   // Reset the response
129 
130    return result;
131 
132 }
133 
134 
SetRequestCommand(String & cmd)135 void HtNNTP::SetRequestCommand(String &cmd)
136 {
137 
138    cmd << "\r\n";
139 
140 }
141 
142 
143 
144 
145 //*****************************************************************************
146 // int HtNNTP::ParseHeader()
147 //   Parse the header of the document
148 //
ParseHeader()149 int HtNNTP::ParseHeader()
150 {
151     String	line = 0;
152     int		inHeader = 1;
153 
154     if (_response._modification_time)
155     {
156 	delete _response._modification_time;
157 	_response._modification_time=NULL;
158     }
159     while (inHeader)
160     {
161 
162       line.trunc();
163 
164       if(! _connection->Read_Line(line, "\n"))
165          return -1;  // Connection down
166 
167       _bytes_read+=line.length();
168       line.chop('\r');
169 
170       if (line.length() == 0)
171          inHeader = 0;
172       else
173       {
174          // Found a not-empty line
175 
176          if (debug > 3)
177             cout << "Header line: " << line << endl;
178 
179          // Status - Line check
180          char	*token = line.get();
181 
182          while (*token && !isspace(*token))
183             token++;
184 
185          while (*token && isspace(*token))
186             token++;
187       }
188     }
189 
190     if (_response._modification_time == NULL)
191     {
192       if (debug > 3)
193          cout << "No modification time returned: assuming now" << endl;
194 
195          //Set the modification time
196       _response._modification_time = new HtDateTime;
197       _response._modification_time->ToGMTime(); // Set to GM time
198 
199     }
200 
201     return 1;
202 
203 }
204 
205 
GetDocumentStatus(HtNNTP_Response & r)206 HtNNTP::DocStatus HtNNTP::GetDocumentStatus(HtNNTP_Response &r)
207 {
208 
209    // Let's give a look at the return status code
210 
211    HtNNTP::DocStatus returnStatus=Document_not_found;
212    int statuscode;
213 
214    statuscode=r.GetStatusCode();
215 
216    if(statuscode==200)
217    {
218 	    returnStatus = Document_ok;   // OK
219    }
220 
221    // Exit the function
222    return returnStatus;
223 
224 }
225 
226 
ReadBody()227 int HtNNTP::ReadBody()
228 {
229 
230     _response._contents = 0;	// Initialize the string
231 
232     char	docBuffer[8192];
233     int		bytesRead = 0;
234     int		bytesToGo = _response._content_length;
235 
236     if (bytesToGo < 0 || bytesToGo > _max_document_size)
237         bytesToGo = _max_document_size;
238 
239     if( _connection == NULL )
240       {
241 	cout << "HtNNTP::ReadBody: _connection is NULL\n";
242 	exit(0);
243       }
244 
245 
246     while (bytesToGo > 0)
247     {
248         int len = bytesToGo< (int)sizeof(docBuffer) ? bytesToGo : (int)sizeof(docBuffer);
249         bytesRead = _connection->Read(docBuffer, len);
250         if (bytesRead <= 0)
251             break;
252 
253 	_response._contents.append(docBuffer, bytesRead);
254 
255 	bytesToGo -= bytesRead;
256 
257 	_bytes_read+=bytesRead;
258 
259     }
260 
261     // Set document length
262     _response._document_length = _response._contents.length();
263 
264    return bytesRead;
265 
266 }
267 
268 
269 ///////
270    //    Show the statistics
271 ///////
272 
ShowStatistics(ostream & out)273 ostream &HtNNTP::ShowStatistics (ostream &out)
274 {
275    Transport::ShowStatistics(out);  // call the base class method
276 
277    out << " NNTP Requests             : " << GetTotRequests() << endl;
278    out << " NNTP KBytes requested     : " << (double)GetTotBytes()/1024 << endl;
279    out << " NNTP Average request time : " << GetAverageRequestTime()
280       << " secs" << endl;
281 
282    out << " NNTP Average speed        : " << GetAverageSpeed()/1024
283       << " KBytes/secs" << endl;
284 
285    return out;
286 }
287