.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$vos42c$
.tt 2 $$$
.tt 3 $R.Roedling$create/extract/read/write remote sql_packets$1997-03-27$
***********************************************************
.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  : create/extract/read/write_remote_sql_packets
=========
.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 : 23.3.93
.sp
.cp 3
Version :
.sp
.cp 3
Release :  6.2 	 Date : 1997-03-27
.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__  "VOS42C : "
#define MF__   MOD__"UNDEFINED"

#define ARGID_PORT_NO           0x50   // = P
#define ARGID_REM_PID           0x49   // = I
#define ARGID_ACKNOWLEDGE       0x52   // = R
#define ARGID_NODE              0x3E   // = N
#define ARGID_DBROOT            0x64   // = d
#define ARGID_SERVERPGM         0x70   // = p


/*
 *  MACROS
 */


/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */


/*
 * EXTERNAL VARIABLES
 */


/*
 *  EXPORTED VARIABLES
 */


/*
 * LOCAL VARIABLES
 */


/*
 * LOCAL FUNCTION PROTOTYPES
 */
_INLINE ULONG __sql42c_sndpkt         ( INT                      sd,
                                        PCHAR                    pData,
                                        INT                      Len,
                                        ERRORTEXT                pErrText );

_INLINE ULONG __sql42c_rcvpkt         ( INT                      sd,
                                        ULONG                    ulSwapType,
                                        PRTE_HEADER_REC          pRTEHeader,
                                        PCHAR                    pData,
                                        ULONG                    ulMaxDataLen,
                                        ERRORTEXT                pErrText );

_INLINE ULONG __sql42c_create_conpkt  ( PCONPKT_PARAM_REC        pConPktParamRec,
                                        PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PINT                     pSendLen );

_INLINE ULONG __sql42c_extract_conpkt ( PCONPKT_PARAM_REC        pConPktParamRec,
                                        PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        ERRORTEXT                pErrText );

_INLINE ULONG __sql42c_get_port_no    ( PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PUSHORT                  pusServicePort );

_INLINE ULONG __sql42c_get_rem_pid    ( PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PID                      *pPID );

_INLINE ULONG __sql42c_get_acknowledge( PRTE_CONNECT_PACKET_REC   pConnectPacket,
                                        PBOOL                     pfAcknowledge );

_INLINE ULONG __sql42c_get_dbroot      ( PRTE_CONNECT_PACKET_REC pConnectPacket,
                                         PSZ                     szDBRoot );

_INLINE ULONG __sql42c_get_serverpgm   ( PRTE_CONNECT_PACKET_REC pConnectPacket,
                                         PSZ                     szServerPgm );

_INLINE VOID  __sql42c_put_rem_pid    ( PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PID                      PID );

_INLINE VOID  __sql42c_put_port_no    ( PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        USHORT                   usServicePort );

_INLINE VOID  __sql42c_put_acknowledge( PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        BOOL                     fAcknowledge );

_INLINE VOID  __sql42c_put_dbroot     ( PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PSZ                      pszServerDBRoot );

_INLINE VOID  __sql42c_put_serverpgm  ( PRTE_HEADER_REC          pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC  pConnectPacket,
                                        PSZ                      pszServerPgm );

_INLINE ULONG __sql42c_unpack_int2    ( ULONG                    ulSwapTyp,
                                        INT2                     Src,
                                        INT2                     *pDst,
                                        ERRORTEXT                pErrText );

_INLINE ULONG __sql42c_unpack_int4    ( ULONG                    ulSwapTyp,
                                        INT4                     Src,
                                        INT4                     *pDst,
                                        ERRORTEXT                pErrText );

static ULONG sql42c_generic_send_conpkt ( PCONPKT_PARAM_REC     pConPktParamRec,
                                          BOOLEAN               useSocket,
                                          HANDLE                writePipe,
                                          ERRORTEXT             pErrText );

static ULONG sql42c_generic_recv_conpkt ( PCONPKT_PARAM_REC     pConPktParamRec,
                                          BOOLEAN               useSocket,
                                          HANDLE                readPipe,
                                          ERRORTEXT             pErrText );
/*
 * ========================== GLOBAL FUNCTIONS ================================
 */

ULONG sql42c_send_conpkt ( PCONPKT_PARAM_REC               pConPktParamRec,
                           ERRORTEXT                       pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_send_conpkt"
  return sql42c_generic_send_conpkt (pConPktParamRec, TRUE,
                             INVALID_HANDLE_VALUE, pErrText);
  }

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

ULONG sql42c_pipe_send_conpkt ( PCONPKT_PARAM_REC                pConPktParamRec,
                                HANDLE                           writePipe,
                                ERRORTEXT                        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_pipe_send_conpkt"
  return sql42c_generic_send_conpkt (pConPktParamRec, FALSE,
                             writePipe, pErrText);
  }

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

ULONG sql42c_recv_conpkt ( PCONPKT_PARAM_REC                pConPktParamRec,
                           ERRORTEXT                        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_recv_conpkt"
  return sql42c_generic_recv_conpkt (pConPktParamRec, TRUE,
                             INVALID_HANDLE_VALUE, pErrText);
  }

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

ULONG sql42c_pipe_recv_conpkt ( PCONPKT_PARAM_REC                pConPktParamRec,
                                HANDLE                           readPipe,
                                ERRORTEXT                        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_pipe_recv_conpkt"
  return sql42c_generic_recv_conpkt (pConPktParamRec, FALSE,
                             readPipe, pErrText);
  }

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

ULONG sql42c_send_relpkt ( INT                             sd,
                           ULONG                           ulSenderRef,
                           ULONG                           ulReceiverRef,
                           ULONG                           ulMessClass,
                           ULONG                           ulCommState )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_send_relpkt"
  LONG                            rc;
  INT                             BytesSend;
  RTE_HEADER_REC                  RTEHeader;

  DBGIN;

  //
  // --- Update RTE header.
  //
  RTEHeader.ProtocolID      = RSQL_RTE_PROT_TCP;
  RTEHeader.MessClass       = (INT1)ulMessClass;
  RTEHeader.RTEFlags        = RSQL_NORMAL;
  RTEHeader.ResidualPackets = 0;
  RTEHeader.SenderRef       = ulSenderRef;
  RTEHeader.ReceiverRef     = ulReceiverRef;
  RTEHeader.RTEReturnCode   = (INT2)ulCommState;
  RTEHeader.Filler          = 0;
  RTEHeader.MaxSendLen      = (INT4)RTE_HEADER_SIZE;
  RTEHeader.ResidualPackets = 0;
  RTEHeader.ActSendLen      = (INT4)RTE_HEADER_SIZE;

  //
  // --- Send release packet.
  //
  rc = sql40c_send_packet ( sd, (PCHAR) &RTEHeader,
                            RTEHeader.ActSendLen, &BytesSend );

  if ( rc != NO_ERROR )
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  if ( BytesSend != RTEHeader.ActSendLen )
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

ULONG sql42c_send_packet ( INT                             sd,
                           ULONG                           ulMaxSegmentSize,
                           PCOMM_PACKET_REC                pCommPacket,
                           ULONG                           ulDataLen,
                           ULONG                           ulSenderRef,
                           ULONG                           ulReceiverRef,
                           ULONG                           ulMessClass,
                           ULONG                           ulCommState,
                           ERRORTEXT                       pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_send_packet"
  ULONG                      ulCurrCommState;
  LONG                       lDataRemaining;
  LONG                       ulMaxDataLen;
  PCHAR                      pchSendBuff;
  RTE_HEADER_REC             RTEHeader;
  CHAR                       chDataSave[RTE_HEADER_SIZE];

  DBGIN;

  if ( ulMaxSegmentSize <= RTE_HEADER_SIZE )
    {
    MSGD (( IERR_ILL_MAXSEGMENTSIZE, ulMaxSegmentSize ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_ILL_MAXSEGMENTSIZE, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  //
  // --- Update RTE header.
  //
  pCommPacket->RTEHeader.ProtocolID      = RSQL_RTE_PROT_TCP;
  pCommPacket->RTEHeader.MessClass       = (INT1)ulMessClass;
  pCommPacket->RTEHeader.RTEFlags        = RSQL_NORMAL;
  pCommPacket->RTEHeader.ResidualPackets = 0;
  pCommPacket->RTEHeader.SenderRef       = ulSenderRef;
  pCommPacket->RTEHeader.ReceiverRef     = ulReceiverRef;
  pCommPacket->RTEHeader.RTEReturnCode   = (INT2)ulCommState;
  pCommPacket->RTEHeader.Filler          = 0;
  pCommPacket->RTEHeader.MaxSendLen      = (INT4)ulDataLen + RTE_HEADER_SIZE;
  pCommPacket->RTEHeader.ResidualPackets = 0;
  pCommPacket->RTEHeader.ActSendLen      = pCommPacket->RTEHeader.MaxSendLen;

  if ( (ULONG)pCommPacket->RTEHeader.MaxSendLen <= ulMaxSegmentSize )
    {
    ulCurrCommState = __sql42c_sndpkt( sd, (PCHAR)pCommPacket,
                                       pCommPacket->RTEHeader.ActSendLen,
                                       pErrText );
    }
  else
    {
    // --- save the header informations.
    RTEHeader                 = pCommPacket->RTEHeader;

    ulMaxDataLen              = ulMaxSegmentSize - RTE_HEADER_SIZE;
    RTEHeader.ResidualPackets = (INT1)(ulDataLen / ulMaxDataLen);
    pchSendBuff               = (PCHAR)pCommPacket;


    for ( lDataRemaining  = ulDataLen;
          lDataRemaining;
          lDataRemaining -= ulDataLen )
      {
      ulDataLen            = min ( ulMaxDataLen, lDataRemaining );
      RTEHeader.ActSendLen = (INT4)ulDataLen + RTE_HEADER_SIZE;

      // --- Save a part of data to replace it with the current header
      //     information.
      memcpy ( chDataSave,  pchSendBuff, RTE_HEADER_SIZE );
      memcpy ( pchSendBuff, &RTEHeader,  RTE_HEADER_SIZE );

      ulCurrCommState = __sql42c_sndpkt( sd, pchSendBuff, RTEHeader.ActSendLen,
                                         pErrText );

      // --- restore saved data part.
      memcpy ( pchSendBuff, chDataSave, RTE_HEADER_SIZE );

      if ( ulCurrCommState != SQLOK )
        break;

      RTEHeader.ResidualPackets--;
      pchSendBuff += ulDataLen;
      }
    }

  DBGOUT;
  return ( ulCurrCommState ) ;
  }

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

ULONG sql42c_send_header ( INT                             sd,
                           ULONG                           ulSenderRef,
                           ULONG                           ulReceiverRef,
                           ULONG                           ulMessClass,
                           ULONG                           ulCommState,
                           ERRORTEXT                       pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_send_header"
  ULONG                      ulCurrCommState;
  RTE_HEADER_REC             RTEHeader;

  DBGIN;

  //
  // --- Create RTE header.
  //
  RTEHeader.ProtocolID      = RSQL_RTE_PROT_TCP;
  RTEHeader.MessClass       = (INT1)ulMessClass;
  RTEHeader.RTEFlags        = RSQL_NORMAL;
  RTEHeader.ResidualPackets = 0;
  RTEHeader.SenderRef       = ulSenderRef;
  RTEHeader.ReceiverRef     = ulReceiverRef;
  RTEHeader.RTEReturnCode   = (INT2)ulCommState;
  RTEHeader.Filler          = 0;
  RTEHeader.MaxSendLen      = (INT4)RTE_HEADER_SIZE;
  RTEHeader.ResidualPackets = 0;
  RTEHeader.ActSendLen      = RTEHeader.MaxSendLen;

  ulCurrCommState = __sql42c_sndpkt( sd, (PCHAR)&RTEHeader,
                                     RTEHeader.ActSendLen,
                                     pErrText );

  DBGOUT;
  return ( ulCurrCommState ) ;
  }

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

ULONG sql42c_recv_header ( INT                             sd,
                           ULONG                           ulSwapType,
                           PULONG                          pulSenderRef,
                           PULONG                          pulReceiverRef,
                           PULONG                          pulMessClass,
                           ERRORTEXT                       pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_recv_header"
  RTE_HEADER_REC             RTEHeader;
  ULONG                      ulCommState;

  DBGIN;

  ulCommState = __sql42c_rcvpkt ( sd, ulSwapType, &RTEHeader,
                                  NULL, 0, pErrText );

  if ( ulCommState != SQLOK )
    return ( ulCommState );

  *pulSenderRef   = RTEHeader.SenderRef;
  *pulReceiverRef = RTEHeader.ReceiverRef;
  *pulMessClass   = (ULONG)RTEHeader.MessClass;


  DBGOUT;
  return ( ulCommState ) ;
  }



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

ULONG sql42c_recv_packet ( INT                             sd,
                           ULONG                           ulSwapType,
                           PCOMM_PACKET_REC                pCommPacket,
                           ULONG                           ulMaxDataLen,
                           PULONG                          pulDataLen,
                           PULONG                          pulSenderRef,
                           PULONG                          pulReceiverRef,
                           PULONG                          pulMessClass,
                           ERRORTEXT                       pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_recv_packet"
  ULONG                       ulCommState;
  PCHAR                       pDst;
  LONG                        lDataRemaining;
  INT4                        MaxSendLen;

  DBGIN;

  ulCommState = __sql42c_rcvpkt ( sd, ulSwapType, &pCommPacket->RTEHeader,
                                  pCommPacket->pDataPart,
                                  ulMaxDataLen,
                                  pErrText );

  if ( ulCommState != SQLOK )
    return ( ulCommState );

  MaxSendLen = (INT4)ulMaxDataLen + RTE_HEADER_SIZE;

  if (( pCommPacket->RTEHeader.MaxSendLen < RTE_HEADER_SIZE  ) ||
      ( pCommPacket->RTEHeader.MaxSendLen > MaxSendLen ))
    {
    MSGD (( ERR_PACKET_GARBLED, pCommPacket->RTEHeader.MaxSendLen ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_PACKET_GARBLED, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  if ( pCommPacket->RTEHeader.ResidualPackets )
    {
    pDst           = pCommPacket->pDataPart +
                     pCommPacket->RTEHeader.ActSendLen - RTE_HEADER_SIZE;
    MaxSendLen     = pCommPacket->RTEHeader.MaxSendLen;
    lDataRemaining = MaxSendLen - pCommPacket->RTEHeader.ActSendLen;

    for( ; (pCommPacket->RTEHeader.ResidualPackets > 0) &&
           (lDataRemaining                         > 0); )
      {
      ulCommState = __sql42c_rcvpkt ( sd, ulSwapType, &pCommPacket->RTEHeader,
                                      pDst, lDataRemaining, pErrText );

      if ( ulCommState != SQLOK )
        {
        DBGOUT;
        return ( SQLNOTOK );
        }


      // --- New 'MaxSendLen' received?
      if ( pCommPacket->RTEHeader.MaxSendLen != MaxSendLen )
        {
        MSGD (( ERR_REC_NEW_MAXSENDLEN ))
        sql46c_build_error_string ( pErrText,  ERRMSG_COM_PACKET_GARBLED, 0 );

        DBGOUT;
        return ( SQLNOTOK );
        }

      pDst           += pCommPacket->RTEHeader.ActSendLen - RTE_HEADER_SIZE;
      lDataRemaining -= pCommPacket->RTEHeader.ActSendLen - RTE_HEADER_SIZE;
      }

    if (( lDataRemaining >  0 ) ||
        ( pCommPacket->RTEHeader.ResidualPackets >  0 ))
      {
      MSGD (( ERR_REC_MISSING_BYTES, lDataRemaining,
              pCommPacket->RTEHeader.ResidualPackets ));
      sql46c_build_error_string ( pErrText,  ERRMSG_COM_PACKET_GARBLED, 0 );

      DBGOUT;
      return ( SQLNOTOK );
      }

    pCommPacket->RTEHeader.ActSendLen = pCommPacket->RTEHeader.MaxSendLen;
    }

  *pulDataLen     = pCommPacket->RTEHeader.ActSendLen - RTE_HEADER_SIZE;
  *pulSenderRef   = pCommPacket->RTEHeader.SenderRef;
  *pulReceiverRef = pCommPacket->RTEHeader.ReceiverRef;
  *pulMessClass   = (ULONG)pCommPacket->RTEHeader.MessClass;

  if ((  *pulDataLen == 0 ) &&
      (( *pulMessClass == RSQL_USER_RELEASE_REQUEST ) ||
       ( *pulMessClass == RSQL_KERN_RELEASE_REQUEST  )))
    {
    sql46c_build_error_string ( pErrText,
                                ERRMSG_COM_CONN_CLOSED_BY_COM_PART, 0 );

    DBGOUT;
    return ( SQLRELEASED );
    }

  DBGOUT;
  return ( SQLOK );
  }

ULONG sql42c_get_dbroot      ( PRTE_CONNECT_PACKET_REC pConnectPacket,
                               PSZ                     szDBRoot )
{
  return __sql42c_get_dbroot (pConnectPacket, szDBRoot);
}

ULONG sql42c_get_serverpgm  ( PRTE_CONNECT_PACKET_REC pConnectPacket,
                              PSZ                     szServerPgm )
{
  return __sql42c_get_serverpgm (pConnectPacket, szServerPgm);
}



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

_INLINE ULONG __sql42c_sndpkt ( INT              sd,
                                PCHAR            pData,
                                INT              Len,
                                ERRORTEXT        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_sndpkt"
  LONG                            rc;
  INT                             BytesSend;

  DBGIN;

  for (BytesSend = 0; Len > 0; pData += BytesSend, Len -= BytesSend )
    {
    rc = sql40c_send_packet ( sd, pData, Len, &BytesSend );

    if ( rc != NO_ERROR )
      {
      MSGD (( ERR_SOCKET_SND_ERR, rc ));
      sql46c_build_error_string ( pErrText, ERRMSG_COM_SOCKET_SND_ERROR, rc );

      DBGOUT;
      return ( SQLNOTOK );
      }
    }

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_rcvpkt ( INT              sd,
                                ULONG            ulSwapType,
                                PRTE_HEADER_REC  pRTEHeader,
                                PCHAR            pData,
                                ULONG            ulMaxDataLen,
                                ERRORTEXT        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_rcvpkt"
  LONG                            rc;
  INT                             BytesRec;
  INT                             BytesRemaining;
  PCHAR                           pRecvPos;


  DBGIN;


  // --- Receive the RTE Header first!
  //
  for ( BytesRec       = 0,
        pRecvPos       = (PCHAR)pRTEHeader,
        BytesRemaining = RTE_HEADER_SIZE;
        BytesRemaining > 0;
        pRecvPos += BytesRec, BytesRemaining -= BytesRec )
    {
    rc = sql40c_recv_packet ( sd, pRecvPos, BytesRemaining, &BytesRec );

    if ( rc != NO_ERROR )
      {
      MSGD (( ERR_SOCKET_REC_ERR, rc ));
      sql46c_build_error_string ( pErrText, ERRMSG_COM_SOCKET_REC_ERROR, rc );

      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( BytesRec == 0 )
      {
      if ( BytesRemaining != RTE_HEADER_SIZE )
        {
        // --- We have already received some data.
        //
        sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROCKEN, 0 );
        MSGD (( ERR_CONN_BROCKEN ));
        }
      else
        sql46c_build_error_string ( pErrText,
                                    ERRMSG_COM_CONN_CLOSED_BY_COM_PART, 0 );

      DBGOUT;
      return ( SQLNOTOK );
      }
    }


  // --- After the rte header is complete,
  //      we know exactly which size to receive.
  //
  __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->ActSendLen,
                         &pRTEHeader->ActSendLen, pErrText );

  __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->MaxSendLen,
                         &pRTEHeader->MaxSendLen, pErrText );

  __sql42c_unpack_int2 ( ulSwapType, pRTEHeader->RTEReturnCode,
                         &pRTEHeader->RTEReturnCode, pErrText );

  __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->ReceiverRef,
                         &pRTEHeader->ReceiverRef, pErrText );

  __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->SenderRef,
                         &pRTEHeader->SenderRef, pErrText );

  if ( (ULONG)pRTEHeader->ActSendLen > ulMaxDataLen + RTE_HEADER_SIZE )
    {
    MSGD (( ERR_ILL_PACKET_SIZE, pRTEHeader->ActSendLen ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_PACKET_GARBLED, 0 );
    return ( SQLNOTOK );
    }


  for( BytesRec = 0, BytesRemaining = pRTEHeader->ActSendLen - RTE_HEADER_SIZE;
       BytesRemaining > 0;
       pData += BytesRec, BytesRemaining -= BytesRec )
    {
    rc = sql40c_recv_packet ( sd, pData, BytesRemaining, &BytesRec );

    if ( rc != NO_ERROR )
      {
      MSGD (( ERR_SOCKET_REC_ERR, rc ));
      sql46c_build_error_string ( pErrText, ERRMSG_COM_SOCKET_REC_ERROR, rc );

      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( BytesRec == 0 )
      {
      sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROCKEN, 0 );
      MSGD (( ERR_CONN_BROCKEN ));
      DBGOUT;
      return ( SQLNOTOK );
      }
    }


  if ( pRTEHeader->RTEReturnCode )
    {
    sql46c_build_error_string ( pErrText,
                                ERRMSG_COM_BAD_RTE_RETURN_CODE, 0 );
    }

  DBGOUT;
  return ( pRTEHeader->RTEReturnCode );
  }

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

_INLINE ULONG __sql42c_create_conpkt( PCONPKT_PARAM_REC       pConPktParamRec,
                                      PRTE_HEADER_REC         pRTEHeader,
                                      PRTE_CONNECT_PACKET_REC pConnectPacket,
                                      PINT                    pSendLen )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_create_conpkt"
  INT                           i;
  union map_check_i4_b4         MapCheck;

  DBGIN;

  pRTEHeader->ActSendLen       = sizeof (*pRTEHeader) +
                                 sizeof (*pConnectPacket) -
                                 sizeof (pConnectPacket->VarPart);
  pRTEHeader->ProtocolID       = RSQL_RTE_PROT_TCP;
  pRTEHeader->RTEFlags         = RSQL_NORMAL;
  pRTEHeader->MessClass        = (INT1)pConPktParamRec->ulMessClass;
  pRTEHeader->ResidualPackets  = 0;
  pRTEHeader->SenderRef        = (INT4)pConPktParamRec->ulSenderRef;
  pRTEHeader->ReceiverRef      = (INT4)pConPktParamRec->ulReceiverRef;
  pRTEHeader->RTEReturnCode    = (INT2)pConPktParamRec->ulCommState;
  pRTEHeader->Filler           = 0;
  pRTEHeader->MaxSendLen       = pRTEHeader->ActSendLen;

  i = ' ';
  if ( i == 32 )
    pConnectPacket->sMessCode[ 0 ] = 0;
  else
    pConnectPacket->sMessCode[ 0 ] = 1;

  MapCheck.int4 = 65536;
  for ( i = 0; (i < 4) && ( MapCheck.c4[ i ] != 1 ); i++ ) { ; }

  pConnectPacket->sMessCode[ 1 ] = i;
  pConnectPacket->ConnectLength  = sizeof (*pConnectPacket) -
                                   sizeof (pConnectPacket->VarPart);
  pConnectPacket->ServiceType    = (INT1)pConPktParamRec->ulServiceType;
  pConnectPacket->OSType         = RSQL_OS_TYPE;
  pConnectPacket->MaxSegmentSize = (INT4)pConPktParamRec->ulMaxSegmentSize;
  pConnectPacket->PacketSize     = (INT4)pConPktParamRec->ulPacketSize;
  pConnectPacket->MaxDataLen     = (INT4)pConPktParamRec->ulMaxDataLen;
  pConnectPacket->MinReplySize   = (INT4)pConPktParamRec->ulMinReplySize;
  pConnectPacket->Filler1        = 0;
  pConnectPacket->Filler2        = 0;

  sql47c_ctop ( pConnectPacket->ReceiverServerDB,
                pConPktParamRec->szReceiverServerDB,
                sizeof ( pConnectPacket->ReceiverServerDB ));
  sql47c_ctop ( pConnectPacket->SenderServerDB,
                pConPktParamRec->szSenderServerDB,
                sizeof ( pConnectPacket->SenderServerDB ));

  __sql42c_put_rem_pid    ( pRTEHeader, pConnectPacket,
                            pConPktParamRec->pidSenderPID );

  __sql42c_put_port_no    ( pRTEHeader, pConnectPacket,
                            pConPktParamRec->usServicePort );

  __sql42c_put_acknowledge ( pRTEHeader, pConnectPacket,
                             pConPktParamRec->fAcknowledge );

  __sql42c_put_dbroot      ( pRTEHeader, pConnectPacket, 
                             pConPktParamRec->szServerDBRoot );

  __sql42c_put_serverpgm   ( pRTEHeader, pConnectPacket, 
                             pConPktParamRec->szServerPgm );

  *pSendLen = pRTEHeader->ActSendLen;

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_extract_conpkt ( PCONPKT_PARAM_REC       pConPktParamRec,
                                        PRTE_HEADER_REC         pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC pConnectPacket,
                                        ERRORTEXT               pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_extract_conpkt"
  ULONG            ulCommState   = SQLOK;
  INT              ulSwapType    = 0;
  PID              pidSenderPID  = 0;
  USHORT           usServicePort = 0;
  BOOL             fAcknowledge;

  DBGPAS;



  ulSwapType  = pConnectPacket->sMessCode[ 1 ];

  if ( __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->ActSendLen,
                              &pRTEHeader->ActSendLen,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int2 ( ulSwapType, pRTEHeader->RTEReturnCode,
                              &pRTEHeader->RTEReturnCode,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->MaxSendLen,
                              &pRTEHeader->MaxSendLen,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->ReceiverRef,
                              &pRTEHeader->ReceiverRef,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pRTEHeader->SenderRef,
                              &pRTEHeader->SenderRef,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int2 ( ulSwapType, pConnectPacket->ConnectLength,
                              &pConnectPacket->ConnectLength,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pConnectPacket->MaxSegmentSize,
                              &pConnectPacket->MaxSegmentSize,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pConnectPacket->MaxDataLen,
                              &pConnectPacket->MaxDataLen,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pConnectPacket->PacketSize,
                              &pConnectPacket->PacketSize,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  if ( __sql42c_unpack_int4 ( ulSwapType, pConnectPacket->MinReplySize,
                              &pConnectPacket->MinReplySize,
                              pErrText ) != SQLOK )
    return ( SQLNOTOK );

  __sql42c_get_rem_pid    ( pConnectPacket, &pidSenderPID );
  __sql42c_get_port_no    ( pConnectPacket, &usServicePort );
  __sql42c_get_acknowledge( pConnectPacket, &fAcknowledge );

  pConPktParamRec->ulSwapType          = ulSwapType;
  pConPktParamRec->pidSenderPID        = pidSenderPID;
  pConPktParamRec->usServicePort       = usServicePort;
  pConPktParamRec->fAcknowledge        = fAcknowledge;

  pConPktParamRec->ulCommState         = pRTEHeader->RTEReturnCode;
  pConPktParamRec->ulSenderRef         = pRTEHeader->SenderRef;
  pConPktParamRec->ulReceiverRef       = pRTEHeader->ReceiverRef;
  pConPktParamRec->ulMessClass         = pRTEHeader->MessClass;

  pConPktParamRec->ulServiceType       = pConnectPacket->ServiceType;
  pConPktParamRec->ulMaxSegmentSize    = pConnectPacket->MaxSegmentSize;
  pConPktParamRec->ulPacketSize        = pConnectPacket->PacketSize;
  pConPktParamRec->ulMaxDataLen        = pConnectPacket->MaxDataLen;
  pConPktParamRec->ulMinReplySize      = pConnectPacket->MinReplySize;

  sql47c_ptoc ( pConPktParamRec->szSenderServerDB,
                pConnectPacket->SenderServerDB,
                sizeof( pConnectPacket->SenderServerDB ));
  sql47c_ptoc ( pConPktParamRec->szReceiverServerDB,
                pConnectPacket->ReceiverServerDB,
                sizeof( pConnectPacket->ReceiverServerDB ));

  return ( ulCommState );
  }

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

/*
 *  Here, we have some functions which use the var_part of the connect
 *  info packet. The var_part can contain several information and is
 *  structured as follows:
 *
 *  var_part: [argument][argument]...
 *
 *  Each argument is structured as follows:
 *
 *  argument: |length|id|information|
 *
 *            'length'      is a one byte integer.
 *                          It includes the length and id-bytes.
 *            'id'          is a one byte character
 *            'information' is coded argument dependent
 *
 *  Example:
 *
 *      var_part: 04 50 1b 58 06 49 31 32 33 00 (hexadecimal)
 *                ^  ^  ^     ^  ^  ^
 *                |  |  |     |  |  |
 *                |  |  |     |  |  NUL terminated string ("123")
 *                |  |  |     |  Argument id 'I' for remote pid
 *                |  |  |     Argument length (6 bytes: length,id,string,\0)
 *                |  |  |
 *                |  |  TCP/IP port number (0x1b58)
 *                |  Argument id 'P' for TCP/IP port number
 *                Argument length (4 bytes: length,id,port number)
 *
 *  There is no terminator for the VarPart since the length of the
 *  connect packet includes the VarPart and thus specifies its length.
 */

_INLINE ULONG __sql42c_get_port_no ( PRTE_CONNECT_PACKET_REC   pConnectPacket,
                                     PUSHORT                   pusServicePort )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_get_port_no"
  ULONG           ulLength;
  ULONG           ulPos;

  DBGIN;

  ulLength = pConnectPacket->ConnectLength  -
             ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  ulLength = min ( ulLength, sizeof (pConnectPacket->VarPart) );

  for ( ulPos =  0;
        ulPos <  ulLength;
        ulPos += pConnectPacket->VarPart[ulPos] & 0xff )
    {
    if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) < 2 )
      {
      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( pConnectPacket->VarPart[ulPos + 1] == ARGID_PORT_NO )
      {
      if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) != 4 )
        {
        MSGD (( WRN_ILL_ARG_LENGTH, pConnectPacket->VarPart[ulPos] & 0xff ));
        DBGOUT;
        return ( SQLNOTOK );
        }
      break;
      }
    }

  if ( ulPos >= ulLength )
    {
    // --- no port number found!
    DBGOUT;
    return ( SQLNOTOK );
    }

  *pusServicePort  = (USHORT)(pConnectPacket->VarPart[ulPos + 2] & 0xff) << 8;
  *pusServicePort |= (USHORT)(pConnectPacket->VarPart[ulPos + 3] & 0xff);

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_get_rem_pid ( PRTE_CONNECT_PACKET_REC   pConnectPacket,
                                     PID                       *pPID )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_get_rem_pid"
  ULONG           ulLength;
  ULONG           ulPos;
  ULONG           ulStrLen;

  DBGIN;

  ulLength = pConnectPacket->ConnectLength  -
             ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  ulLength = min ( ulLength, sizeof (pConnectPacket->VarPart) );

  for ( ulPos =  0;
        ulPos <  ulLength;
        ulPos += pConnectPacket->VarPart[ulPos] & 0xff )
    {
    if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) < 2 )
      {
      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( pConnectPacket->VarPart[ulPos + 1] == ARGID_REM_PID )
      {
      ulStrLen = pConnectPacket->VarPart[ulPos] & 0xff;

      if ( ( ulStrLen < 4 ) ||
           ( pConnectPacket->VarPart[ulPos + ulStrLen - 1 ] != '\0' ))
        {
        MSGD (( WRN_ILL_ARG_LENGTH, pConnectPacket->VarPart[ulPos] & 0xff ));
        DBGOUT;
        return ( SQLNOTOK );
        }
      break;
      }
    }

  if ( ulPos >= ulLength )
    {
    // --- no pid found!
    DBGOUT;
    return ( SQLNOTOK );
    }

  *pPID = (PID)atol( pConnectPacket->VarPart + ulPos + 2 );

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_get_acknowledge( PRTE_CONNECT_PACKET_REC pConnectPacket,
                                        PBOOL                   pfAcknowledge )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_get_acknowledge"
  ULONG           ulLength;
  ULONG           ulPos;

  DBGIN;

  *pfAcknowledge = TRUE;

  ulLength = pConnectPacket->ConnectLength  -
             ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  ulLength = min ( ulLength, sizeof (pConnectPacket->VarPart) );

  for ( ulPos =  0;
        ulPos <  ulLength;
        ulPos += pConnectPacket->VarPart[ulPos] & 0xff )
    {
    if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) < 2 )
      {
      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( pConnectPacket->VarPart[ulPos + 1] == ARGID_ACKNOWLEDGE )
      {
      if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) != 3 )
        {
        MSGD (( WRN_ILL_ARG_LENGTH, pConnectPacket->VarPart[ulPos] & 0xff ));
        DBGOUT;
        return ( SQLNOTOK );
        }
      break;
      }
    }

  if ( ulPos >= ulLength )
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  *pfAcknowledge = ((pConnectPacket->VarPart[ulPos + 2]) == 0);

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_get_dbroot( PRTE_CONNECT_PACKET_REC pConnectPacket,
                                   PSZ                     szDBRoot )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_get_dbroot"
  ULONG           ulLength;
  ULONG           ulPos;
  ULONG           ulArglen;

  DBGIN;

  szDBRoot [0] = '\0';

  ulLength = pConnectPacket->ConnectLength  -
             ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  ulLength = min ( ulLength, sizeof (pConnectPacket->VarPart) );

  for ( ulPos =  0;
        ulPos <  ulLength;
        ulPos += pConnectPacket->VarPart[ulPos] & 0xff )
    {
    if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) < 2 )
      {
      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( pConnectPacket->VarPart[ulPos + 1] == ARGID_DBROOT )
      {
      ulArglen = pConnectPacket->VarPart[ulPos] & 0xff;
      if ( ( ulArglen > sizeof ( PATHNAME ) ) || ( ulArglen == 0 ) )
        {
        MSGD (( WRN_ILL_ARG_LENGTH, ulArglen ));
        DBGOUT;
        return ( SQLNOTOK );
        }
      break;
      }
    }

  if ( ulPos >= ulLength )
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  memcpy (szDBRoot, pConnectPacket->VarPart + ulPos + 2, ulArglen);
  szDBRoot [ulArglen] = '\0';

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_get_serverpgm( PRTE_CONNECT_PACKET_REC pConnectPacket,
                                      PSZ                     szServerPgm )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_get_serverpgm"
  ULONG           ulLength;
  ULONG           ulPos;
  ULONG           ulArglen;

  DBGIN;

  ulLength = pConnectPacket->ConnectLength  -
             ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  ulLength = min ( ulLength, sizeof (pConnectPacket->VarPart) );

  for ( ulPos =  0;
        ulPos <  ulLength;
        ulPos += pConnectPacket->VarPart[ulPos] & 0xff )
    {
    if ( ( pConnectPacket->VarPart[ulPos] & 0xff ) < 2 )
      {
      DBGOUT;
      return ( SQLNOTOK );
      }

    if ( pConnectPacket->VarPart[ulPos + 1] == ARGID_SERVERPGM )
      {
      ulArglen = pConnectPacket->VarPart[ulPos] & 0xff;
      if ( ( ulArglen > sizeof ( PATHNAME ) ) || ( ulArglen == 0 ) )
        {
        MSGD (( WRN_ILL_ARG_LENGTH, ulArglen ));
        DBGOUT;
        return ( SQLNOTOK );
        }
      break;
      }
    }

  if ( ulPos >= ulLength )
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  memcpy (szServerPgm, pConnectPacket->VarPart + ulPos + 2, ulArglen);
  szServerPgm [ulArglen] = '\0';

  DBGOUT;
  return ( SQLOK );
  }

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

_INLINE VOID __sql42c_put_port_no ( PRTE_HEADER_REC           pRTEHeader,
                                    PRTE_CONNECT_PACKET_REC   pConnectPacket,
                                    USHORT                    usServicePort )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_put_port_no"
  ULONG           ulPos;

  DBGIN;

  ulPos  = pConnectPacket->ConnectLength  -
           ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  pConnectPacket->VarPart[ulPos]     = 4;
  pConnectPacket->VarPart[ulPos + 1] = ARGID_PORT_NO;
  pConnectPacket->VarPart[ulPos + 2] = ( usServicePort >> 8 & 0xFF ); // - high byte
  pConnectPacket->VarPart[ulPos + 3] = ( usServicePort      & 0xFF ); // - low  byte

  pConnectPacket->ConnectLength  += 4;
  pRTEHeader->ActSendLen         += 4;
  pRTEHeader->MaxSendLen         += 4;

  DBGOUT;
  return;
  }

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

_INLINE VOID __sql42c_put_acknowledge ( PRTE_HEADER_REC         pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC pConnectPacket,
                                        BOOL                    fAcknowledge )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_put_acknowledge"
  ULONG           ulPos;

  DBGIN;

  ulPos  = pConnectPacket->ConnectLength  -
           ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  pConnectPacket->VarPart[ulPos]     = 3;
  pConnectPacket->VarPart[ulPos + 1] = ARGID_ACKNOWLEDGE;
  pConnectPacket->VarPart[ulPos + 2] = (UINT1) (fAcknowledge == FALSE);

  pConnectPacket->ConnectLength  += 3;
  pRTEHeader->ActSendLen         += 3;
  pRTEHeader->MaxSendLen         += 3;

  DBGOUT;
  return;
  }

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

_INLINE VOID __sql42c_put_dbroot      ( PRTE_HEADER_REC         pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC pConnectPacket,
                                        PSZ                     pszServerDBRoot )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_put_dbroot"
  ULONG           ulPos;
  UINT1           fullLen;

  DBGIN;

  if ((pszServerDBRoot == NULL) || (pszServerDBRoot [0] == '\0'))
    {
    DBGOUT;
    return;
    }
  fullLen = (UINT1)strlen ( pszServerDBRoot ) + 2;
  ulPos  = pConnectPacket->ConnectLength  -
           ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  pConnectPacket->VarPart[ulPos]     = fullLen;
  pConnectPacket->VarPart[ulPos + 1] = ARGID_DBROOT;
  strcpy (pConnectPacket->VarPart + ulPos + 2, pszServerDBRoot);

  pConnectPacket->ConnectLength  += fullLen;
  pRTEHeader->ActSendLen         += fullLen;
  pRTEHeader->MaxSendLen         += fullLen;

  DBGOUT;
  return;
  }

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

_INLINE VOID __sql42c_put_serverpgm   ( PRTE_HEADER_REC         pRTEHeader,
                                        PRTE_CONNECT_PACKET_REC pConnectPacket,
                                        PSZ                     pszServerPgm )
  {
  #undef  MF__
  #define MF__ mod__"__sql42c_put_serverpgm"
  ULONG           ulPos;
  UINT1           fullLen;

  DBGIN;

  if ((pszServerPgm == NULL) || (pszServerPgm [0] == '\0'))
    {
    DBGOUT;
    return;
    }
  fullLen = (UINT1)strlen ( pszServerPgm ) + 2;
  ulPos  = pConnectPacket->ConnectLength  -
           ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  pConnectPacket->VarPart[ulPos]     = fullLen;
  pConnectPacket->VarPart[ulPos + 1] = ARGID_SERVERPGM;
  strcpy (pConnectPacket->VarPart + ulPos + 2, pszServerPgm);

  pConnectPacket->ConnectLength  += fullLen;
  pRTEHeader->ActSendLen         += fullLen;
  pRTEHeader->MaxSendLen         += fullLen;

  DBGOUT;
  return;
  }

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

_INLINE VOID __sql42c_put_rem_pid ( PRTE_HEADER_REC           pRTEHeader,
                                    PRTE_CONNECT_PACKET_REC   pConnectPacket,
                                    PID                       pid )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_put_rem_pid"
  USHORT          usLength;
  ULONG           ulPos;

  DBGIN;

  ulPos  = pConnectPacket->ConnectLength  -
           ( sizeof (*pConnectPacket) - sizeof (pConnectPacket->VarPart) );

  _ultoa ( pid, (PSZ)pConnectPacket->VarPart + ulPos + 2, 10 );
  usLength = (USHORT)strlen ( (PSZ)pConnectPacket->VarPart + ulPos + 2 ) + 3;

  pConnectPacket->VarPart[ulPos]      = (UCHAR)usLength;
  pConnectPacket->VarPart[ulPos + 1]  = ARGID_REM_PID;

  pConnectPacket->ConnectLength  += usLength;
  pRTEHeader->ActSendLen         += usLength;
  pRTEHeader->MaxSendLen         += usLength;

  DBGOUT;
  return;
  }

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

_INLINE ULONG __sql42c_unpack_int2 ( ULONG                 ulSwapTyp,
                                     INT2                  Src,
                                     INT2                  *pDst,
                                     ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_unpack_int2"
  register PUCHAR puc;

  DBGPAS;

  puc = (PUCHAR) &Src;

  switch ( ulSwapTyp )
    {
    case 1:
          // --- no swap: hi-lo
          *pDst = ( puc[ 0 ] << 8 ) | ( puc[ 1 ] << 0 );
          break;
    case 2:
          // --- full swap: lo-hi
    case 3:
          // --- half swap: lo-hi
          *pDst = ( puc[ 0 ] << 0 ) | ( puc[ 1 ] << 8 );
          break;
    default:
          MSGD (( IERR_ILL_SWAP_TYPE, ulSwapTyp ));
          sql46c_build_error_string ( pErrText, ERRMSG_ILL_SWAP_TYPE, 0 );
          *pDst = 0;
          return ( SQLNOTOK );
    }

  return ( SQLOK );
  }

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

_INLINE ULONG __sql42c_unpack_int4 ( ULONG                 ulSwapTyp,
                                     INT4                  Src,
                                     INT4                  *pDst,
                                     ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"__sql42c_unpack_int4"
  register PUCHAR puc;

  DBGPAS;

  puc = (PUCHAR) &Src;

  switch ( ulSwapTyp )
    {
    case 1:
          // --- no swap
          *pDst = ( puc[ 0 ] << 24 ) |
                  ( puc[ 1 ] << 16 ) |
                  ( puc[ 2 ] <<  8 ) |
                  ( puc[ 3 ] <<  0 );
          break;
    case 2:
          // --- full swap
          *pDst = ( puc[ 0 ] <<  0 ) |
                  ( puc[ 1 ] <<  8 ) |
                  ( puc[ 2 ] << 16 ) |
                  ( puc[ 3 ] << 24 );
          break;
    case 3:
          // --- half swap
          *pDst = ( puc[ 0 ] <<  8 ) |
                  ( puc[ 1 ] <<  0 ) |
                  ( puc[ 2 ] << 24 ) |
                  ( puc[ 3 ] << 16 );
          break;
    default:
          MSGD (( IERR_ILL_SWAP_TYPE, ulSwapTyp ));
          sql46c_build_error_string ( pErrText, ERRMSG_ILL_SWAP_TYPE, 0 );
          *pDst = 0;
          return ( SQLNOTOK );
    }

  return ( SQLOK );
  }

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

static ULONG sql42c_generic_send_conpkt ( PCONPKT_PARAM_REC    pConPktParamRec,
                                          BOOLEAN              useSocket,
                                          HANDLE               writePipe,
                                          ERRORTEXT            pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_send_conpkt"
  LONG                            rc;
  INT                             BytesSend;
  INT                             SendLen;
  ULONG                           ulCommState;
  PRTE_HEADER_REC                 pRTEHeader;
  PRTE_CONNECT_PACKET_REC         pConnectPacket;
  UCHAR                           ucPacket[sizeof(RTE_HEADER_REC) +
                                           sizeof(RTE_CONNECT_PACKET_REC)];

  DBGIN;

  /*
   * - Structure of the remote connect packet:
   *
   *      +------------------------------------+
   *      |     rte_header_record              |
   *      +------------------------------------+
   *      |     rte_connect_packet_record      |
   *      +------------------------------------+
   *
   */
  pRTEHeader     = (PRTE_HEADER_REC) &ucPacket[0];
  pConnectPacket = (PRTE_CONNECT_PACKET_REC) &ucPacket[sizeof(RTE_HEADER_REC)];

  ulCommState = __sql42c_create_conpkt ( pConPktParamRec, pRTEHeader,
                                         pConnectPacket, &SendLen );

  if ( ulCommState != SQLOK )
    return ( ulCommState );

  //
  // --- Send connect packet.
  //
  if (useSocket)
    {
    rc = sql40c_send_packet ( pConPktParamRec->sd, (PCHAR) &ucPacket,
                            SendLen, &BytesSend );
    }
  else 
    {
    rc = WRITE_FILE (writePipe, &ucPacket, SendLen, &BytesSend);
    }

  if ( rc != NO_ERROR )
    {
    MSGD (( ERR_CANT_SND_TO_SOCKET, rc ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_SND_TO_SOCKET, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  if ( BytesSend != SendLen )
    {
    MSGD (( ERR_PACK_SEND_SIZE_ERROR, BytesSend ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_PACK_SEND_SIZE_ERROR, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG sql42c_generic_recv_conpkt ( PCONPKT_PARAM_REC    pConPktParamRec,
                                          BOOLEAN              useSocket,
                                          HANDLE               readPipe,
                                          ERRORTEXT            pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql42c_generic_recv_conpkt"
  INT                             BytesRec;
  LONG                            rc;
  ULONG                           ulCommState;
  PRTE_HEADER_REC                 pRTEHeader;
  PRTE_CONNECT_PACKET_REC         pConnectPacket;
  UCHAR                           ucPacket[sizeof(RTE_HEADER_REC     ) +
                                           sizeof(RTE_CONNECT_PACKET_REC)];

  DBGIN;

  /*
   * - Structure of the remote connect packet:
   *
   *      +------------------------------------+
   *      |     rte_header_record              |
   *      +------------------------------------+
   *      |     rte_connect_packet_record      |
   *      +------------------------------------+
   *
   */
  pRTEHeader     = (PRTE_HEADER_REC) &ucPacket[0];
  pConnectPacket = (PRTE_CONNECT_PACKET_REC) &ucPacket[sizeof(RTE_HEADER_REC)];

  if (useSocket)
    {
    rc = sql40c_recv_packet ( pConPktParamRec->sd, ucPacket,
                            sizeof(ucPacket), &BytesRec );
    }
  else
    {
    rc = READ_FILE (readPipe, ucPacket, sizeof(ucPacket), &BytesRec );
    }

  if ( rc != NO_ERROR )
    {
    MSGD (( ERR_CONN_PACKET_REC_ERR, rc ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_PACKET_REC_ERR, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  if ( BytesRec == 0 )
    {
    MSGD (( ERR_CONN_SERV_REJECT ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_SERV_REJECT, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  if ( BytesRec <  sizeof (ucPacket) - sizeof (pConnectPacket->VarPart))

    {
    MSGD (( ERR_CONN_PACKET_GARBLED, BytesRec ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_PACKET_GARBLED, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  ulCommState = __sql42c_extract_conpkt ( pConPktParamRec, pRTEHeader,
                                          pConnectPacket, pErrText );

  if ( ulCommState != SQLOK )
    {
    return ( ulCommState );
    }

  switch ( pConPktParamRec->ulCommState )
    {
    case SQLTASKLIMIT :
       MSGD (( ERR_TO_MANY_SESSIONS ));
       sql46c_build_error_string ( pErrText, ERRMSG_COM_TO_MANY_DB_SESSIONS, 0 );

       DBGOUT;
       return ( pConPktParamRec->ulCommState );

    case SQLSTART_REQUIRED:
       MSGD (( ERR_COM_SERVER_OR_DB_NOT_ACC ));
       sql46c_build_error_string( pErrText, ERRMSG_COM_DATABASE_NOT_STARTED, 0);

       DBGOUT;
       return ( pConPktParamRec->ulCommState );

    case SQLOK:
       break;

    default:
       MSGD (( ERR_CONN_REFUSED ))
       sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_REFUSED,
                                   0 );

       DBGOUT;
       return ( pConPktParamRec->ulCommState );
    }

  if (( pRTEHeader->ActSendLen       != pRTEHeader->MaxSendLen ) ||
      ( pRTEHeader->ResidualPackets  != 0 ) ||
      ( pRTEHeader->ActSendLen       >  sizeof (ucPacket) ))
    {
    MSGD (( ERR_CONN_PACKET_GARBLED, BytesRec ))
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_PACKET_GARBLED, 0 );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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