//===================== CTempMemory_list ==================================
CTempMemory_list::CTempMemory_list()
{
	SRVRTRACE_ENTER(FILE_TNSPTB+6);
	list=NULL;
	m_list_length = 0;
	SRVRTRACE_EXIT(FILE_TNSPTB+6);
}
CTCPIPSystemSrvr* CTCPIPSystemSrvr_list::ins_node( short nSocketFnum )
{
	SRVRTRACE_ENTER(FILE_TSS+3);

	CTCPIPSystemSrvr* cnode = list;
	CTCPIPSystemSrvr* pnode = list;
	CTCPIPSystemSrvr* nnode;

	del_node(nSocketFnum);

	while(cnode!=NULL )
	{
		pnode=cnode;
		cnode=cnode->next;
	}
	if((nnode = (CTCPIPSystemSrvr*) new CTCPIPSystemSrvr(nSocketFnum))!=NULL)
	{
		nnode->next = cnode;
		if(pnode!=NULL) 
			pnode->next = nnode;
		else
			list = nnode;
	}
	SRVRTRACE_EXIT(FILE_TSS+3);
	return nnode;
}
CEE_status
odbc_SQLSvc_TerminateDialogue_ts_res_(
    /* In    */ CEE_tag_def objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In    */ const struct odbc_SQLSvc_TerminateDialogue_exc_ *exception_
  )
{
	SRVRTRACE_ENTER(FILE_OIOM+2);
	CInterface* pnode = (CInterface*)objtag_;

	CEE_status sts = CEE_SUCCESS;

	CEERCV_IOMessage_exc_ RCVexception_;
	IDL_short error;
	short reply_count;
	CEERCV_IOMessage_reply_seq_ reply;

	char* buffer = NULL;
	UInt32 message_length = 0;

	sts = odbc_SQLSvc_TerminateDialogue_param_res_(
			  pnode
			, buffer
			, message_length
			, exception_
	);
	if (sts == CEE_SUCCESS)
		sts = pnode->send_response(buffer, message_length, call_id_);
	SRVRTRACE_EXIT(FILE_OIOM+2);
	return sts;
}
CEE_status
odbc_SQLSrvr_EndTransaction_ts_res_(
    /* In    */ CEE_tag_def objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In    */ const struct odbc_SQLSvc_EndTransaction_exc_ *exception_
  , /* In    */ ERROR_DESC_LIST_def *sqlWarning
  )
{
	SRVRTRACE_ENTER(FILE_OIOM+13);
	CInterface* pnode = (CInterface*)objtag_;

	CEE_status sts = CEE_SUCCESS;

	CEERCV_IOMessage_exc_ RCVexception_;
	IDL_short error;
	short reply_count;
	CEERCV_IOMessage_reply_seq_ reply;

	char* buffer = NULL;
	UInt32 message_length = 0;

	odbc_SQLSrvr_EndTransaction_param_res_(
			  pnode
			, buffer
			, message_length
			, exception_
			, sqlWarning
	);
	if (sts == CEE_SUCCESS)
		sts = pnode->send_response(buffer, message_length, call_id_);
	SRVRTRACE_EXIT(FILE_OIOM+13);
	return sts;

} // odbc_SQLSrvr_EndTransaction_ts_res_()
CTimer_list::CTimer_list()
{
	SRVRTRACE_ENTER(FILE_LSN+3);
	list=NULL;
	memset(&m_timer_handle,0,sizeof(CEE_handle_def));
	SRVRTRACE_EXIT(FILE_LSN+3);
}
CEE_status
odbc_SQLSrvr_Close_ts_res_(
    /* In    */ CEE_tag_def objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In    */ IDL_long returnCode
  , /* In    */ IDL_long rowsAffected
  , /* In    */ IDL_long sqlWarningOrErrorLength
  , /* In    */ BYTE *sqlWarningOrError
  )
{
	SRVRTRACE_ENTER(FILE_OIOM+12);

	CInterface* pnode = (CInterface*)objtag_;
	CEE_status sts = CEE_SUCCESS;

	IDL_char* buffer = NULL;
	IDL_unsigned_long message_length = 0;

	odbc_SQLSrvr_Close_param_res_(
			  pnode
			, buffer
			, message_length
			, returnCode
			, sqlWarningOrErrorLength
			, sqlWarningOrError
			, rowsAffected
	);

	if (sts == CEE_SUCCESS)
		sts = pnode->send_response(buffer, message_length, call_id_);
	SRVRTRACE_EXIT(FILE_OIOM+12);
	return sts;
}
/* 
 *   write_count: on input  contains the input size (i.e. uncompressed size)
 *              : on output contains the size after compression
 */
void DoCompression(CTCPIPSystemSrvr* pnode, HEADER* wheader, unsigned char* wbuffer, unsigned long& write_count)
{
	SRVRTRACE_ENTER(FILE_TSS+19);
	bool retcode = true;
	unsigned long inCmpCount = write_count; // In number of bytes 

	unsigned char* cmp_buf = NULL;

	retcode = pnode->m_compression.compress((unsigned char*)wbuffer,  // input buffer (data to be compressed)
																  (unsigned int)inCmpCount,              // input number of bytes
																  (int)COMP_DEFAULT,
	                                               (unsigned char**)&cmp_buf,                 // output buffer containing compressed output
																  (unsigned long&)write_count);            // input/output param - input == max size, on output contains compressed size

	if (retcode == false)
	{
		delete[] cmp_buf;
		wheader->compress_type = COMP_NO_COMPRESSION;
		wheader->cmp_length = 0;
		write_count = inCmpCount;
		SRVRTRACE_EXIT(FILE_TSS+19);
		return;
	}
	memcpy(wbuffer, cmp_buf, write_count);

	delete[] cmp_buf; //allocated in m_compression.compress();
	wheader->compress_type=COMP_DEFAULT;
	wheader->cmp_length = write_count;
	SRVRTRACE_EXIT(FILE_TSS+19);
}
CEE_status
odbc_SQLSrvr_SetConnectionOption_ts_res_(
    /* In    */ CEE_tag_def objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In    */ const struct odbc_SQLSvc_SetConnectionOption_exc_ *exception_
  , /* In    */ ERROR_DESC_LIST_def *sqlWarning
  )
{
	SRVRTRACE_ENTER(FILE_OIOM+3);
	CInterface* pnode = (CInterface*)objtag_;
	CEE_status sts = CEE_SUCCESS;

	IDL_char* buffer = NULL;
	IDL_unsigned_long message_length = 0;

	sts = odbc_SQLSrvr_SetConnectionOption_param_res_(
			  pnode
			, buffer
			, message_length
			, exception_
			, sqlWarning
	);
	if (sts == CEE_SUCCESS)
		sts = pnode->send_response(buffer, message_length, call_id_);
	SRVRTRACE_EXIT(FILE_OIOM+3);
	return sts;
}
void CNSKListener::CheckReceiveMessage(_cc_status &cc, int countRead, CEE_handle_def* call_id)
{
	SRVRTRACE_ENTER(FILE_LSN+10);
	request_def *request = (request_def*)m_RequestBuf;
	FS_Receiveinfo_Type receive_info;
	FILE_GETRECEIVEINFO_ ((TPT_RECEIVE)&receive_info );
	if (_status_gt(cc))
	{
// it is a system message
		if (request->request_code == ZSYS_VAL_SMSG_TIMESIGNAL)
		{
// signaltimeout message (-22)
			BUILD_TIMER_MSG_CALL((const CEE_handle_def *)&m_call_id, request, countRead, &receive_info);
		}
		else
		{
			BUILD_SYSTEM_MSG_CALL((const CEE_handle_def *)&m_call_id, request, countRead, &receive_info);
		}
	}
	else
	{
// it is a user message
		BUILD_USER_MSG_CALL((const CEE_handle_def *)&m_call_id, request, countRead, &receive_info);
	}
	SRVRTRACE_EXIT(FILE_LSN+10);
}
void CTCPIPSystemSrvr::process_swap( char* buffer )
{
	SRVRTRACE_ENTER(FILE_TSS+1);
// the server does not swap - keeping it in place just
// in case this is being used somewhere
	SRVRTRACE_EXIT(FILE_TSS+1);
}
CTempMemory::~CTempMemory()
{
	SRVRTRACE_ENTER(FILE_TNSPTB+5);
	if(p != NULL) free(p);
	GTransport.m_TempMemory_list.m_list_length--;
	SRVRTRACE_EXIT(FILE_TNSPTB+5);
}
extern void
CEE_HANDLE_SET_NIL( CEE_handle_def *handle)
{
	SRVRTRACE_ENTER(FILE_TNSPTB+3);
	memset(handle, 0, sizeof(CEE_handle_def));
	SRVRTRACE_EXIT(FILE_TNSPTB+3);
}
CEE_status CTimer_list::timer_create( long seconds,long microseconds, void* e_routine, CEE_tag_def u_tag, 
			CEE_handle_def *thandle, int receiveThrId )
{
	SRVRTRACE_ENTER(FILE_LSN+5);
	CTimer* cnode = list;
	CTimer* pnode = list;
	CTimer* nnode;
	static short t_tag = 0;
	_cc_status cc;

	ADD_ONE_TO_HANDLE(&m_timer_handle);
	memcpy(thandle, &m_timer_handle, sizeof(CEE_handle_def));
    cc = SIGNALTIMEOUT(seconds * 100 + microseconds / 100, 0, (long)thandle, &t_tag, receiveThrId);
	if (_status_lt (cc))
	{
//SIGNALTIMEOUT cannot allocate a time-list element (TLE).
		SRVRTRACE_EXIT(FILE_LSN+5);
		SendEventMsg( MSG_SET_SRVR_CONTEXT_FAILED,
						EVENTLOG_INFORMATION_TYPE,
						GetCurrentProcessId(),
						ODBCMX_SERVICE,
						"CTimer_list::timer_create",
						1,
						"SIGNALTIMEOUT cannot allocate a time-list element (TLE)."
				);
		return CEE_OBJECTINITFAILED;
	}
	else if (_status_gt (cc))
	{
//The given timeout value is illegal.
		SRVRTRACE_EXIT(FILE_LSN+5);
		SendEventMsg( MSG_PROGRAMMING_ERROR,
						EVENTLOG_INFORMATION_TYPE,
						GetCurrentProcessId(),
						ODBCMX_SERVICE,
						"CTimer_list::timer_create",
						1,
						"The given timeout value is illegal for SIGNALTIMEOUT."
				);
		return CEE_BADTIME;
	}
//the timer has been created
	while(cnode!=NULL )
	{
		pnode=cnode;
		cnode=cnode->next;
	}
	if((nnode = new CTimer( seconds, microseconds, e_routine, u_tag, thandle, t_tag, cnode))!=NULL)
	{
		if(pnode!=NULL) 
			pnode->next = nnode;
		else
			list = nnode;
	}
	else
		CANCELTIMEOUT ( t_tag );
	SRVRTRACE_EXIT(FILE_LSN+5);
	return (nnode == NULL)?CEE_OBJECTINITFAILED:CEE_SUCCESS;
}
//LCOV_EXCL_STOP
CNSKListener::CNSKListener(): m_TraceCount(0), m_bIPv4 (false)
{
	SRVRTRACE_ENTER(FILE_LSN+9);
	m_bKeepRunning = true;
	m_bTCPThreadKeepRunning = true;
	memset(&m_call_id,0,sizeof(CEE_handle_def));
	SRVRTRACE_EXIT(FILE_LSN+9);
}
//void* CNSKListenerSrvr::OpenTCPIPSession()
//moved to platform specific implementation file
void* CNSKListenerSrvr::CheckTCPIPRequest(void* ipnode)
{
	SRVRTRACE_ENTER(FILE_LSNS+4);
	CTCPIPSystemSrvr* pnode = (CTCPIPSystemSrvr*) ipnode;
	pnode = (CTCPIPSystemSrvr*)PROCESS_TCPIP_REQUEST(pnode);
	SRVRTRACE_EXIT(FILE_LSNS+4);
	return (void*)pnode;
}
void CTCPIPSystemSrvr::w_assign(char* buffer, long length)
{
	SRVRTRACE_ENTER(FILE_TSS+26);
	if (m_wbuffer != NULL)
		delete m_wbuffer;
	m_wbuffer = buffer;
	m_wbuffer_length = length;
	SRVRTRACE_EXIT(FILE_TSS+26);
}
CEE_status CTCPIPSystemSrvr::send_response(char* buffer, unsigned long message_length, const CEE_handle_def *call_id_)
{
	SRVRTRACE_ENTER(FILE_TSS+11);
	CEE_status retcode = WRITE_TCPIP_RESPONSE(this, message_length);
	if (GTransport.m_TempMemory_list.m_list_length )
		DEALLOCATE_TEMP_MEMORY(&m_call_id);
	SRVRTRACE_EXIT(FILE_TSS+11);
	return retcode;
}
//===================== CTempMemory =======================================
CTempMemory::CTempMemory( const CEE_handle_def* call_id, void* p_mem, CTempMemory* cnext)
{
	SRVRTRACE_ENTER(FILE_TNSPTB+4);
	memcpy(&m_call_id, call_id,sizeof(CEE_handle_def));
	p = p_mem;
	next = cnext;
	GTransport.m_TempMemory_list.m_list_length++;
	SRVRTRACE_EXIT(FILE_TNSPTB+4);
}
void CTCPIPSystemSrvr::r_release()
{
	SRVRTRACE_ENTER(FILE_TSS+28);
	if (m_rbuffer != NULL)
		delete m_rbuffer;
	m_rbuffer = NULL;
	m_rbuffer_length = 0;
	SRVRTRACE_EXIT(FILE_TSS+28);
}
CNSKListenerSrvr::~CNSKListenerSrvr()
{
	SRVRTRACE_ENTER(FILE_LSNS+2);
	if (m_nListenSocketFnum > 0)
	{
	    closeTCPIPSession(m_nListenSocketFnum);
	}
	delete doingRequest;
	SRVRTRACE_EXIT(FILE_LSNS+2);
}
CEE_status
odbc_SQLSrvr_Prepare_ts_res_(
    /* In    */ CEE_tag_def objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In   */ IDL_long returnCode
  , /* In   */ IDL_long sqlWarningOrErrorLength
  , /* In   */ BYTE *sqlWarningOrError
  , /* In   */ IDL_long sqlQueryType
  , /* In   */ IDL_long stmtHandleKey
  , /* In   */ IDL_long estimatedCost
  , /* In   */ IDL_long inputDescLength
  , /* In   */ BYTE *inputDesc
  , /* In   */ IDL_long outputDescLength
  , /* In   */ BYTE *outputDesc
 )
{
	SRVRTRACE_ENTER(FILE_OIOM+11);
	CInterface* pnode = (CInterface*)objtag_;

	CEE_status sts = CEE_SUCCESS;

	CEERCV_IOMessage_exc_ RCVexception_;
	IDL_short error;
	short reply_count;
	CEERCV_IOMessage_reply_seq_ reply;

	char* buffer = NULL;
	UInt32 message_length = 0;

	odbc_SQLSrvr_Prepare_param_res_(
			  pnode
			, buffer
			, message_length
			, returnCode
			, sqlWarningOrErrorLength
			, sqlWarningOrError
			, sqlQueryType
			, stmtHandleKey
			, estimatedCost
			, inputDescLength
			, inputDesc
			, outputDescLength
			, outputDesc
	);

	if (sts == CEE_SUCCESS)
	{
		sts = pnode->send_response(buffer, message_length, call_id_);
	}
	SRVRTRACE_EXIT(FILE_OIOM+11);
	return sts;
} /* odbc_SQLSrvr_Prepare_ts_res_() */
CEE_status
odbc_SQLSrvr_Execute_ts_res_(
    /* In    */       CEE_tag_def     objtag_
  , /* In    */ const CEE_handle_def *call_id_
  , /* In    */       IDL_long        returnCode
  , /* In    */       IDL_long        sqlWarningOrErrorLength
  , /* In    */       BYTE           *sqlWarningOrError
  , /* In    */       IDL_long        rowsReturned
  , /* In    */       IDL_long        sqlQueryType
  , /* In    */       IDL_long        estimatedCost
  , /* In    */       IDL_long        outValuesLength
  , /* In    */       BYTE           *outValues
  , /* In    */		  IDL_long outputDescLength // Used with execdirect
  , /* In    */		  BYTE *outputDesc          // Used with execdirect
  , /* In    */		  Long stmtHandle       // Used for SPJ result sets
  , /* In    */       IDL_long   stmtHandleKey  
                          )
{
  SRVRTRACE_ENTER(FILE_OIOM+23);

  CInterface                   *pnode = (CInterface*)objtag_;
  CEE_status                    sts = CEE_SUCCESS;
  CEERCV_IOMessage_exc_         RCVexception_;
  IDL_short                     error;
  short                         reply_count;
  CEERCV_IOMessage_reply_seq_   reply;
  char                         *buffer = NULL;
  UInt32 message_length = 0;

  odbc_SQLSrvr_Execute_param_res_( pnode
			       , buffer
			       , message_length
			       , returnCode
			       , sqlWarningOrErrorLength
			       , sqlWarningOrError
			       , rowsReturned
				   , sqlQueryType
				   , estimatedCost
			       , outValuesLength
			       , outValues
				   , outputDescLength
				   , outputDesc
				   , stmtHandle
				   , stmtHandleKey
				   );

  if (sts == CEE_SUCCESS)
    sts = pnode->send_response(buffer, message_length, call_id_);
  SRVRTRACE_EXIT(FILE_OIOM+11);
  return sts;

}  // end odbc_SQLSrvr_Execute_ts_res_
void BUILD_TCPIP_REQUEST(CTCPIPSystemSrvr* pnode)
{
	SRVRTRACE_ENTER(FILE_TSS+18);
	CEE_tag_def* objtag_ = (CEE_tag_def*)pnode;
	const CEE_handle_def *call_id_ = &pnode->m_call_id;
	short operation_id = pnode->m_rhdr.operation_id;
	short tx_handle[10];

	if(pnode->m_trans_begin_tag != 0 && GETTRANSID(&tx_handle[0]) != 0)
		RESUMETRANSACTION(pnode->m_trans_begin_tag);
	DISPATCH_TCPIPRequest(objtag_, call_id_, operation_id);
	SRVRTRACE_EXIT(FILE_TSS+18);
}
CNSKListenerSrvr::CNSKListenerSrvr()
{
	SRVRTRACE_ENTER(FILE_LSNS+1);
	m_port = 0;
	m_TraceCount = 0;
	m_tcpip_operation = CURR_UNDEFINED;
	m_bIPv4 = true;
	m_TcpProcessName[0] = 0;
	doingRequest = new SB_Thread::Errorcheck_Mutex(true);
	pipefd[0] = 0; //read fd
	pipefd[1] = 0; // write fd
	SRVRTRACE_EXIT(FILE_LSNS+1);
}
CTimer* CTimer_list::find_timerByhandle(const CEE_handle_def* handle)
{
	SRVRTRACE_ENTER(FILE_LSN+7);
	CTimer* cnode = list;
	CTimer* pnode = list;
	while( cnode!= NULL && memcmp(&cnode->m_timer_handle, handle,sizeof(CEE_handle_def)) != 0 )
	{
		pnode = cnode;
		cnode = cnode->next;
	}
	SRVRTRACE_EXIT(FILE_LSN+7);
	return cnode;
}
bool DoExpand(CTCPIPSystemSrvr* pnode, HEADER& rheader, unsigned char* ibuffer, unsigned long& output_size)
{
	SRVRTRACE_ENTER(FILE_TSS+20);
	bool retcode;
	unsigned char* obuffer;
	int error=0;
	char* tcp_obuffer=NULL;

	if(rheader.compress_ind == COMP_YES )
	{
	  /*
	   * check that the compression types is something that the driver understands
	   */ 
	   if((rheader.compress_type < COMP_DEFAULT) ||
		   (rheader.compress_type > COMP_BEST_COMPRESSION))
	   {
		   pnode->send_error(SRVR_ERR_EXPAND_OPERATION,0, NULL);
		   SRVRTRACE_EXIT(FILE_TSS+20);
		   return false;
	   }
	}
	obuffer = (unsigned char*)new char[rheader.total_length +512]; // +512 is just to be safe
	                                                               // (in case something goes wrong in decompression)
	if (obuffer == NULL)
	{
		pnode->send_error(SRVR_ERR_MEMORY_ALLOCATE,(unsigned short)rheader.total_length, NULL);
		SRVRTRACE_EXIT(FILE_TSS+20);
		return false;
	}

	output_size = rheader.total_length; 
	retcode = pnode->m_compression.expand((unsigned char*)ibuffer,            // input compressed buffer    
		                                          (unsigned long)rheader.cmp_length, // input compresses length
		                                          (unsigned char**)&obuffer,            // output buffer after decompression
															   (unsigned long&)output_size,
																(int&)error);       // output size after decompression (should be equal to rheader.total_length)
	//output_size could be 0 or rheader.total_length, no other value.
	if (retcode == false || output_size == 0 )
	{
		delete[] obuffer;
		pnode->send_error(SRVR_ERR_EXPAND_OPERATION,0, NULL);
		SRVRTRACE_EXIT(FILE_TSS+20);
		return false;
	}
	pnode->r_assign((char*)obuffer, output_size);
	rheader.compress_type = COMP_NO_COMPRESSION;
	rheader.cmp_length = 0;

	SRVRTRACE_EXIT(FILE_TSS+20);
	return true;
}
void CTimer_list::timer_destroy(const CEE_handle_def *thandle)
{
	SRVRTRACE_ENTER(FILE_LSN+6);
	_cc_status cc;
	CTimer* cnode = find_timerByhandle(thandle);
	if( cnode==NULL)
	{
		SRVRTRACE_EXIT(FILE_LSN+6);
		return;
	}
	cc = CANCELTIMEOUT ( cnode->m_timer_tag );
	del_timer_node(cnode);
	SRVRTRACE_EXIT(FILE_LSN+6);
}
void CTCPIPSystemSrvr_list::cleanup() 
{
	SRVRTRACE_ENTER(FILE_TSS+2);
	CTCPIPSystemSrvr* cnode = list;
	CTCPIPSystemSrvr* nnode;
	while( cnode != NULL ){
		nnode = cnode->next;
		delete cnode;
		cnode = nnode;
	}
	list=NULL;
	m_node_iterator=NULL;
	SRVRTRACE_EXIT(FILE_TSS+2);
}
//LCOV_EXCL_START
CTimer::CTimer(long seconds, long microseconds, void* e_routine, CEE_tag_def u_tag, 
				CEE_handle_def *thandle, short t_tag, void* pObject, CTimer* cnext)
{
	SRVRTRACE_ENTER(FILE_LSN+1);
	m_seconds = seconds;
	m_microseconds = microseconds;
	m_expiration_routine = e_routine;
	m_user_tag = u_tag;
	memcpy(&m_timer_handle, thandle, sizeof(CEE_handle_def));
	m_timer_tag = t_tag;
	m_pObject = pObject;
	next = cnext;
	SRVRTRACE_EXIT(FILE_LSN+1);
}
CTCPIPSystemSrvr* CTCPIPSystemSrvr_list::find_node(short nSocketFnum)
{
	SRVRTRACE_ENTER(FILE_TSS+7);
	CTCPIPSystemSrvr* cnode = list;

	while( cnode != NULL )
	{
		if ( cnode->m_nSocketFnum == nSocketFnum )
			break;
		cnode = cnode->next;
	}
	SRVRTRACE_EXIT(FILE_TSS+7);
	return cnode;
}