Files correlati : Ricompilazione Demo : [ ] Commento : Modificato il nome del metodo SOAP in postman e memorizzato il nome della tabella git-svn-id: svn://10.65.10.50/trunk@16539 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1220 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1220 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#define XVT_INCL_NATIVE
 | 
						||
#include <xvt.h>
 | 
						||
 | 
						||
#include <agasys.h>
 | 
						||
#include <diction.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
// 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
 | 
						||
 | 
						||
#ifdef INCSTR_H
 | 
						||
#include <incstr.h>
 | 
						||
#endif
 | 
						||
 | 
						||
#ifdef WIN32
 | 
						||
#include "winsock.h"
 | 
						||
#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
 | 
						||
 | 
						||
//
 | 
						||
// 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
 | 
						||
#ifdef WIN32
 | 
						||
  const WORD wMinVer = 0x0101;  // request WinSock v1.1 (at least)
 | 
						||
  WSADATA wsaData;
 | 
						||
  if( 0 == WSAStartup( wMinVer, &wsaData ) )
 | 
						||
    return TRUE ;
 | 
						||
  return FALSE ;
 | 
						||
#else
 | 
						||
	return TRUE;
 | 
						||
#endif
 | 
						||
}
 | 
						||
 | 
						||
int skstream::shutdown( void )
 | 
						||
{
 | 
						||
  // platform dependent shutdown
 | 
						||
#ifdef WIN32
 | 
						||
  if( 0 == WSACleanup() )
 | 
						||
    return TRUE ;
 | 
						||
  return FALSE ;
 | 
						||
#else
 | 
						||
	return TRUE;
 | 
						||
#endif
 | 
						||
}
 | 
						||
 | 
						||
skstream::skstream( void ) : iostream( &_sockbuf ), _sockbuf( _socket )
 | 
						||
{
 | 
						||
  if( init() )
 | 
						||
    attach( INVALID_SOCKET ) ;
 | 
						||
}
 | 
						||
 | 
						||
skstream::skstream( const char *addr, const service port, const role side )
 | 
						||
 : iostream( &_sockbuf ), _sockbuf( _socket )
 | 
						||
{
 | 
						||
  if( init() )
 | 
						||
  {
 | 
						||
    attach( INVALID_SOCKET ) ;
 | 
						||
    open( addr, port, side ) ;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
skstream::skstream( SOCKET sock ) : iostream( &_sockbuf ), _sockbuf( _socket )
 | 
						||
{
 | 
						||
  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 ;
 | 
						||
#ifdef WIN32
 | 
						||
  sa.sin_addr.S_un.S_addr = INADDR_ANY ;
 | 
						||
#else  
 | 
						||
  sa.sin_addr.s_addr = INADDR_ANY ;
 | 
						||
#endif  
 | 
						||
  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
 | 
						||
    SOCKADDR_IN sa ; memset(&sa,0,sizeof(sa));
 | 
						||
    sa.sin_family = AF_INET ;
 | 
						||
                               
 | 
						||
    unsigned long indirizzo = 0xFFFFFFFF;
 | 
						||
    
 | 
						||
    int ip[4];
 | 
						||
//e' un indirizzo numerico?
 | 
						||
//si...    
 | 
						||
    if (sscanf( addr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4)
 | 
						||
    {
 | 
						||
      indirizzo = ::inet_addr(addr);
 | 
						||
    }
 | 
						||
//no...
 | 
						||
    else
 | 
						||
    { 
 | 
						||
      hostent* he = ::gethostbyname( addr );    
 | 
						||
      if( NULL != he )
 | 
						||
        indirizzo = *(unsigned long *)( he->h_addr_list[ 0 ] );
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (indirizzo == 0 || indirizzo == 0xFFFFFFFF)
 | 
						||
    {
 | 
						||
      close();
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    
 | 
						||
#ifdef WIN32
 | 
						||
    sa.sin_addr.S_un.S_addr = indirizzo;
 | 
						||
    sa.sin_port = ::htons( port ) ;
 | 
						||
#else
 | 
						||
    sa.sin_addr.s_addr = indirizzo;
 | 
						||
    sa.sin_port = htons( port ) ;
 | 
						||
#endif
 | 
						||
 | 
						||
    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 ) ;
 | 
						||
#ifdef WIN32
 | 
						||
  if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
 | 
						||
#else
 | 
						||
  if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, (socklen_t *) &sasize ) )
 | 
						||
#endif
 | 
						||
    // 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 ) ;
 | 
						||
#ifdef WIN32
 | 
						||
  if( SOCKET_ERROR ==::getpeername( getsocket(), (sockaddr *)&sa, &sasize ) )
 | 
						||
    // Cannot get peer port
 | 
						||
    return ::ntohs( IPPORT_RESERVED ); 
 | 
						||
  return ::ntohs( sa.sin_port ) ;
 | 
						||
#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
 | 
						||
}
 | 
						||
 | 
						||
//
 | 
						||
//  sockbuf
 | 
						||
//
 | 
						||
sockbuf::sockbuf( SOCKET &sock ) : _socket( sock ) 
 | 
						||
{
 | 
						||
  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 ) ;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
sockbuf::sockbuf( SOCKET &sock, char *buf, int length ) : _socket( sock )
 | 
						||
{
 | 
						||
  _buffer = NULL ;
 | 
						||
 | 
						||
  if( this == setbuf( buf, length ) )
 | 
						||
	{
 | 
						||
  	setp( buf, buf + length / 2 ) ;
 | 
						||
  	setg( buf + length / 2, buf + length, buf + length ) ;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
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
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
#include "netsock.h"
 | 
						||
 | 
						||
class TSocket_connection : public TConnection
 | 
						||
{
 | 
						||
	TString _server;
 | 
						||
  skstream::service _service;
 | 
						||
 | 
						||
  skstream* _socket;
 | 
						||
 | 
						||
protected:
 | 
						||
  bool connect();
 | 
						||
 
 | 
						||
public:
 | 
						||
	const TString & Server() const { return _server; }
 | 
						||
  virtual bool Execute(const char* cmd);
 | 
						||
 | 
						||
  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)
 | 
						||
{
 | 
						||
	skstream* calza = GetSocket();
 | 
						||
	bool ok = calza != NULL;
 | 
						||
  if (ok)
 | 
						||
	{
 | 
						||
    const size_t buflen = strlen(cmd)+1;
 | 
						||
    calza->sync();
 | 
						||
    calza->write(cmd, buflen);
 | 
						||
    calza->flush();
 | 
						||
    ok = calza->good() != 0;
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocket_connection::WriteLine(const char* cmd)
 | 
						||
{
 | 
						||
	skstream* calza = GetSocket();
 | 
						||
	bool ok = calza != NULL;
 | 
						||
  if (ok)
 | 
						||
	{
 | 
						||
    const size_t buflen = strlen(cmd); // Unica differenza da Execute
 | 
						||
    calza->sync();
 | 
						||
    calza->write(cmd, buflen);
 | 
						||
    calza->flush();
 | 
						||
    ok = calza->good() != 0;
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocket_connection::ReadLine(TString& str)
 | 
						||
{
 | 
						||
	skstream* calza = GetSocket();
 | 
						||
	bool ok = calza != NULL;
 | 
						||
	if (ok)
 | 
						||
	{
 | 
						||
    char *buf = str.get_buffer(4096);
 | 
						||
    calza->getline(buf, str.size(), '\n');
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocket_connection::Read(byte* buf, size_t size)
 | 
						||
{
 | 
						||
	skstream* calza = GetSocket();
 | 
						||
	bool ok = calza != NULL;
 | 
						||
	if (ok)
 | 
						||
	{
 | 
						||
    calza->read((char *)buf, size);
 | 
						||
		ok = calza->good() != 0;
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocket_connection::connect()
 | 
						||
{ 
 | 
						||
	if (_socket != NULL)
 | 
						||
		delete _socket;
 | 
						||
  _socket = new skstream(_server, _service);
 | 
						||
	if (_socket->is_open())
 | 
						||
	  SetId((CONNID)_socket);
 | 
						||
  else
 | 
						||
  {
 | 
						||
    delete _socket;
 | 
						||
    _socket = NULL;
 | 
						||
	  SetId(0);
 | 
						||
  }  
 | 
						||
 | 
						||
	return _socket != NULL;
 | 
						||
}
 | 
						||
 | 
						||
skstream* TSocket_connection::GetSocket()
 | 
						||
{
 | 
						||
	if (_socket == NULL || !_socket->is_open())
 | 
						||
		connect();
 | 
						||
	return _socket;
 | 
						||
}
 | 
						||
 | 
						||
TSocket_connection::TSocket_connection(TLanManager* lm, 
 | 
						||
																			 const char* service, const char* server) 
 | 
						||
                  : TConnection(lm, 0), _socket(NULL)
 | 
						||
{
 | 
						||
  _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)
 | 
						||
  {
 | 
						||
    _service = (skstream::service)atoi(_server.mid(pos+1));
 | 
						||
    _server.cut(pos);
 | 
						||
  }
 | 
						||
 | 
						||
  if (_server.blank() || xvt_str_compare_ignoring_case(_server, "localhost") == 0)
 | 
						||
    _server = "127.0.0.1";           
 | 
						||
 | 
						||
	connect();
 | 
						||
}
 | 
						||
 | 
						||
TSocket_connection::~TSocket_connection()
 | 
						||
{
 | 
						||
	if (_socket)
 | 
						||
		delete _socket;
 | 
						||
}
 | 
						||
 | 
						||
TSocketClient::TSocketClient() 
 | 
						||
      : m_pData(NULL), m_dwSize(0)
 | 
						||
{ }
 | 
						||
 | 
						||
TSocketClient::~TSocketClient()
 | 
						||
{ 
 | 
						||
  ReleaseBuffer();
 | 
						||
  RemoveAllConnections();
 | 
						||
}
 | 
						||
 | 
						||
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;
 | 
						||
	}
 | 
						||
 | 
						||
 | 
						||
  return pConnection;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::Request(CONNID id, const char* cmd)
 | 
						||
{   
 | 
						||
  static bool semaphore = FALSE;
 | 
						||
  bool ok = FALSE;
 | 
						||
 | 
						||
  if (!semaphore)
 | 
						||
  {
 | 
						||
    semaphore = TRUE;
 | 
						||
    
 | 
						||
    ReleaseBuffer();
 | 
						||
    ok = Execute(id, cmd);
 | 
						||
    if (ok)
 | 
						||
    {                                  
 | 
						||
			TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
      m_dwSize = 0;
 | 
						||
      conn->Read((byte*)&m_dwSize, sizeof(m_dwSize));
 | 
						||
      ok = m_dwSize > 0;
 | 
						||
      if (ok)
 | 
						||
      {
 | 
						||
        m_pData = new byte[m_dwSize];
 | 
						||
        ok = conn->Read(m_pData, m_dwSize);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    semaphore = FALSE;
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
byte* TSocketClient::GetBuffer(size_t& dwSize)
 | 
						||
{
 | 
						||
  dwSize = m_dwSize;
 | 
						||
  return m_pData;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::WriteLine(CONNID id, const char* str)
 | 
						||
{
 | 
						||
	TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
	if (conn)
 | 
						||
    return conn->WriteLine(str);
 | 
						||
  return FALSE;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
bool TSocketClient::ReadLine(CONNID id, TString& str)
 | 
						||
{
 | 
						||
	TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
	if (conn)
 | 
						||
    return conn->ReadLine(str);
 | 
						||
	return false;
 | 
						||
}
 | 
						||
 | 
						||
void TSocketClient::ReleaseBuffer()
 | 
						||
{
 | 
						||
  if (m_pData)
 | 
						||
  {
 | 
						||
    delete m_pData;
 | 
						||
    m_pData = NULL;
 | 
						||
    m_dwSize = 0;
 | 
						||
  }
 | 
						||
}
 | 
						||
int TSocketClient::HttpGetHeader(CONNID id, const char* remote, const char* authorization, 
 | 
						||
                                 TString_array& header)
 | 
						||
{
 | 
						||
  int ret = 0;
 | 
						||
 | 
						||
  TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
  TString buf(4*1024);
 | 
						||
  buf << "GET " << remote << " HTTP/1.1\r\n"
 | 
						||
      << "User-Agent: Campo\r\n"
 | 
						||
      << "Host: " << conn->Server()	<< "\r\n";
 | 
						||
  
 | 
						||
  if (authorization && *authorization)
 | 
						||
    buf << "Authorization: " << authorization << "\r\n";
 | 
						||
  
 | 
						||
  const TFixed_string rem(remote);
 | 
						||
  buf << "Connection: " << (rem.ends_with("/") ? "Close" : "Keep-Alive") << "\r\n";
 | 
						||
  
 | 
						||
  buf << "\r\n";
 | 
						||
 | 
						||
  header.destroy();
 | 
						||
  if (WriteLine(id, buf))
 | 
						||
  {
 | 
						||
    for (int r = 0; ; r++)
 | 
						||
    {
 | 
						||
			ReadLine(id, buf);
 | 
						||
      if (buf.blank())
 | 
						||
        break;
 | 
						||
      if (r == 0)
 | 
						||
        ret = atoi(buf.after(' '));
 | 
						||
      header.add(buf);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::HttpIsRedirectedServer(CONNID id, TString & http_server, TFilename & remote, const char* authorization)
 | 
						||
{
 | 
						||
  TString_array header;
 | 
						||
  const bool redirected = HttpGetHeader(id, remote, NULL, header) == 302;
 | 
						||
  if (redirected) 
 | 
						||
  {
 | 
						||
    FOR_EACH_ARRAY_ROW(header, r, row)
 | 
						||
    {
 | 
						||
      TString& buf = *row;
 | 
						||
	    if (buf.starts_with("Location:", true))
 | 
						||
      {
 | 
						||
				buf = buf.after(':');
 | 
						||
				if (buf.full())
 | 
						||
				{
 | 
						||
          buf.trim();
 | 
						||
				  if (buf.starts_with("http://", true))
 | 
						||
						buf.ltrim(7);
 | 
						||
				  const int slash =  buf.find('/');
 | 
						||
					if (slash > 0)
 | 
						||
					{
 | 
						||
				    remote = buf.mid(slash);
 | 
						||
				    if (!remote.ends_with("/"))
 | 
						||
							remote << '/';
 | 
						||
				    http_server = buf.left(slash);
 | 
						||
					}
 | 
						||
				}
 | 
						||
      }
 | 
						||
    }
 | 
						||
	}
 | 
						||
  return redirected;
 | 
						||
}
 | 
						||
 | 
						||
static const TString& bytes2str(long b)
 | 
						||
{
 | 
						||
  TString& tmp = get_tmp_string();
 | 
						||
  if (b > 0)
 | 
						||
  {
 | 
						||
    const long mega = 1024*1024;
 | 
						||
    if (b >= mega)
 | 
						||
      tmp.format("%ld MBytes", (b+mega/2)/mega);
 | 
						||
    else
 | 
						||
    {
 | 
						||
      const long kappa = 1024;
 | 
						||
      if (b >= kappa)
 | 
						||
        tmp.format("%ld KBytes", (b+kappa/2)/kappa);
 | 
						||
      else
 | 
						||
        tmp.format("%ld Bytes", b);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
    tmp = TR("Dimensione sconosciuta");
 | 
						||
  return tmp;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::HttpGetFile(CONNID id, const char* remote, const char* local, const char* authorization)
 | 
						||
{
 | 
						||
  bool ok = false;
 | 
						||
  
 | 
						||
  TString_array header;
 | 
						||
  const int ret = HttpGetHeader(id, remote, authorization, header);
 | 
						||
  if (ret == 200)
 | 
						||
  {
 | 
						||
    long size = -1;  // Unknown size
 | 
						||
    FOR_EACH_ARRAY_ROW(header, r, row)
 | 
						||
    {
 | 
						||
      if (row->starts_with("Content-length:", true))
 | 
						||
      {
 | 
						||
        size = atol(row->after(':'));
 | 
						||
        break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (size == 0) // File not found
 | 
						||
      return false;
 | 
						||
 | 
						||
    ofstream outfile(local, ios::out | ios::binary);
 | 
						||
    if (outfile.good())
 | 
						||
    {    
 | 
						||
      TString buf(8*1024);
 | 
						||
 | 
						||
      TToken_string strpi(256, '\n');
 | 
						||
      strpi << remote << " - " << bytes2str(size); 
 | 
						||
      strpi.add(TR("Trasferiti"));
 | 
						||
      long total = 0;
 | 
						||
 | 
						||
      TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
      skstream* cur_socket = conn->GetSocket();
 | 
						||
 | 
						||
      if (size > 0) // Dimensione nota
 | 
						||
      {
 | 
						||
        if (size <= buf.size())  // File piccolo: Niente barra di progresso
 | 
						||
        {
 | 
						||
          while (total < size && !cur_socket->eof())
 | 
						||
          {
 | 
						||
				    const int nchars = min(buf.size(), size - total);
 | 
						||
            cur_socket->read(buf.get_buffer(), nchars);
 | 
						||
            const int count = cur_socket->gcount();
 | 
						||
            if (count > 0)
 | 
						||
            {
 | 
						||
              total += count;
 | 
						||
              outfile.write(buf, count);  
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          TProgind pi(size, strpi, true, true);
 | 
						||
          while (!cur_socket->eof() && !pi.iscancelled())
 | 
						||
          {
 | 
						||
				    const int nchars = min(buf.size(), size - total);
 | 
						||
            cur_socket->read(buf.get_buffer(), nchars);
 | 
						||
            const int count = cur_socket->gcount();
 | 
						||
            if (count > 0)
 | 
						||
            {
 | 
						||
              outfile.write(buf, count);  
 | 
						||
              total += count;
 | 
						||
              if (total >= size || !pi.setstatus(total))  // Controllo se ormai ho finito
 | 
						||
  				      break;
 | 
						||
              strpi.add(TR("Trasferiti"), 1);
 | 
						||
              strpi << ' ' << bytes2str(total); 
 | 
						||
              pi.set_text(strpi);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        ok = total >= size; // Ho finito per bene?
 | 
						||
      }
 | 
						||
      else  // Dimensione ignota
 | 
						||
      { 
 | 
						||
        TIndwin pi(100, strpi, true, false);
 | 
						||
        while (!cur_socket->eof() && !pi.iscancelled())
 | 
						||
        {
 | 
						||
          cur_socket->read(buf.get_buffer(), buf.size());
 | 
						||
          const int count = cur_socket->gcount();
 | 
						||
          if (count > 0)
 | 
						||
          {
 | 
						||
            outfile.write(buf, count);  
 | 
						||
            total += count;
 | 
						||
            strpi.add(TR("Trasferiti"), 1);
 | 
						||
            strpi << ' ' << bytes2str(total); 
 | 
						||
            pi.set_text(strpi);
 | 
						||
          }
 | 
						||
        }
 | 
						||
        ok = total > 0 && !pi.iscancelled();  // Ho finito per bene?
 | 
						||
      }
 | 
						||
    } 
 | 
						||
    else 
 | 
						||
      error_box(FR("Impossibile scrivere il file %s"), local);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN int find_href(const TString& riga, int from)
 | 
						||
{
 | 
						||
  int href = -1;
 | 
						||
  int img = riga.find("<img", from);
 | 
						||
  if (img >= 0)
 | 
						||
    href = riga.find("href=", img+4);
 | 
						||
  return href;
 | 
						||
}
 | 
						||
 
 | 
						||
bool TSocketClient::HttpGetDir(CONNID id, const char* remote, TString_array& list)
 | 
						||
{
 | 
						||
  TFilename local; local.temp();
 | 
						||
  const bool ok = HttpGetFile(id, remote, local);
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    ifstream s(local);
 | 
						||
    TString riga(512);
 | 
						||
    while (!s.eof())
 | 
						||
    {
 | 
						||
      s.getline(riga.get_buffer(), riga.size());
 | 
						||
      riga.lower();
 | 
						||
      for (int href = find_href(riga, 0); href > 0; href = find_href(riga, href+5))
 | 
						||
      {
 | 
						||
        const int start = riga.find('"', href) + 1;
 | 
						||
        if (start > href)
 | 
						||
        {
 | 
						||
          const int stop  = riga.find('"', start);
 | 
						||
          if (stop > start)
 | 
						||
          {
 | 
						||
            const TString& name = riga.sub(start, stop);
 | 
						||
            if (isdigit(name[0]) || (name[0]>='a' && name[0]<='z')) // isalnum non funziona!
 | 
						||
              list.add(name);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    s.close();
 | 
						||
    ::remove(local);
 | 
						||
  }
 | 
						||
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::HttpSoap(CONNID id, const char* cmd)
 | 
						||
{
 | 
						||
  bool ok = false;
 | 
						||
 | 
						||
	TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
  if (conn == NULL)
 | 
						||
    return ok;
 | 
						||
  
 | 
						||
  if (cmd == NULL || *cmd == '\0')
 | 
						||
    return ok;
 | 
						||
 | 
						||
	char hostname[256];
 | 
						||
  xvt_sys_get_host_name(hostname, sizeof(hostname));
 | 
						||
 | 
						||
	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\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))
 | 
						||
  {
 | 
						||
		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);
 | 
						||
			cur_socket->read((char *) m_pData, size);
 | 
						||
			ok = true;
 | 
						||
		}
 | 
						||
	}
 | 
						||
  return ok;
 | 
						||
} 
 | 
						||
 | 
						||
static const char* const eol = "\r\n";
 | 
						||
 | 
						||
bool TSocketClient::HttpPostFile(CONNID id, const char* remote, const char* local, const char* authorization)
 | 
						||
{
 | 
						||
  bool ok = false;
 | 
						||
 | 
						||
	TSocket_connection* conn = (TSocket_connection*)GetConnection(id);
 | 
						||
  if (conn == NULL)
 | 
						||
    return ok;
 | 
						||
 | 
						||
  char peer[MAX_PATH];
 | 
						||
  conn->GetSocket()->getpeername(peer, sizeof(peer));
 | 
						||
 | 
						||
  TString buf(4096);
 | 
						||
  buf << "POST " << remote << " HTTP/1.1" << eol
 | 
						||
      << "Host: " << peer << eol
 | 
						||
      << "User-Agent: Campo" << eol
 | 
						||
      << "Content-Type: text/plain" << eol
 | 
						||
      << "Content-Length: " << fsize(local) << eol;
 | 
						||
  if (authorization && *authorization)
 | 
						||
    buf << "Authorization: " << authorization << eol;
 | 
						||
  buf << eol;
 | 
						||
  
 | 
						||
  ok = conn->WriteLine(buf); 
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    ifstream input(local, ios::binary);
 | 
						||
 | 
						||
    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;
 | 
						||
                    
 | 
						||
    if (ok)                
 | 
						||
    {
 | 
						||
			skstream* cur_socket = conn->GetSocket();
 | 
						||
      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;
 | 
						||
        if (buf.starts_with("Content-length:", true) == 0)
 | 
						||
        {
 | 
						||
          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));
 | 
						||
        cur_socket->read((char *) m_pData, (size_t)m_dwSize);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      ReleaseBuffer();
 | 
						||
      m_dwSize = buf.len()+1;
 | 
						||
      m_pData = new BYTE[m_dwSize];
 | 
						||
      memcpy(m_pData, buf, (size_t)m_dwSize);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
static bool FtpSendCommand(TSocket_connection& conn, const char* cmd, const char* param, TString* line)
 | 
						||
{
 | 
						||
  TString command = cmd;
 | 
						||
  if (param && *param)
 | 
						||
    command << ' ' << param;
 | 
						||
  command << "\r\n";
 | 
						||
 | 
						||
  if (!conn.WriteLine(command))
 | 
						||
    return false;
 | 
						||
 | 
						||
  if (line != NULL)
 | 
						||
  {
 | 
						||
    line->cut(0);
 | 
						||
    if (!conn.ReadLine(*line))
 | 
						||
      return false;
 | 
						||
    line->rtrim();
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TSocketClient::FtpSendFile(CONNID id, const char* remote, const char* local, const char* user, const char* pass)
 | 
						||
{
 | 
						||
  bool ok = false;
 | 
						||
 | 
						||
  if (!fexist(local))
 | 
						||
    return ok;
 | 
						||
 | 
						||
  TString response;
 | 
						||
  if (!ReadLine(id, response)) // 220 Welcome
 | 
						||
    return ok;
 | 
						||
 | 
						||
  TSocket_connection& conn = *(TSocket_connection*)GetConnection(id);
 | 
						||
  if (user==NULL || !*user)
 | 
						||
    user = "anonimous";
 | 
						||
  ok = FtpSendCommand(conn, "USER", user, &response); // 331 Please specify the password.
 | 
						||
  if (!ok || response[0] != '3')
 | 
						||
    return false;
 | 
						||
 | 
						||
  if (pass==NULL || !*pass)
 | 
						||
    pass = "user@campo.it";
 | 
						||
 | 
						||
  ok = FtpSendCommand(conn, "PASS", pass, &response); // 230 Login successful.
 | 
						||
  if (!ok || response[0] != '2')
 | 
						||
    return false;
 | 
						||
    
 | 
						||
  ok = FtpSendCommand(conn, "TYPE", "I", &response); // 200 Switching to Binary mode.
 | 
						||
  if (!ok || response[0] != '2')
 | 
						||
    return false;
 | 
						||
 | 
						||
  FtpSendCommand(conn, "PASV", NULL, &response); // 227 Entering Passive Mode (192,168,4,3,4,82)
 | 
						||
  const TString& address = response.after("(").before(")");
 | 
						||
  int a[6]; 
 | 
						||
  if (sscanf(address, "%d,%d,%d,%d,%d,%d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]) != 6)
 | 
						||
    return false;
 | 
						||
 | 
						||
  ok = FtpSendCommand(conn, "STOR", remote, NULL);
 | 
						||
  if (!ok)
 | 
						||
  return false;
 | 
						||
 | 
						||
  TString16 addr; addr.format("%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
 | 
						||
  const skstream::service port = skstream::service((a[4] << 8) | a[5]);
 | 
						||
  skstream outstream(addr, port) ;
 | 
						||
 | 
						||
  ifstream input(local, ios::binary);
 | 
						||
  while (!input.eof())
 | 
						||
  {
 | 
						||
    input.read(response.get_buffer(), 1024*4);
 | 
						||
    const size_t count = input.gcount();
 | 
						||
    if (count > 0)
 | 
						||
    {
 | 
						||
      outstream.sync();
 | 
						||
      outstream.write(response, count);
 | 
						||
      outstream.flush();
 | 
						||
    }
 | 
						||
    else
 | 
						||
      break;
 | 
						||
  }
 | 
						||
  ok = conn.ReadLine(response); // 150 Ok to send data.
 | 
						||
  if (ok)
 | 
						||
    ok = response[0] == '1';
 | 
						||
 | 
						||
  FtpSendCommand(conn, "QUIT", NULL, NULL);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TDDEClient
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TConnection* TDDEClient::OnQueryConnection(const char* service, const char* server)
 | 
						||
{
 | 
						||
  TConnection* conn = NULL;
 | 
						||
  CONNID id = aga_dde_connect(server, service, "");
 | 
						||
  if (id != 0)
 | 
						||
    conn = new TConnection(this, id);
 | 
						||
  return conn;
 | 
						||
}
 | 
						||
 | 
						||
bool TDDEClient::OnRemoveConnection(CONNID id)
 | 
						||
{
 | 
						||
  aga_dde_terminate(id);
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
byte* TDDEClient::GetBuffer(unsigned int& dwSize)
 | 
						||
{ return NULL; }
 | 
						||
 | 
						||
void TDDEClient::ReleaseBuffer()
 | 
						||
{ }
 | 
						||
 | 
						||
bool TDDEClient::Execute(CONNID id, const char* cmd)
 | 
						||
{
 | 
						||
  return aga_dde_execute(id, cmd) == 0;
 | 
						||
}
 |