.ad 8
.bm 8
.fm 4
.bt $Copyright by   Software AG, 1993$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$vos40lc$
.tt 2 $$$
.tt 3 $R.Roedling$TCP/IP$1997-06-12$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2002 SAP AG

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    ========== licence end

.fo
.nf
.sp
Module  : TCP/IP
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : R.Roedling
.sp
.cp 3
Created : 13.3.93
.sp
.cp 3
Version :
.sp
.cp 3
Release :  6.2 	 Date : 1997-06-12
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
/*PRETTY*/

/*
 * INCLUDE FILES
 */

/*
 *  DEFINES
 */
#define MOD__  "VOS40LC : "
#define MF__   MOD__"UNDEFINED"



/*
 *  MACROS
 */
#define MK_PA(f)       (*lp##f)

#define LOAD_FUNC(f)   ((lp##f = sql40c_load_tcp_func(#f)) == NULL) ? \
                         -1 : NO_ERROR

#define CALL_FUNC(f,p) ( lp##f == NULL ) ? sql40c_func_err(#f),-1 :   \
                                           lp##f##p;

/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */

/*
 * EXTERNAL VARIABLES
 */


/*
 *  EXPORTED VARIABLES
 */


/*
 * LOCAL VARIABLES
 */
static HINSTANCE    hinstTCPIPDLL = NULL;

static BOOL MK_PA (sql40c_sock_init)           ( VOID );

static BOOL MK_PA (sql40c_get_dll_version)     ( PRTE_VERSION_ID pRTEVersion );

static BOOL MK_PA (sql40c_get_sock_version)    ( UCHAR    *pcMajorSockVersion,
                                                 UCHAR    *pcMinorSockVersion );
static BOOL MK_PA (sql40c_sock_cleanup)        ( VOID );

static INT  MK_PA (sql40c_getservbyname)       ( PCHAR    pszService,
                                                 PUSHORT  pusServicePort );
static INT  MK_PA (sql40c_gethostbyname)       ( PSZ      pszHostName,
                                                 PUCHAR   pucAddr,
                                                 PINT     pAddrLen );
static INT  MK_PA (sql40c_gethostbyaddr)       ( PSZ      pszHostName,
                                                 PUCHAR   pucAddr,
                                                 LONG     lAddrLen );
static INT  MK_PA (sql40c_gethostbyaddr)       ( PSZ      pszHostName,
                                                 PUCHAR   pucAddr,
                                                 LONG     lAddrLen );
static INT  MK_PA (sql40c_stream_socket)       ( PINT     psd );
static INT  MK_PA (sql40c_socket_close)        ( INT      sd );
static INT  MK_PA (sql40c_accept_conn_request) ( INT      sd,
                                                 PINT     psdClient,
                                                 PVOID    pSockAddr,
                                                 PINT     pLen );
static INT  MK_PA (sql40c_keep_alive)          ( INT      sd );
static INT  MK_PA (sql40c_linger)              ( INT      sd,
                                                 BOOL     fLinger,
                                                 INT      iSeconds );
static INT  MK_PA (sql40c_bind)                ( INT      sd,
                                                 USHORT   usServicePort );
static INT  MK_PA (sql40c_listen)              ( INT      sd,
                                                 INT      Count );
static INT  MK_PA (sql40c_set_send_buffer_size)( INT      sd,
                                                 PINT     pMaxSize,
                                                 INT      MinSize );
static INT  MK_PA (sql40c_set_recv_buffer_size)( INT      sd,
                                                 PINT     pMaxSize,
                                                 INT      MinSize );
static INT  MK_PA (sql40c_connect)             ( INT      sd,
                                                 USHORT   usServicePort,
                                                 PUCHAR   pucName,
                                                 INT      NameLen );
static INT  MK_PA (sql40c_send_packet)         ( INT      sd,
                                                 PCHAR    pPacket,
                                                 INT      SendLen,
                                                 PINT     pBytesSend );
static INT  MK_PA (sql40c_recv_packet)          ( INT     sd,
                                                  PCHAR   pPacket,
                                                  INT     ReceiveLen,
                                                  PINT    pBytesReceived );
static INT  MK_PA (sql40c_select)               ( PINT    pSDCount,
                                                  PVOID   pReadSDMask,
                                                  PVOID   pWriteSDMask,
                                                  PVOID   pExceptSDMask,
                                                  USHORT  usTimeOut );
static INT  MK_PA (sql40c_get_serviceport)      ( INT     sd,
                                                  PUSHORT pusServicePort );


/*
 * LOCAL FUNCTION PROTOTYPES
 */
static VOID* sql40c_load_tcp_func ( PSZ  pszFuncName );
static VOID  sql40c_func_err      ( PSZ  pszFuncName );
static ULONG sql40c_load_functions( VOID );

/*
 * ========================== GLOBAL FUNCTIONS ================================
 */


ULONG sql40c_get_dll_version ( PRTE_VERSION_ID pRTEVersion )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_get_dll_version"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = LOAD_FUNC( sql40c_get_dll_version );

  if ( rc != NO_ERROR )
    {
    memset ( pRTEVersion, 0, sizeof(*pRTEVersion));
    return ( rc );
    }

  CALL_FUNC( sql40c_get_dll_version,(pRTEVersion ));

  return ( rc );
  }

/*------------------------------*/

INT sql40c_sock_init ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_sock_init"
  INT  rc = NO_ERROR;

  rc = sql40c_load_functions();
  if ( rc != NO_ERROR ) return ( rc );

  rc = CALL_FUNC( sql40c_sock_init,() );

  return ( rc );
  }


/*------------------------------*/

INT sql40c_get_sock_version ( UCHAR *pcMajorSockVersion,
                              UCHAR *pcMinorSockVersion )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_get_sock_version"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_get_sock_version,(pcMajorSockVersion,
                                           pcMinorSockVersion) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_sock_cleanup ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_sock_cleanup"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_sock_cleanup, () );

  return ( rc );
  }


/*------------------------------*/

INT sql40c_getservbyname ( PCHAR pszService, PUSHORT pusServicePort )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_getservbyname"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_getservbyname, (pszService, pusServicePort) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_gethostbyname ( PSZ      pszHostName,
                           PUCHAR   pucAddr,
                           PINT     pAddrLen )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_gethostbyname"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_gethostbyname, (pszHostName, pucAddr, pAddrLen) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_gethostbyaddr ( PSZ      pszHostName,
                           PUCHAR   pucAddr,
                           LONG     lAddrLen )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_gethostbyaddr"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_gethostbyaddr, (pszHostName, pucAddr, lAddrLen) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_stream_socket ( PINT psd )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_socket"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_stream_socket, (psd) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_socket_close ( INT sd )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_socket_close"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_socket_close, (sd) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_accept_conn_request ( INT    sd,
                                 PINT   psdClient,
                                 PVOID  pSockAddr,
                                 PINT   pLen )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_accept"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC(sql40c_accept_conn_request,(sd, psdClient, pSockAddr, pLen));

  return ( rc );
  }

/*------------------------------*/

INT sql40c_keep_alive ( INT sd )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_keep_alive"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_keep_alive, (sd) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_linger ( INT sd, BOOL fLinger, INT iSeconds )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_linger"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_linger, (sd, fLinger, iSeconds) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_bind ( INT sd, USHORT usServicePort )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_bind"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_bind, (sd, usServicePort) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_listen ( INT sd, INT Count )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_listen"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_listen, (sd, Count ) );

  return ( rc );
  }


/*------------------------------*/

INT sql40c_set_send_buffer_size ( INT sd, PINT pMaxSize, INT MinSize )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_set_send_buffer_size"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_set_send_buffer_size,
                  (sd, pMaxSize, MinSize) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_set_recv_buffer_size ( INT sd, PINT pMaxSize, INT MinSize )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_set_recv_buffer_size"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_set_recv_buffer_size,
                  (sd, pMaxSize, MinSize) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_connect( INT sd, USHORT usServicePort, PUCHAR pucName, INT NameLen )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_connect"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_connect,
                  (sd, usServicePort, pucName, NameLen) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_send_packet ( INT                             sd,
                         PCHAR                           pPacket,
                         INT                             SendLen,
                         PINT                            pBytesSend )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_send_packet"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_send_packet,
                  (sd, pPacket, SendLen, pBytesSend) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_recv_packet ( INT                             sd,
                         PCHAR                           pPacket,
                         INT                             ReceiveLen,
                         PINT                            pBytesReceived )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_recv_packet"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_recv_packet,
                  (sd, pPacket, ReceiveLen, pBytesReceived) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_select ( PINT                            pSDCount,
                    PVOID                           pReadSDMask,
                    PVOID                           pWriteSDMask,
                    PVOID                           pExceptSDMask,
                    USHORT                          usTimeOut )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_select"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_select, (pSDCount, pReadSDMask,
                  pWriteSDMask, pExceptSDMask, usTimeOut) );

  return ( rc );
  }

/*------------------------------*/

INT sql40c_get_serviceport ( INT sd, PUSHORT pusServicePort )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_get_serviceport"
  INT  rc = NO_ERROR;

  DBGPAS;

  rc = CALL_FUNC( sql40c_get_serviceport, (sd, pusServicePort) );

  return ( rc );
  }

/*------------------------------*/

LONG sql40c_set_tcpip_dll_path ( PSZ  pszTCPIPDLLName )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_set_tcpip_dll_path"
  REG_ENTRY_REC    RegistryEntries[1];
  LONG             rc    = NO_ERROR;

  RegistryEntries[0].pszValueName = REG_VN_TCPIP_DLL;
  RegistryEntries[0].pValue       = pszTCPIPDLLName;
  RegistryEntries[0].ulValueSize  = strlen(pszTCPIPDLLName);
  RegistryEntries[0].ulValueType  = 0;

  rc = sql50_reg_put_applic_values ( NULL, HKEY_LOCAL_MACHINE,
                                     NULL, NULL, 1, RegistryEntries );

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

ULONG sql40c_get_tcpip_dll_path ( PSZ  *ppszTCPIPDLLName )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_get_tcpip_dll_path"
  REG_ENTRY_REC    RegistryEntries[1];
  LONG             rc    = NO_ERROR;
  static PATHNAME  szDLL;

  RegistryEntries[0].pszValueName = REG_VN_TCPIP_DLL;
  RegistryEntries[0].pValue       = szDLL;
  RegistryEntries[0].ulValueSize  = sizeof(szDLL);
  RegistryEntries[0].ulValueType  = REG_EXPAND_SZ;

  rc = sql50_reg_get_applic_values ( NULL, HKEY_LOCAL_MACHINE, REG_SK_DLLS,
                                     1, RegistryEntries );

  if ( rc != NO_ERROR )
    {
    RegistryEntries[0].ulValueType  = REG_SZ;

    rc = sql50_reg_get_applic_values ( NULL, HKEY_LOCAL_MACHINE, REG_SK_DLLS,
                                       1, RegistryEntries );
    }

  if ((rc == NO_ERROR) && (szDLL[0] != '\0' ))
    *ppszTCPIPDLLName = szDLL;
  else
    *ppszTCPIPDLLName = "";

  DBGOUT;
  return ( rc );
  }


/*
 * ========================== LOCAL FUNCTIONS =================================
 */

static ULONG sql40c_load_functions(  VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_load_functions"
  LONG             rc                  = NO_ERROR;
  static BOOL      fAllFunctionsLoaded = FALSE;

  DBGIN;

  if ( !fAllFunctionsLoaded )
  {
    rc = LOAD_FUNC( sql40c_sock_init );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_get_dll_version );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_get_sock_version );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_sock_cleanup );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_getservbyname );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_gethostbyname );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_gethostbyaddr );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_gethostbyaddr );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_stream_socket );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_socket_close );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_accept_conn_request );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_keep_alive );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_linger );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_bind );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_listen );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_set_send_buffer_size );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_set_recv_buffer_size );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_connect );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_send_packet );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_recv_packet );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_select );
    if ( rc != NO_ERROR ) return ( rc );

    rc = LOAD_FUNC( sql40c_get_serviceport );
    if ( rc != NO_ERROR ) return ( rc );

    fAllFunctionsLoaded = TRUE;
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

static VOID* sql40c_load_tcp_func(  PSZ  pszFuncName )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_load_tcp_func"
  static PSZ       pszDLL;
  HINSTANCE        hinst = NULL;
  LONG             rc    = NO_ERROR;
  FARPROC          pFunc;

  DBGIN;

  if ( hinstTCPIPDLL == NULL )
    {
    rc = sql40c_get_tcpip_dll_path ( &pszDLL );

    if ((rc != NO_ERROR) || ( !pszDLL[0] ))
      {
      pszDLL = DEFAULT_TCPIP_DLL;
      MSGCD (( INFO_LOADING_DEFAULT_TCPIP, pszDLL ));
      }

    hinst = LoadLibrary( pszDLL );

    if ( hinst == NULL )
      {
      rc = GetLastError();

      sql60_enable_message_box ();

      MSGALL (( ERR_LOADING_TCPIP_DLL, rc ));

      sql60_disable_message_box ();

      DBGOUT;
      return ( NULL );
      }

    hinstTCPIPDLL = hinst;
    }

  pFunc = GetProcAddress( hinstTCPIPDLL, pszFuncName);

  if ( pFunc == NULL )
    {
    sql60_enable_message_box ();

    MSGALL (( ERR_LOADING_FUNCTION, pszFuncName, pszDLL ));

    sql60_disable_message_box ();
    }

  DBGOUT;
  return ( pFunc );
  }

/*------------------------------*/

static VOID sql40c_func_err( PSZ  pszFuncName )
  {
  #undef  MF__
  #define MF__ MOD__"sql40c_func_err"

  sql60_enable_message_box();

  MSGALL (( IERR_FUNCTION_NOT_LOADED, pszFuncName ));

  sql60_disable_message_box();

  return;
  }


/*
 * =============================== END ========================================
 */
.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
