summaryrefslogtreecommitdiff
path: root/src/connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/connection.cpp')
-rw-r--r--src/connection.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/src/connection.cpp b/src/connection.cpp
new file mode 100644
index 0000000..a277ea7
--- /dev/null
+++ b/src/connection.cpp
@@ -0,0 +1,432 @@
1#include "connection.h"
2#include <string.h>
3#include <stdio.h>
4#include <errno.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <netinet/in.h>
10#include <netdb.h>
11#include <arpa/inet.h>
12
13Connection::Connection()
14{
15 nSocket = -1;
16 bActive = false;
17 bDisconnectMe = false;
18 pProtocol = NULL;
19}
20
21Connection::~Connection()
22{
23 if( pProtocol != NULL ) delete pProtocol;
24}
25
26bool Connection::appendOutput( const char *lpOutput, int nSize )
27{
28 return xOutputBuf.appendData( lpOutput, nSize );
29}
30
31bool Connection::appendOutput( const char lOutput )
32{
33 return xOutputBuf.appendData( lOutput );
34}
35
36bool Connection::appendOutput( const short lOutput )
37{
38 return xOutputBuf.appendData( lOutput );
39}
40
41bool Connection::appendOutput( const int lOutput )
42{
43 return xOutputBuf.appendData( lOutput );
44}
45
46bool Connection::appendOutput( const long lOutput )
47{
48 return xOutputBuf.appendData( lOutput );
49}
50
51bool Connection::appendOutput( const float lOutput )
52{
53 return xOutputBuf.appendData( lOutput );
54}
55
56bool Connection::appendOutput( const double lOutput )
57{
58 return xOutputBuf.appendData( lOutput );
59}
60
61bool Connection::appendOutput( const unsigned char lOutput )
62{
63 return xOutputBuf.appendData( lOutput );
64}
65
66bool Connection::appendOutput( const unsigned short lOutput )
67{
68 return xOutputBuf.appendData( lOutput );
69}
70
71bool Connection::appendOutput( const unsigned long lOutput )
72{
73 return xOutputBuf.appendData( lOutput );
74}
75
76bool Connection::appendOutput( const unsigned int lOutput )
77{
78 return xOutputBuf.appendData( lOutput );
79}
80
81bool Connection::appendInput( const char *lpInput, int nSize )
82{
83 return xInputBuf.appendData( lpInput, nSize );
84}
85
86int Connection::scanInputFor( char cTarget )
87{
88 const char *lpTmp = xInputBuf.getData();
89 int jMax = xInputBuf.getLength();
90
91 for( int j = 0; j < jMax; j++ )
92 {
93 if( lpTmp[j] == cTarget )
94 {
95 return j;
96 }
97 }
98
99 return -1;
100}
101
102const char *Connection::getOutput()
103{
104 return xOutputBuf.getData();
105}
106
107const char *Connection::getInput()
108{
109 return xInputBuf.getData();
110}
111
112void Connection::setSocket( int nNewSocket )
113{
114 nSocket = nNewSocket;
115}
116
117int Connection::getSocket()
118{
119 return nSocket;
120}
121
122bool Connection::isActive()
123{
124 return bActive;
125}
126
127void Connection::close()
128{
129 if( bActive )
130 {
131 fsync( nSocket );
132 ::close( nSocket );
133 }
134 bActive = false;
135 //nSocket = -1;
136 xInputBuf.clearData();
137 xOutputBuf.clearData();
138 if( pProtocol != NULL )
139 {
140 delete pProtocol;
141 pProtocol = NULL;
142 }
143}
144
145bool Connection::open( int nNewSocket )
146{
147 bActive = true;
148 setSocket( nNewSocket );
149 bDisconnectMe = false;
150
151 return true;
152}
153
154bool Connection::open( const char *sAddr, int nPort )
155{
156 struct sockaddr_in xServerName;
157 bActive = false;
158
159 /* Create the socket. */
160 nSocket = socket( PF_INET, SOCK_STREAM, 0 );
161 if( nSocket < 0 )
162 {
163 bActive = false;
164 return false;
165 }
166
167 /* Connect to the server. */
168 {
169 struct hostent *hostinfo;
170
171 xServerName.sin_family = AF_INET;
172 xServerName.sin_port = htons( nPort );
173 hostinfo = gethostbyname( sAddr );
174 if (hostinfo == NULL)
175 {
176 return false;
177 }
178 xServerName.sin_addr = *(struct in_addr *) hostinfo->h_addr;
179 }
180
181 int ret = connect(
182 nSocket,
183 (struct sockaddr *)&xServerName,
184 sizeof(xServerName)
185 );
186
187 if( ret < 0 )
188 {
189 return false;
190 }
191
192 bActive = true;
193 bDisconnectMe = false;
194
195 return true;
196}
197
198bool Connection::readInput()
199{
200 char buffer[2048];
201 int nbytes;
202 int nTotalRead=0;
203
204 for(;;)
205 {
206 memset( buffer, 0, 2048 );
207
208 nbytes = read( nSocket, buffer, 2048 );
209 if (nbytes < 0)
210 {
211 /* Read error. */
212 //perror("readInput");
213 return false;
214 }
215 else if (nbytes == 0)
216 {
217 /* End-of-file. */
218 //perror("readInput");
219 return false;
220 }
221 else
222 {
223 nTotalRead += nbytes;
224 appendInput( buffer, nbytes );
225 /* Data read. */
226 if( nbytes < 2047 )
227 {
228 if( pProtocol != NULL && nTotalRead > 0 )
229 {
230 pProtocol->onNewData();
231 }
232
233 return true;
234 }
235 }
236 }
237
238 return true;
239}
240
241bool Connection::readInput( int nSec, int nUSec )
242{
243 fd_set rfds;
244 struct timeval tv;
245 int retval;
246
247 /* Watch stdin (fd 0) to see when it has input. */
248 FD_ZERO(&rfds);
249 FD_SET(nSocket, &rfds);
250 /* Wait up to five seconds. */
251 tv.tv_sec = nSec;
252 tv.tv_usec = nUSec;
253
254 retval = select( nSocket+1, &rfds, NULL, NULL, &tv );
255 /* Don't rely on the value of tv now! */
256
257 if (retval == -1)
258 {
259 // Oh my god!!! some kind of horrible problem!!!!
260 return false;
261 }
262 else if( retval )
263 {
264 // None of them have data, but the connection is still active.
265 return readInput();
266 }
267 else
268 {
269 return true;
270 }
271}
272
273bool Connection::clearOutput()
274{
275 return xOutputBuf.clearData();
276}
277
278bool Connection::clearInput()
279{
280 return xInputBuf.clearData();
281}
282
283#define min( a, b ) ((a<b)?(a):(b))
284
285bool Connection::writeOutput()
286{
287 int nBytes = TEMP_FAILURE_RETRY( write( nSocket, xOutputBuf.getData(), min( 2048, xOutputBuf.getLength() ) ) );
288 if( nBytes < 0 )
289 {
290 perror("writeOutput");
291 return true;
292 }
293 /*
294 if( nBytes < xOutputBuf.getLength() )
295 {
296 printf("Havn't written all the data (%d/%d/%d%%)\n", nBytes, xOutputBuf.getLength(), nBytes/(xOutputBuf.getLength()*100) );
297 }
298 else
299 {
300 printf("Wrote all pending data.\n");
301 }
302 */
303 xOutputBuf.usedData( nBytes );
304 //clearOutput();
305
306 return true;
307}
308
309bool Connection::hasOutput()
310{
311 if( xOutputBuf.getLength() == 0 )
312 {
313 return false;
314 }
315 else
316 {
317 return true;
318 }
319}
320
321bool Connection::hasInput()
322{
323 if( xInputBuf.getLength() == 0 )
324 {
325 return false;
326 }
327 else
328 {
329 return true;
330 }
331}
332
333bool Connection::usedInput( int nAmount )
334{
335 return xInputBuf.usedData( nAmount );
336}
337
338bool Connection::needDisconnect()
339{
340 return bDisconnectMe;
341}
342
343void Connection::disconnect()
344{
345 bDisconnectMe = true;
346}
347
348void Connection::setProtocol( class Protocol *pNewProtocol )
349{
350 pProtocol = pNewProtocol;
351 pProtocol->setConnection( this );
352}
353
354int Connection::getInputAmnt()
355{
356 return xInputBuf.getLength();
357}
358
359int Connection::getOutputAmnt()
360{
361 return xOutputBuf.getLength();
362}
363
364class Protocol *Connection::getProtocol()
365{
366 return pProtocol;
367}
368
369void Connection::printInputDebug( const char *lpPrefix, FILE *fh, int nBytesMax )
370{
371 printDataDebug(
372 (const unsigned char *)xInputBuf.getData(),
373 xInputBuf.getLength(),
374 "input",
375 lpPrefix,
376 fh,
377 nBytesMax
378 );
379}
380
381void Connection::printOutputDebug( const char *lpPrefix, FILE *fh, int nBytesMax )
382{
383 printDataDebug(
384 (const unsigned char *)xOutputBuf.getData(),
385 xOutputBuf.getLength(),
386 "output",
387 lpPrefix,
388 fh,
389 nBytesMax
390 );
391}
392
393void Connection::printDataDebug( const unsigned char *pData, long nDataLen, const char *lpName, const char *lpPrefix, FILE *fh, int nBytesMax )
394{
395 if( nBytesMax > 0 )
396 {
397 nDataLen = (nBytesMax<nDataLen)?(nBytesMax):(nDataLen);
398 }
399
400 fprintf( fh, "%sDisplaying %d bytes of %s.\n", lpPrefix, nDataLen, lpName );
401 int j = 0;
402 fprintf( fh, lpPrefix );
403 for( int l = 0; l < 8*3+2*8+2; l++ ) fprintf( fh, (l!=8*3)?("-"):("+") ); fprintf( fh, "\n");
404 for(;;)
405 {
406 fprintf( fh, lpPrefix );
407 int kmax = 8;
408 if( nDataLen-j < 8 ) kmax = nDataLen-j;
409 for(int k = 0; k < 8; k++ )
410 {
411 if( k < kmax )
412 {
413 fprintf( fh, "%02X ", (int)((unsigned char)pData[j+k]) );
414 }
415 else
416 {
417 fprintf( fh, "-- ");
418 }
419 }
420 printf("| ");
421 for(int k = 0; k < kmax; k++ )
422 {
423 fprintf( fh, "%c ", (pData[j+k]>32 && pData[j+k]<=128)?(pData[j+k]):('.') );
424 }
425 fprintf( fh, "\n");
426 j += kmax;
427 if( j >= nDataLen ) break;
428 }
429 fprintf( fh, lpPrefix );
430 for( int l = 0; l < 8*3+2*8+2; l++ ) fprintf( fh, (l!=8*3)?("-"):("+") ); fprintf( fh, "\n");
431}
432