1998-11-10 10:07:12 +00:00
|
|
|
|
#define XVT_INCL_NATIVE
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#include <xvt.h>
|
1998-11-04 18:04:26 +00:00
|
|
|
|
#include <progind.h>
|
|
|
|
|
#include <config.h>
|
2002-09-13 14:56:23 +00:00
|
|
|
|
#include <agasys.h>
|
2003-02-26 10:18:34 +00:00
|
|
|
|
#include <utility.h>
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
|
|
|
|
// skstream.h
|
|
|
|
|
// Copyright (C) 1995, 1996 by John C. Wang. All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// You may distribute this file with your product in either of two ways:
|
|
|
|
|
// IN SOURCE CODE FORM: You must include this file in its entirety.
|
|
|
|
|
// IN OBJECT CODE FORM: You must give proper acknowledgements to the author(s)
|
|
|
|
|
// of this program. This may take the form of credits on the start-up screen.
|
|
|
|
|
//
|
|
|
|
|
// IN ANYCASE, THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY KIND OF EXPLICIT OR
|
|
|
|
|
// IMPLICIT WARRANTIES AND THE AUTHORS ARE NOT RESPONSIBLE FOR ANY EVENTS THAT
|
|
|
|
|
// OCCURS AS A RESULT OF USING THIS SOFTWARE.
|
|
|
|
|
//
|
|
|
|
|
// History:
|
|
|
|
|
// [JCW 95-Dec-04] created
|
|
|
|
|
// [JCW 95-Dec-20] comments added for distribution 95a
|
|
|
|
|
// [JCW 96-Jan-01] removed UDP capabilities from skstream
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef INCSTR_H
|
|
|
|
|
#include <incstr.h>
|
|
|
|
|
#endif
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
#include "winsock.h"
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#define SOCKET int
|
|
|
|
|
#define INVALID_SOCKET -1
|
|
|
|
|
#define SOCKET_ERROR -1
|
|
|
|
|
#define SOCKADDR_IN sockaddr_in
|
|
|
|
|
#define closesocket close
|
|
|
|
|
#define BYTE byte
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// sockbuf
|
|
|
|
|
//
|
|
|
|
|
class sockbuf : public streambuf
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
sockbuf( SOCKET & );
|
|
|
|
|
sockbuf( SOCKET &, char *, int );
|
|
|
|
|
|
|
|
|
|
virtual ~sockbuf();
|
|
|
|
|
|
|
|
|
|
virtual int overflow(int =EOF) ;
|
|
|
|
|
virtual int underflow() ;
|
|
|
|
|
|
|
|
|
|
virtual int sync();
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
char *_buffer ;
|
|
|
|
|
|
|
|
|
|
// sockbuf specific
|
|
|
|
|
SOCKET &_socket ;
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// skstream
|
|
|
|
|
//
|
|
|
|
|
class skstream : public iostream {
|
|
|
|
|
public:
|
|
|
|
|
// constants
|
|
|
|
|
enum service
|
|
|
|
|
{
|
|
|
|
|
ftp = 21, //tcp
|
|
|
|
|
telnet = 23, //tcp
|
|
|
|
|
smtp = 25, //tcp mail
|
|
|
|
|
time = 37, //tcp timserver
|
|
|
|
|
name = 42, //tcp nameserver
|
|
|
|
|
nameserver = 53, //tcp domain # name-domain server
|
|
|
|
|
finger = 79, //tcp
|
|
|
|
|
http = 80, //tcp
|
|
|
|
|
pop = 109, //tcp postoffice
|
|
|
|
|
pop2 = 109, //tcp # Post Office
|
|
|
|
|
pop3 = 110, //tcp postoffice
|
|
|
|
|
nntp = 119 //tcp usenet # Network News Transfer
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
enum role
|
|
|
|
|
{
|
|
|
|
|
server ,
|
|
|
|
|
client
|
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
// methods
|
|
|
|
|
skstream( void );
|
|
|
|
|
skstream( const char *addr, const service, const role = client ) ;
|
|
|
|
|
skstream( SOCKET );
|
|
|
|
|
~skstream( void );
|
|
|
|
|
|
|
|
|
|
void open( const char *addr, const service, const role = client ) ;
|
|
|
|
|
void close( void ) ;
|
|
|
|
|
int is_open( void ) const ;
|
|
|
|
|
void attach( SOCKET = NULL );
|
|
|
|
|
SOCKET getsocket() const ;
|
|
|
|
|
|
|
|
|
|
char *getpeername( char *, int ) const ;
|
|
|
|
|
unsigned short getport( void ) const ;
|
|
|
|
|
protected:
|
|
|
|
|
SOCKET _socket ;
|
|
|
|
|
sockbuf _sockbuf ;
|
|
|
|
|
|
|
|
|
|
// platform dependent library housekeeping
|
|
|
|
|
int init( void ) ;
|
|
|
|
|
int shutdown( void ) ;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// skstream.cpp
|
|
|
|
|
// Copyright (C) 1996, 1995 by John C. Wang <jcwang@csie.ntu.edu.tw>
|
|
|
|
|
// All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// You may distribute this file with your product in either of two ways:
|
|
|
|
|
// IN SOURCE CODE FORM: You must include this file in its entirety.
|
|
|
|
|
// IN OBJECT CODE FORM: You must give proper acknowledgements to the author(s)
|
|
|
|
|
// of this program. This may take the form of credits on the start-up screen.
|
|
|
|
|
//
|
|
|
|
|
// IN ANYCASE, THIS SOFTWARE IS DISTRIBUTED WITHOUT ANY KIND OF EXPLICIT OR
|
|
|
|
|
// IMPLICIT WARRANTY AND THE AUTHOR(S) ARE NOT RESPONSIBLE FOR ANY EVENT THAT
|
|
|
|
|
// OCCURS DUE TO THE USE OR MISUSE OF THIS SOFTWARE.
|
|
|
|
|
//
|
|
|
|
|
// History:
|
|
|
|
|
// [JCW 95-Dec-04] created.
|
|
|
|
|
// [JCW 95-Dec-20] comments added for distribution 95a.
|
|
|
|
|
// [JCW 96-Jan-01] removed UDP capabilities from skstream.
|
|
|
|
|
// [JCW 96-Mar-14] exceptions made optional.
|
|
|
|
|
// [JCW 96-Oct-20] protected skstream::init and ::shutdown changed.
|
|
|
|
|
// char( 255 ) == EOF bug fixed.
|
|
|
|
|
|
|
|
|
|
#ifdef _UNIX
|
|
|
|
|
#define INVALID_SOCKET -1
|
|
|
|
|
// Add definitions here
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Machine independent macros
|
|
|
|
|
#ifdef DBG
|
|
|
|
|
#define dassert(x) assert(x)
|
|
|
|
|
#define debug(x) x
|
|
|
|
|
#else
|
|
|
|
|
#define dassert(x)
|
|
|
|
|
#define debug(x)
|
|
|
|
|
#endif //def _DEBUG
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// skstream
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int skstream::init( void )
|
|
|
|
|
{
|
|
|
|
|
// platform dependent initialization
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
const WORD wMinVer = 0x0101; // request WinSock v1.1 (at least)
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
|
if( 0 == WSAStartup( wMinVer, &wsaData ) )
|
|
|
|
|
return TRUE ;
|
|
|
|
|
return FALSE ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
return TRUE;
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int skstream::shutdown( void )
|
|
|
|
|
{
|
|
|
|
|
// platform dependent shutdown
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
if( 0 == WSACleanup() )
|
|
|
|
|
return TRUE ;
|
|
|
|
|
return FALSE ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
return TRUE;
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
skstream::skstream( void ) : iostream( &_sockbuf ), _sockbuf( _socket )
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
if( init() )
|
|
|
|
|
attach( INVALID_SOCKET ) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
skstream::skstream( const char *addr, const service port, const role side )
|
2004-03-12 16:10:04 +00:00
|
|
|
|
: iostream( &_sockbuf ), _sockbuf( _socket )
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
if( init() )
|
|
|
|
|
{
|
|
|
|
|
attach( INVALID_SOCKET ) ;
|
|
|
|
|
open( addr, port, side ) ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
skstream::skstream( SOCKET sock ) : iostream( &_sockbuf ), _sockbuf( _socket )
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
if( init() )
|
|
|
|
|
attach( sock ) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
skstream::~skstream( void )
|
|
|
|
|
{
|
|
|
|
|
close() ;
|
|
|
|
|
shutdown() ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int skstream::is_open( void ) const
|
|
|
|
|
{
|
|
|
|
|
return ( INVALID_SOCKET != getsocket() ) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void skstream::open( const char *addr, const service port, const role side )
|
|
|
|
|
{
|
|
|
|
|
// in case of error condition, user finds out by testing is_open()
|
|
|
|
|
|
|
|
|
|
if( is_open() )
|
|
|
|
|
close() ;
|
|
|
|
|
|
|
|
|
|
// 1. Create socket
|
|
|
|
|
if( INVALID_SOCKET == ( _socket = ::socket( PF_INET, SOCK_STREAM, 0 ) ) )
|
|
|
|
|
// Cannot create socket
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
// 2. Bind
|
|
|
|
|
SOCKADDR_IN sa ;
|
|
|
|
|
sa.sin_family = AF_INET ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
sa.sin_addr.S_un.S_addr = INADDR_ANY ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
sa.sin_addr.s_addr = INADDR_ANY ;
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
sa.sin_port = side == client ? 0 : htons( (unsigned short)port ) ;
|
|
|
|
|
// rationale: no client requires fixed port number, so let system assign
|
|
|
|
|
if( SOCKET_ERROR == ::bind( _socket, (sockaddr *)&sa, sizeof( sa ) ) )
|
|
|
|
|
{
|
|
|
|
|
// Cannot bind to the chosen port
|
|
|
|
|
close() ;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From now on the two sides are very much different
|
|
|
|
|
if( side == skstream::client )
|
|
|
|
|
{
|
|
|
|
|
// 3(cli). Connect
|
2003-02-25 14:39:02 +00:00
|
|
|
|
SOCKADDR_IN sa ; memset(&sa,0,sizeof(sa));
|
1997-06-03 13:56:29 +00:00
|
|
|
|
sa.sin_family = AF_INET ;
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
|
|
|
|
unsigned long indirizzo = 0xFFFFFFFF;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
|
|
|
|
int ip[4];
|
2003-02-25 14:39:02 +00:00
|
|
|
|
//e' un indirizzo numerico?
|
|
|
|
|
//si...
|
1997-06-03 13:56:29 +00:00
|
|
|
|
if (sscanf( addr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4)
|
2003-02-25 14:39:02 +00:00
|
|
|
|
{
|
|
|
|
|
indirizzo = ::inet_addr(addr);
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
2003-02-25 14:39:02 +00:00
|
|
|
|
//no...
|
1997-06-03 13:56:29 +00:00
|
|
|
|
else
|
2003-02-25 14:39:02 +00:00
|
|
|
|
{
|
|
|
|
|
hostent* he = ::gethostbyname( addr );
|
|
|
|
|
if( NULL != he )
|
|
|
|
|
indirizzo = *(unsigned long *)( he->h_addr_list[ 0 ] );
|
|
|
|
|
}
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2003-02-25 14:39:02 +00:00
|
|
|
|
if (indirizzo == 0 || indirizzo == 0xFFFFFFFF)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2003-02-25 14:39:02 +00:00
|
|
|
|
close();
|
|
|
|
|
return;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
2003-02-25 14:39:02 +00:00
|
|
|
|
sa.sin_addr.S_un.S_addr = indirizzo;
|
1997-12-02 13:21:19 +00:00
|
|
|
|
sa.sin_port = ::htons( port ) ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
sa.sin_addr.s_addr = indirizzo;
|
|
|
|
|
sa.sin_port = htons( port ) ;
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
|
|
|
|
if( SOCKET_ERROR == ::connect( _socket, (sockaddr *)&sa, sizeof( sa ) ) )
|
|
|
|
|
{
|
|
|
|
|
// Connection error
|
|
|
|
|
close() ;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 3(svr). Listen
|
|
|
|
|
if( SOCKET_ERROR == ::listen( _socket, 5 ) ) // max backlog
|
|
|
|
|
{
|
|
|
|
|
// Error listening
|
|
|
|
|
close() ;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. Accept
|
|
|
|
|
SOCKET commsock ;
|
|
|
|
|
if( INVALID_SOCKET == ( commsock = ::accept( _socket, NULL, NULL ) ) )
|
|
|
|
|
{
|
|
|
|
|
// Accepting error
|
|
|
|
|
close() ;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rationale: after we accept a connection, close the server port
|
|
|
|
|
// so another process may become a server
|
|
|
|
|
if( SOCKET_ERROR == ::closesocket( _socket ) )
|
|
|
|
|
{
|
|
|
|
|
// Cannot close service port, resource may be occupied
|
|
|
|
|
close() ;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
_socket = commsock ;
|
|
|
|
|
}
|
|
|
|
|
// success!
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void skstream::close( void )
|
|
|
|
|
{
|
|
|
|
|
if( is_open() )
|
|
|
|
|
{
|
|
|
|
|
_sockbuf.sync() ;
|
|
|
|
|
if( SOCKET_ERROR == ::closesocket( _socket ) )
|
|
|
|
|
// Cannot close. Leave _socket as it was
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_socket = INVALID_SOCKET ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void skstream::attach( SOCKET sock )
|
|
|
|
|
{
|
|
|
|
|
_socket = sock ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SOCKET skstream::getsocket() const
|
|
|
|
|
{
|
|
|
|
|
return _socket ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *skstream::getpeername( char *buf, int size ) const
|
|
|
|
|
{
|
|
|
|
|
SOCKADDR_IN sa ;
|
|
|
|
|
int sasize = sizeof( sa ) ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, (socklen_t *) &sasize ) )
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
// Cannot get peer name
|
|
|
|
|
return NULL ;
|
|
|
|
|
strncpy( buf, ::inet_ntoa( sa.sin_addr ), size - 1 ) ;
|
|
|
|
|
return buf ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned short skstream::getport( void ) const
|
|
|
|
|
{
|
|
|
|
|
SOCKADDR_IN sa ;
|
|
|
|
|
int sasize = sizeof( sa ) ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#ifdef WIN32
|
1997-06-03 13:56:29 +00:00
|
|
|
|
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
|
|
|
|
|
// Cannot get peer port
|
2004-03-12 16:10:04 +00:00
|
|
|
|
return ::ntohs( IPPORT_RESERVED );
|
1997-12-02 13:21:19 +00:00
|
|
|
|
return ::ntohs( sa.sin_port ) ;
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#else
|
|
|
|
|
if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, (socklen_t *) &sasize ) )
|
|
|
|
|
// Cannot get peer port
|
|
|
|
|
return ntohs( IPPORT_RESERVED );
|
|
|
|
|
return ntohs( sa.sin_port ) ;
|
|
|
|
|
#endif
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// sockbuf
|
|
|
|
|
//
|
2004-03-12 16:10:04 +00:00
|
|
|
|
sockbuf::sockbuf( SOCKET &sock ) : _socket( sock )
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
const int insize = 0x2000 ; // allocate 16k buffer each for input and output
|
|
|
|
|
const int outsize = 0x2000 ;
|
|
|
|
|
const int bufsize = insize + outsize ;
|
|
|
|
|
|
|
|
|
|
_buffer = new char [ bufsize ] ;
|
|
|
|
|
|
|
|
|
|
if( this != setbuf( _buffer, bufsize ) )
|
|
|
|
|
_buffer = NULL ;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
setp( _buffer, _buffer + insize ) ;
|
|
|
|
|
setg( _buffer + insize, _buffer + bufsize, _buffer + bufsize ) ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
sockbuf::sockbuf( SOCKET &sock, char *buf, int length ) : _socket( sock )
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
_buffer = NULL ;
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
if( this == setbuf( buf, length ) )
|
|
|
|
|
{
|
|
|
|
|
setp( buf, buf + length / 2 ) ;
|
|
|
|
|
setg( buf + length / 2, buf + length, buf + length ) ;
|
|
|
|
|
}
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sockbuf::~sockbuf()
|
|
|
|
|
{
|
|
|
|
|
delete[] _buffer ;
|
|
|
|
|
_buffer = NULL ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sockbuf::overflow( int nCh )
|
|
|
|
|
{
|
|
|
|
|
// in case of error, user finds out by testing fail()
|
|
|
|
|
if( _socket == INVALID_SOCKET )
|
|
|
|
|
// Invalid socket
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
if( pptr() - pbase() <= 0 )
|
|
|
|
|
// nothing to send
|
|
|
|
|
return 0 ;
|
|
|
|
|
|
|
|
|
|
int size ;
|
|
|
|
|
if( SOCKET_ERROR == ( size = ::send( _socket, pbase(), pptr() - pbase(), 0 ) ) )
|
|
|
|
|
// (TCP) Cannot send
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
if( size == 0 )
|
|
|
|
|
// remote site has closed this connection
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
if( nCh != EOF ) // size >= 1 at this point
|
|
|
|
|
{
|
|
|
|
|
size-- ;
|
|
|
|
|
*( pbase() + size ) = nCh ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move remaining pbase() + size .. pptr() - 1 => pbase() .. pptr() - size - 1
|
|
|
|
|
for( char *p = pbase() + size; p < pptr(); p++ )
|
|
|
|
|
*( p - size ) = *p ;
|
|
|
|
|
const int newlen = ( pptr() - pbase() ) - size ;
|
|
|
|
|
|
|
|
|
|
setp( pbase(), epptr() ) ;
|
|
|
|
|
pbump( newlen ) ;
|
|
|
|
|
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sockbuf::underflow()
|
|
|
|
|
{
|
|
|
|
|
// if get area not empty, return first character
|
|
|
|
|
// else fill up get area and return 1st character
|
|
|
|
|
|
|
|
|
|
// in case of error, user finds out by testing eof()
|
|
|
|
|
|
|
|
|
|
if( _socket == INVALID_SOCKET )
|
|
|
|
|
// Invalid socket!
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
if( egptr() - gptr() > 0 )
|
|
|
|
|
return (int)(unsigned char)(*gptr()) ;
|
|
|
|
|
|
|
|
|
|
// fill up from eback to egptr
|
|
|
|
|
int size ;
|
|
|
|
|
if( SOCKET_ERROR == ( size = ::recv( _socket, eback(), egptr() - eback(), 0 ) ) )
|
|
|
|
|
// (TCP) Receive error
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
if( size == 0 )
|
|
|
|
|
// remote site has closed this connection
|
|
|
|
|
return EOF ;
|
|
|
|
|
|
|
|
|
|
// move rcvd data from eback() .. eback() + size to egptr() - size .. egptr()
|
|
|
|
|
const int delta = egptr() - ( eback() + size ) ;
|
|
|
|
|
for( char *p = eback() + size - 1; p >= eback(); p-- )
|
|
|
|
|
{
|
|
|
|
|
CHECK( p + delta >= eback(), "Socket underflow" ) ;
|
|
|
|
|
CHECK( p + delta < egptr(), "Socket underflow" ) ;
|
|
|
|
|
*( p + delta ) = *p ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setg( eback(), egptr() - size, egptr() ) ;
|
|
|
|
|
|
|
|
|
|
return (int)(unsigned char)(*gptr()) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sockbuf::sync()
|
|
|
|
|
{
|
|
|
|
|
if( EOF == overflow() )
|
|
|
|
|
return EOF ; // ios will set the fail bit
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// empty put and get areas
|
|
|
|
|
setp( pbase(), epptr() ) ;
|
|
|
|
|
setg( eback(), egptr(), egptr() ) ;
|
|
|
|
|
|
|
|
|
|
return 0 ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// end of skstreams
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
#include "netsock.h"
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
class TSocket_connection : public TConnection
|
|
|
|
|
{
|
|
|
|
|
TString _server;
|
|
|
|
|
skstream::service _service;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
skstream* _socket;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool connect();
|
|
|
|
|
|
|
|
|
|
public:
|
2006-01-09 01:15:53 +00:00
|
|
|
|
const TString & Server() const { return _server; }
|
2002-09-13 14:56:23 +00:00
|
|
|
|
virtual bool Execute(const char* cmd);
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool WriteLine(const char* cmd);
|
|
|
|
|
bool ReadLine(TString& str);
|
|
|
|
|
bool Read(byte* buf, size_t size);
|
|
|
|
|
|
|
|
|
|
skstream* GetSocket();
|
|
|
|
|
|
|
|
|
|
TSocket_connection(TLanManager* lm, const char* service, const char* server);
|
|
|
|
|
~TSocket_connection();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool TSocket_connection::Execute(const char* cmd)
|
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
|
skstream* calza = GetSocket();
|
|
|
|
|
bool ok = calza != NULL;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
const size_t buflen = strlen(cmd)+1;
|
2002-12-20 17:08:30 +00:00
|
|
|
|
calza->sync();
|
|
|
|
|
calza->write(cmd, buflen);
|
|
|
|
|
calza->flush();
|
|
|
|
|
ok = calza->good() != 0;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TSocket_connection::WriteLine(const char* cmd)
|
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
|
skstream* calza = GetSocket();
|
|
|
|
|
bool ok = calza != NULL;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
const size_t buflen = strlen(cmd); // Unica differenza da Execute
|
2002-12-20 17:08:30 +00:00
|
|
|
|
calza->sync();
|
|
|
|
|
calza->write(cmd, buflen);
|
|
|
|
|
calza->flush();
|
|
|
|
|
ok = calza->good() != 0;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
}
|
|
|
|
|
return ok;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocket_connection::ReadLine(TString& str)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
|
skstream* calza = GetSocket();
|
|
|
|
|
bool ok = calza != NULL;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
char *buf = str.get_buffer(4096);
|
2002-12-20 17:08:30 +00:00
|
|
|
|
calza->getline(buf, str.size(), '\n');
|
2002-09-13 14:56:23 +00:00
|
|
|
|
}
|
|
|
|
|
return ok;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocket_connection::Read(byte* buf, size_t size)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
|
skstream* calza = GetSocket();
|
|
|
|
|
bool ok = calza != NULL;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
2004-03-12 16:10:04 +00:00
|
|
|
|
calza->read((char *)buf, size);
|
2002-12-20 17:08:30 +00:00
|
|
|
|
ok = calza->good() != 0;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TSocket_connection::connect()
|
|
|
|
|
{
|
|
|
|
|
if (_socket != NULL)
|
|
|
|
|
delete _socket;
|
|
|
|
|
_socket = new skstream(_server, _service);
|
|
|
|
|
if (_socket->is_open())
|
|
|
|
|
SetId((CONNID)_socket);
|
|
|
|
|
else
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
delete _socket;
|
|
|
|
|
_socket = NULL;
|
|
|
|
|
SetId(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _socket != NULL;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
skstream* TSocket_connection::GetSocket()
|
|
|
|
|
{
|
|
|
|
|
if (_socket == NULL || !_socket->is_open())
|
|
|
|
|
connect();
|
|
|
|
|
return _socket;
|
|
|
|
|
}
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocket_connection::TSocket_connection(TLanManager* lm,
|
|
|
|
|
const char* service, const char* server)
|
|
|
|
|
: TConnection(lm, 0), _socket(NULL)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
_service = (skstream::service)((service && *service) ? atoi(service) : 0);
|
|
|
|
|
|
|
|
|
|
_server = server;
|
|
|
|
|
int pos = _server.find("://");
|
|
|
|
|
if (pos > 0)
|
|
|
|
|
_server.ltrim(pos+3);
|
|
|
|
|
|
|
|
|
|
pos = _server.rfind(':');
|
|
|
|
|
if (pos >= 0)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
_service = (skstream::service)atoi(_server.mid(pos+1));
|
|
|
|
|
_server.cut(pos);
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
2002-09-13 14:56:23 +00:00
|
|
|
|
|
2004-03-12 16:10:04 +00:00
|
|
|
|
if (_server.blank() || xvt_str_compare_ignoring_case(_server, "localhost") == 0)
|
2002-09-13 14:56:23 +00:00
|
|
|
|
_server = "127.0.0.1";
|
|
|
|
|
|
|
|
|
|
connect();
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocket_connection::~TSocket_connection()
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (_socket)
|
|
|
|
|
delete _socket;
|
|
|
|
|
}
|
1998-12-10 16:25:48 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocketClient::TSocketClient()
|
|
|
|
|
: m_pData(NULL), m_dwSize(0)
|
|
|
|
|
{ }
|
1998-12-10 16:25:48 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocketClient::~TSocketClient()
|
|
|
|
|
{
|
|
|
|
|
ReleaseBuffer();
|
|
|
|
|
RemoveAllConnections();
|
|
|
|
|
}
|
1998-12-10 16:25:48 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TConnection* TSocketClient::OnQueryConnection(const char* service, const char* server)
|
|
|
|
|
{
|
|
|
|
|
TSocket_connection* pConnection = new TSocket_connection(this, service, server);
|
|
|
|
|
if (pConnection->Id() == 0)
|
|
|
|
|
{
|
|
|
|
|
delete pConnection;
|
|
|
|
|
pConnection = NULL;
|
|
|
|
|
}
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
2003-05-05 14:32:23 +00:00
|
|
|
|
|
1997-06-03 13:56:29 +00:00
|
|
|
|
return pConnection;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocketClient::Request(CONNID id, const char* cmd)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
static bool semaphore = FALSE;
|
|
|
|
|
bool ok = FALSE;
|
1997-06-03 13:56:29 +00:00
|
|
|
|
|
|
|
|
|
if (!semaphore)
|
|
|
|
|
{
|
|
|
|
|
semaphore = TRUE;
|
|
|
|
|
|
|
|
|
|
ReleaseBuffer();
|
|
|
|
|
ok = Execute(id, cmd);
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
1998-06-10 14:25:36 +00:00
|
|
|
|
m_dwSize = 0;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
conn->Read((byte*)&m_dwSize, sizeof(m_dwSize));
|
1998-06-10 14:25:36 +00:00
|
|
|
|
ok = m_dwSize > 0;
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
m_pData = new byte[m_dwSize];
|
|
|
|
|
ok = conn->Read(m_pData, m_dwSize);
|
1998-06-10 14:25:36 +00:00
|
|
|
|
}
|
1997-06-03 13:56:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
semaphore = FALSE;
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
byte* TSocketClient::GetBuffer(size_t& dwSize)
|
1997-06-03 13:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
dwSize = m_dwSize;
|
|
|
|
|
return m_pData;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocketClient::WriteLine(CONNID id, const char* str)
|
1998-08-20 14:49:34 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
|
|
|
|
if (conn)
|
|
|
|
|
return conn->WriteLine(str);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
1998-12-10 16:25:48 +00:00
|
|
|
|
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocketClient::ReadLine(CONNID id, TString& str)
|
|
|
|
|
{
|
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
|
|
|
|
if (conn)
|
|
|
|
|
return conn->ReadLine(str);
|
|
|
|
|
return FALSE;
|
1998-12-10 16:25:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
void TSocketClient::ReleaseBuffer()
|
1998-12-10 16:25:48 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
if (m_pData)
|
|
|
|
|
{
|
|
|
|
|
delete m_pData;
|
|
|
|
|
m_pData = NULL;
|
|
|
|
|
m_dwSize = 0;
|
|
|
|
|
}
|
1998-12-10 16:25:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-04-22 15:06:36 +00:00
|
|
|
|
bool TSocketClient::HttpGetFile(CONNID id, const char* remote, const char* local, const char* authorization)
|
2003-05-05 14:32:23 +00:00
|
|
|
|
|
1998-12-10 16:25:48 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool ok = FALSE;
|
2006-01-09 01:15:53 +00:00
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
1999-04-06 16:31:40 +00:00
|
|
|
|
|
2006-01-09 01:15:53 +00:00
|
|
|
|
TString buf(8*1024);
|
|
|
|
|
buf << "GET " << remote << " HTTP/1.1\r\n"
|
|
|
|
|
<< "User-Agent: Campo\r\n"
|
|
|
|
|
<< "Host: " << conn->Server() << "\r\n";
|
2003-05-05 14:32:23 +00:00
|
|
|
|
if (authorization && *authorization)
|
|
|
|
|
buf << "Authorization: " << authorization << "\r\n";
|
|
|
|
|
buf << "\r\n";
|
2002-09-13 14:56:23 +00:00
|
|
|
|
|
|
|
|
|
if (WriteLine(id, buf))
|
1999-04-06 16:31:40 +00:00
|
|
|
|
{
|
|
|
|
|
long size = 0;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
for (int r = 0; ; r++)
|
1999-04-06 16:31:40 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
ReadLine(id, buf);
|
1999-04-06 16:31:40 +00:00
|
|
|
|
if (buf.blank())
|
|
|
|
|
break;
|
2003-05-05 14:32:23 +00:00
|
|
|
|
if (r == 0 && buf.find("200 OK") < 0)
|
1999-04-06 16:31:40 +00:00
|
|
|
|
return FALSE; // File not found
|
|
|
|
|
if (buf.compare("Content-length:", 15, TRUE) == 0)
|
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
const int colon = buf.find(':');
|
|
|
|
|
size = atol(buf.mid(colon+1));
|
1999-04-06 16:31:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ofstream outfile(local, ios::out | ios::binary);
|
1998-08-20 14:49:34 +00:00
|
|
|
|
if (outfile.good())
|
|
|
|
|
{
|
2003-04-30 15:46:08 +00:00
|
|
|
|
buf.cut(0) << remote << " - " << (size / 1024 + 1) << " KBytes";
|
|
|
|
|
TProgind pi(size, buf, TRUE, TRUE);
|
1998-08-20 14:49:34 +00:00
|
|
|
|
long total = 0;
|
2006-01-09 01:15:53 +00:00
|
|
|
|
skstream* cur_socket = conn->GetSocket();
|
|
|
|
|
|
1998-08-20 14:49:34 +00:00
|
|
|
|
while (!cur_socket->eof())
|
|
|
|
|
{
|
2006-01-09 01:15:53 +00:00
|
|
|
|
int nchars = buf.size();
|
|
|
|
|
|
|
|
|
|
if (size >0 && nchars > size - total)
|
|
|
|
|
nchars = size - total;
|
|
|
|
|
cur_socket->read(buf.get_buffer(), nchars);
|
1998-08-20 14:49:34 +00:00
|
|
|
|
const int count = cur_socket->gcount();
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2003-04-30 15:46:08 +00:00
|
|
|
|
outfile.write(buf, count);
|
|
|
|
|
total += count;
|
2006-01-09 01:15:53 +00:00
|
|
|
|
pi.setstatus(total);
|
|
|
|
|
if (pi.iscancelled())
|
|
|
|
|
break;
|
|
|
|
|
if (size > 0 && total >= size)
|
|
|
|
|
break;
|
1998-08-20 14:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-01-09 01:15:53 +00:00
|
|
|
|
ok = size = 0 ? cur_socket->eof() != 0 : total >= size;
|
1998-08-20 14:49:34 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
error_box("Impossibile scrivere il file %s", local);
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
2003-10-28 15:53:38 +00:00
|
|
|
|
|
|
|
|
|
HIDDEN int find_href(const TString& riga)
|
|
|
|
|
{
|
|
|
|
|
int href = -1;
|
|
|
|
|
int img = riga.find("<img");
|
|
|
|
|
if (img >= 0)
|
|
|
|
|
href = riga.find("href=", img+4);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
img = riga.find("<IMG");
|
|
|
|
|
if (img >= 0)
|
|
|
|
|
href = riga.find("HREF=", img+4);
|
|
|
|
|
}
|
|
|
|
|
return href;
|
|
|
|
|
}
|
1998-11-04 18:04:26 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocketClient::HttpGetDir(CONNID id, const char* remote, TString_array& list)
|
1998-08-20 14:49:34 +00:00
|
|
|
|
{
|
|
|
|
|
TFilename local; local.temp();
|
2002-09-13 14:56:23 +00:00
|
|
|
|
const bool ok = HttpGetFile(id, remote, local);
|
1998-08-20 14:49:34 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
ifstream s(local);
|
2002-10-24 10:47:49 +00:00
|
|
|
|
TString riga(256);
|
1998-08-20 14:49:34 +00:00
|
|
|
|
while (!s.eof())
|
|
|
|
|
{
|
|
|
|
|
s.getline(riga.get_buffer(), riga.size());
|
2003-10-28 15:53:38 +00:00
|
|
|
|
const int href = find_href(riga);
|
|
|
|
|
if (href > 0)
|
1998-08-20 14:49:34 +00:00
|
|
|
|
{
|
|
|
|
|
const int start = riga.find('"', href) + 1;
|
2002-10-24 10:47:49 +00:00
|
|
|
|
if (start > href && isalnum(riga[start + 1]))
|
1998-08-20 14:49:34 +00:00
|
|
|
|
{
|
|
|
|
|
const int stop = riga.find('"', start);
|
|
|
|
|
if (stop > start)
|
|
|
|
|
{
|
|
|
|
|
const TString& name = riga.sub(start, stop);
|
|
|
|
|
list.add(name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s.close();
|
|
|
|
|
::remove(local);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
1998-11-04 18:04:26 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool TSocketClient::HttpSoap(CONNID id, const char* cmd)
|
1998-11-04 18:04:26 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
|
|
|
|
if (conn == NULL)
|
|
|
|
|
return ok;
|
|
|
|
|
|
|
|
|
|
if (cmd == NULL || *cmd == '\0')
|
|
|
|
|
return ok;
|
|
|
|
|
|
2004-06-04 11:28:14 +00:00
|
|
|
|
char hostname[256];
|
2003-04-30 15:46:08 +00:00
|
|
|
|
xvt_sys_get_host_name(hostname, sizeof(hostname));
|
2002-09-13 14:56:23 +00:00
|
|
|
|
|
|
|
|
|
TString content(256);
|
|
|
|
|
content = cmd;
|
|
|
|
|
if (content.find("<SOAP-ENV") < 0) // Controllo se c'<27> tutto
|
|
|
|
|
{
|
|
|
|
|
content.insert("<SOAP-ENV:Envelope>\n<SOAP-ENV:Body>\n");
|
|
|
|
|
content << "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\r\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TString buf(4096);
|
|
|
|
|
buf << "POST / HTTP/1.1\n"
|
|
|
|
|
<< "User-Agent: Campo\n"
|
|
|
|
|
<< "Host: " << hostname << "\n"
|
|
|
|
|
<< "Content-Type: text/xml; charset=utf-8\n"
|
|
|
|
|
<< "Content-length: " << content.len() << "\n"
|
|
|
|
|
<< "SOAPAction: \"/\"\r\n\r\n"
|
|
|
|
|
<< content;
|
|
|
|
|
|
|
|
|
|
if (conn->WriteLine(buf))
|
1998-11-04 18:04:26 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
skstream* cur_socket = conn->GetSocket();
|
|
|
|
|
|
|
|
|
|
unsigned long size = 0;
|
|
|
|
|
for (int r = 0; !cur_socket->eof(); r++)
|
|
|
|
|
{
|
|
|
|
|
conn->ReadLine(buf);
|
|
|
|
|
if (buf.blank())
|
|
|
|
|
break;
|
|
|
|
|
if (buf.compare("Content-length:", 15, TRUE) == 0)
|
|
|
|
|
{
|
|
|
|
|
const int colon = buf.find(':');
|
|
|
|
|
size = atol(buf.mid(colon+1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (size > 0)
|
|
|
|
|
{
|
|
|
|
|
if (size >= m_dwSize)
|
|
|
|
|
{
|
|
|
|
|
ReleaseBuffer();
|
|
|
|
|
m_dwSize = size+1;
|
|
|
|
|
m_pData = new BYTE[m_dwSize];
|
|
|
|
|
}
|
|
|
|
|
memset(m_pData, 0, m_dwSize);
|
2004-03-12 16:10:04 +00:00
|
|
|
|
cur_socket->read((char *) m_pData, size);
|
2002-09-13 14:56:23 +00:00
|
|
|
|
ok = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
2003-02-26 09:51:05 +00:00
|
|
|
|
|
2003-02-26 10:18:34 +00:00
|
|
|
|
bool TSocketClient::HttpPostFile(CONNID id, const char* remote, const char* local, const char* authorization)
|
2003-02-25 14:39:02 +00:00
|
|
|
|
{
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
|
|
TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
|
|
|
|
|
if (conn == NULL)
|
|
|
|
|
return ok;
|
2003-12-03 09:41:16 +00:00
|
|
|
|
const char* const eol = "\r\n";
|
|
|
|
|
|
2003-02-25 14:39:02 +00:00
|
|
|
|
TString buf(4096);
|
2003-12-03 09:41:16 +00:00
|
|
|
|
buf << "POST " << remote << " HTTP/1.0" << eol
|
2006-10-31 09:47:42 +00:00
|
|
|
|
<< "User-Agent: Campo" << eol
|
2003-12-03 09:41:16 +00:00
|
|
|
|
<< "Content-Type: text/plain" << eol
|
|
|
|
|
<< "Content-Length: " << fsize(local) << eol;
|
2003-02-25 14:39:02 +00:00
|
|
|
|
if (authorization && *authorization)
|
2003-12-03 09:41:16 +00:00
|
|
|
|
buf << "Authorization: " << authorization << eol;
|
|
|
|
|
buf << eol;
|
2003-02-25 14:39:02 +00:00
|
|
|
|
|
2003-02-26 10:18:34 +00:00
|
|
|
|
ok = conn->WriteLine(buf);
|
2003-02-25 14:39:02 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
2004-03-12 16:10:04 +00:00
|
|
|
|
ifstream input(local, ios::binary);
|
2006-12-29 14:16:28 +00:00
|
|
|
|
|
2003-02-25 14:39:02 +00:00
|
|
|
|
while (!input.eof())
|
|
|
|
|
{
|
|
|
|
|
input.read(buf.get_buffer(), buf.size());
|
|
|
|
|
const size_t count = input.gcount();
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
skstream* cur_socket = conn->GetSocket();
|
|
|
|
|
|
|
|
|
|
cur_socket->sync();
|
|
|
|
|
cur_socket->write(buf, count);
|
|
|
|
|
cur_socket->flush();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
conn->ReadLine(buf);
|
|
|
|
|
ok = buf.find("200 OK") >= 0;
|
2003-05-05 14:32:23 +00:00
|
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
2003-05-07 14:55:35 +00:00
|
|
|
|
skstream* cur_socket = conn->GetSocket();
|
2003-05-05 14:32:23 +00:00
|
|
|
|
unsigned long size = 0;
|
|
|
|
|
for (int r = 0; !cur_socket->eof(); r++)
|
|
|
|
|
{
|
|
|
|
|
cur_socket->getline(buf.get_buffer(), buf.size(), '\n');
|
|
|
|
|
if (buf.blank())
|
|
|
|
|
break;
|
2003-12-03 09:41:16 +00:00
|
|
|
|
if (buf.starts_with("Content-length:", true) == 0)
|
2003-05-05 14:32:23 +00:00
|
|
|
|
{
|
|
|
|
|
const int colon = buf.find(':');
|
|
|
|
|
size = atol(buf.mid(colon+1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ReleaseBuffer();
|
|
|
|
|
ok = size > 0;
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
m_dwSize = size;
|
|
|
|
|
m_pData = new BYTE[m_dwSize+1];
|
|
|
|
|
memset(m_pData, 0, size_t(m_dwSize+1));
|
2004-03-12 16:10:04 +00:00
|
|
|
|
cur_socket->read((char *) m_pData, (size_t)m_dwSize);
|
2003-05-05 14:32:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ReleaseBuffer();
|
|
|
|
|
m_dwSize = buf.len()+1;
|
|
|
|
|
m_pData = new BYTE[m_dwSize];
|
|
|
|
|
memcpy(m_pData, buf, (size_t)m_dwSize);
|
|
|
|
|
}
|
2003-02-25 14:39:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|