CClientEndPoint.cpp [plain text]
#include <stdio.h>
#include <stdlib.h> // for malloc()
#include <string.h>
#include <unistd.h> // for getpid()
#include <time.h> // for time()
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <servers/bootstrap.h>
#include <syslog.h>
#include "CClientEndPoint.h"
#include "DirServicesTypes.h"
#include "DirServicesConst.h"
#include "DirServicesPriv.h"
#include "PrivateTypes.h"
#include "DSCThread.h"
#include "DirectoryServiceMIG.h"
#define kMsgSize sizeof( sComData )
#define kIPCMsgSize sizeof( sIPCMsg )
UInt32 CClientEndPoint::fMessageID = 0;
CClientEndPoint::CClientEndPoint ( const char *inSrvrName )
{
fSrvrName = nil;
if ( inSrvrName != nil )
{
fSrvrName = strdup(inSrvrName);
}
fReplyMsg = NULL;
fServerPort = MACH_PORT_NULL;
fSessionPort = MACH_PORT_NULL;
}
CClientEndPoint::~CClientEndPoint ( void )
{
if ( fSrvrName != nil )
{
free( fSrvrName );
fSrvrName = nil;
}
if ( fReplyMsg != NULL )
{
free( fReplyMsg );
fReplyMsg = NULL;
}
if ( fServerPort != MACH_PORT_NULL )
{
mach_port_mod_refs( mach_task_self(), fServerPort, MACH_PORT_RIGHT_SEND, -1 );
fServerPort = MACH_PORT_NULL;
}
if ( fSessionPort != MACH_PORT_NULL )
{
mach_port_mod_refs( mach_task_self(), fSessionPort, MACH_PORT_RIGHT_SEND, -1 );
fSessionPort = MACH_PORT_NULL;
}
}
inline UInt32 CClientEndPoint::GetMessageID ( void )
{
return( ++fMessageID );
}
SInt32 CClientEndPoint::Initialize ( void )
{
kern_return_t kr = KERN_FAILURE;
if( fServerPort != MACH_PORT_NULL )
{
mach_port_mod_refs( mach_task_self(), fServerPort, MACH_PORT_RIGHT_SEND, -1 );
fServerPort = MACH_PORT_NULL;
}
if( fSessionPort != MACH_PORT_NULL )
{
mach_port_mod_refs( mach_task_self(), fSessionPort, MACH_PORT_RIGHT_SEND, -1 );
fSessionPort = MACH_PORT_NULL;
}
if (fSrvrName != nil) {
kr = bootstrap_look_up( bootstrap_port, fSrvrName, &fServerPort );
}
if (kr != KERN_SUCCESS && (fSrvrName == nil || strcmp(fSrvrName, kDSStdMachPortName) != 0) )
{
kr = bootstrap_look_up( bootstrap_port, kDSStdMachPortName, &fServerPort );
if (kr != KERN_SUCCESS)
{
LOG3( kStdErr, "*** failed bootstrap_look_up: %s at: %d: Msg = %s\n", __FILE__, __LINE__, mach_error_string( kr ) );
}
}
return ( (kr == KERN_SUCCESS && dsmig_create_api_session(fServerPort, &fSessionPort) == KERN_SUCCESS) ? eDSNoErr : eServerSendError );
}
SInt32 CClientEndPoint::SendServerMessage ( sComData *inMsg )
{
SInt32 result = eServerSendError;
bool bTryAgain = false;
do
{
kern_return_t kr = MACH_SEND_INVALID_DEST;
mach_msg_type_name_t serverPoly = MACH_MSG_TYPE_COPY_SEND;
if( fSessionPort != MACH_PORT_NULL )
{
char replyFixedBuffer[ kMaxFixedMsg ];
sComDataPtr replyFixedData = (sComDataPtr) replyFixedBuffer;
mach_msg_type_number_t replyFixedLen = 0;
vm_address_t sendData = 0;
mach_msg_type_number_t sendLen = sizeof(sComData) + inMsg->fDataLength - 1;
vm_address_t replyData = 0;
mach_msg_type_number_t replyLen = 0;
if( inMsg->fDataLength <= kMaxFixedMsgData )
{
kr = dsmig_api_call( fSessionPort, serverPoly, inMsg, sendLen, 0, 0, replyFixedData, &replyFixedLen, &replyData, &replyLen );
}
else
{
vm_read( mach_task_self(), (vm_address_t)inMsg, sendLen, &sendData, &sendLen );
kr = dsmig_api_call( fSessionPort, serverPoly, NULL, 0, sendData, sendLen, replyFixedData, &replyFixedLen, &replyData, &replyLen );
if( kr == MACH_SEND_INVALID_DEST )
{
vm_deallocate( mach_task_self(), sendData, sendLen );
}
}
if( kr == KERN_SUCCESS )
{
sComDataPtr pComData = NULL;
UInt32 uiLength = 0;
if( replyFixedLen )
{
pComData = (sComDataPtr) replyFixedData;
uiLength = replyFixedLen;
}
else if( replyLen )
{
pComData = (sComDataPtr) replyData;
uiLength = replyLen;
}
if( pComData != NULL && pComData->fDataLength == (uiLength - (sizeof(sComData) - 1)) )
{
fReplyMsg = (sComData *) calloc( sizeof(char), sizeof(sComData) + pComData->fDataSize );
bcopy( pComData, fReplyMsg, uiLength );
result = eDSNoErr;
}
if( replyLen )
{
vm_deallocate( mach_task_self(), replyData, replyLen );
}
}
}
if( bTryAgain == false && kr == MACH_SEND_INVALID_DEST )
{
mach_port_mod_refs( mach_task_self(), fSessionPort, MACH_PORT_RIGHT_SEND, -1 );
fSessionPort = MACH_PORT_NULL;
if( dsmig_create_api_session( fServerPort, &fSessionPort ) == KERN_SUCCESS )
{
bTryAgain = true;
}
else
{
bTryAgain = (Initialize() == 0);
}
}
else
{
bTryAgain = false;
}
} while( bTryAgain );
return result;
}
SInt32 CClientEndPoint::GetServerReply ( sComData **outMsg )
{
SInt32 siResult = eServerReplyError;
if( fReplyMsg != NULL )
{
if( *outMsg )
free( *outMsg );
*outMsg = fReplyMsg;
fReplyMsg = NULL;
siResult = eDSNoErr;
}
return( siResult );
}