The non-java project is being replaced by a client and a server project
in order to allow for the client component to be consumed by distributions targeting the desktop. This check-in is for the server project.
This commit is contained in:
628
CASA-auth-token/server/utilities/IpcLibs/linux/client/client.cpp
Normal file
628
CASA-auth-token/server/utilities/IpcLibs/linux/client/client.cpp
Normal file
@@ -0,0 +1,628 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* 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
|
||||
* Library 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, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
//===[ Include files ]=====================================================
|
||||
|
||||
#include "ipcint.h"
|
||||
|
||||
extern "C" {
|
||||
#include "casa_c_ipc.h"
|
||||
}
|
||||
|
||||
#include "cchannel.h"
|
||||
#include "clientreq.h"
|
||||
#include "remoteendpoint.h"
|
||||
|
||||
|
||||
//===[ External data ]=====================================================
|
||||
|
||||
extern
|
||||
unsigned long numCChannelObjects;
|
||||
|
||||
//===[ External prototypes ]===============================================
|
||||
|
||||
//===[ Manifest constants ]================================================
|
||||
|
||||
#define DEFAULT_MAX_RPC_RETRIES 3
|
||||
|
||||
//===[ Type definitions ]==================================================
|
||||
|
||||
//===[ Function prototypes ]===============================================
|
||||
|
||||
//===[ Global variables ]==================================================
|
||||
|
||||
// Debug Level
|
||||
int DebugLevel = 0;
|
||||
bool UseSyslog = false;
|
||||
|
||||
// Application Name for logging purposes
|
||||
char unInitialized[] = "Uninitialized";
|
||||
char *pAppName = unInitialized;
|
||||
|
||||
// Application threaded information
|
||||
bool appMultithreaded;
|
||||
|
||||
// Client mutex
|
||||
pthread_mutex_t clientMutex;
|
||||
|
||||
// Mutex for interlocked operations
|
||||
pthread_mutex_t interlockedMutex;
|
||||
|
||||
// Indicators
|
||||
bool svcInitialized = false;
|
||||
|
||||
// Map of open remote endpoints.
|
||||
//
|
||||
// This map contains all of the open remote
|
||||
// endpoint objects. The key used to obtain
|
||||
// RemoteEndPoint objects from the map is an
|
||||
// object handle.
|
||||
//
|
||||
typedef map<uint32_t, SmartPtr<RemoteEndPoint>*> REPMap;
|
||||
typedef REPMap::iterator REPMapIter;
|
||||
typedef pair<REPMapIter, bool> REPIterBoolPair;
|
||||
REPMap repMap;
|
||||
|
||||
// RemoteEndPoint handle allocator
|
||||
uint32_t remoteEndPointHandleAllocator = 1;
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
int
|
||||
IpcClientOpenUnixRemoteEndPoint(
|
||||
IN char *pSocketFileName,
|
||||
IN int maxRpcRetries,
|
||||
INOUT uint32_t *pEndPointHandle)
|
||||
//
|
||||
// Arguments In: port - Server's listening port number.
|
||||
//
|
||||
// address - The server's IP Address. Use
|
||||
// 0x7F000001 if the server is local.
|
||||
//
|
||||
// maxRpcRetries - Maximum number of Rpc retries that
|
||||
// should be utilized when submitting
|
||||
// a request to the endpoint. A value
|
||||
// of zero requests that the default
|
||||
// setting be utilized.
|
||||
//
|
||||
// Arguments Out: pEndPointHandle - Pointer to variable that will receive
|
||||
// the endpoint handle.
|
||||
//
|
||||
// Returns: 0 == Success
|
||||
// -1 == Failure
|
||||
//
|
||||
// Abstract: Method to open a UNIX (PF_UNIX) remote endpoint.
|
||||
//
|
||||
// Note: The service should have been initialized before calling
|
||||
// this procedure.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus = -1;
|
||||
|
||||
DbgTrace(1, "IpcClientOpenUnixRemoteEndPoint- Start\n", 0);
|
||||
|
||||
// Verify the input parameters
|
||||
if (pSocketFileName == NULL
|
||||
|| pEndPointHandle == NULL)
|
||||
{
|
||||
DbgTrace(0, "IpcClientOpenUnixRemoteEndPoint- Invalid parameter\n", 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Verify that we have been initialized
|
||||
if (svcInitialized)
|
||||
{
|
||||
// Set the default max rpc retry value if necessary
|
||||
if (maxRpcRetries == 0)
|
||||
maxRpcRetries = DEFAULT_MAX_RPC_RETRIES;
|
||||
|
||||
// Acquire our mutex
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
|
||||
try {
|
||||
// Instantiate a RemoteEndPoint object and keep track of it
|
||||
// with a smart pointer.
|
||||
SmartRemoteEndPoint *pSmartRemoteEndPoint = new SmartRemoteEndPoint(new RemoteEndPoint(appMultithreaded,
|
||||
maxRpcRetries,
|
||||
pSocketFileName));
|
||||
|
||||
// Allocate a handle for the endpoint
|
||||
uint32_t handle = remoteEndPointHandleAllocator ++;
|
||||
|
||||
// Insert the new RemoteEndPoint into the REP map
|
||||
REPIterBoolPair insertResult;
|
||||
insertResult = repMap.insert(make_pair(handle, pSmartRemoteEndPoint));
|
||||
if (!insertResult.second)
|
||||
{
|
||||
// Insertion failed
|
||||
DbgTrace(0, "IpcClientOpenUnixRemoteEndPoint- Unable to insert RemoteEndPoint into REP\n", 0);
|
||||
delete pSmartRemoteEndPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RemoteEndPoint inserted in the REP map, success.
|
||||
*pEndPointHandle = handle;
|
||||
retStatus = 0;
|
||||
}
|
||||
} catch (...) {
|
||||
DbgTrace(0, "IpcClientOpenUnixRemoteEndPoint- Exception caught\n", 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientOpenUnixRemoteEndPoint- Not initialized\n", 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
DbgTrace(1, "IpcClientOpenUnixRemoteEndPoint- End, status = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
int
|
||||
IpcClientOpenInetRemoteEndPoint(
|
||||
IN unsigned short int port,
|
||||
IN uint32_t address,
|
||||
IN int maxRpcRetries,
|
||||
INOUT uint32_t *pEndPointHandle)
|
||||
//
|
||||
// Arguments In: port - Server's listening port number.
|
||||
//
|
||||
// address - The server's IP Address. Use
|
||||
// 0x7F000001 if the server is local.
|
||||
//
|
||||
// maxRpcRetries - Maximum number of Rpc retries that
|
||||
// should be utilized when submitting
|
||||
// a request to the endpoint. A value
|
||||
// of zero requests that the default
|
||||
// setting be utilized.
|
||||
//
|
||||
// Arguments Out: pEndPointHandle - Pointer to variable that will receive
|
||||
// the endpoint handle.
|
||||
//
|
||||
// Returns: 0 == Success
|
||||
// -1 == Failure
|
||||
//
|
||||
// Abstract: Method to open a TCP (AF_INET) remote endpoint.
|
||||
//
|
||||
// Note: The service should have been initialized before calling
|
||||
// this procedure.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus = -1;
|
||||
|
||||
DbgTrace(1, "IpcClientOpenInetRemoteEndPoint- Start\n", 0);
|
||||
|
||||
// Verify the input parameters
|
||||
if (pEndPointHandle == NULL)
|
||||
{
|
||||
DbgTrace(0, "IpcClientOpenInetRemoteEndPoint- Invalid parameter\n", 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Verify that we have been initialized
|
||||
if (svcInitialized)
|
||||
{
|
||||
// Set the default max rpc retry value if necessary
|
||||
if (maxRpcRetries == 0)
|
||||
maxRpcRetries = DEFAULT_MAX_RPC_RETRIES;
|
||||
|
||||
// Acquire our mutex
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
|
||||
try {
|
||||
// tbd - add code to allow us to share endpoints to the same destination that are already opened
|
||||
//
|
||||
// Instantiate a RemoteEndPoint object and keep track of it
|
||||
// with a smart pointer.
|
||||
SmartRemoteEndPoint *pSmartRemoteEndPoint = new SmartRemoteEndPoint(new RemoteEndPoint(appMultithreaded,
|
||||
maxRpcRetries,
|
||||
port,
|
||||
address));
|
||||
|
||||
// Allocate a handle for the endpoint
|
||||
uint32_t handle = remoteEndPointHandleAllocator ++;
|
||||
|
||||
// Insert the new RemoteEndPoint into the REP map
|
||||
REPIterBoolPair insertResult;
|
||||
insertResult = repMap.insert(make_pair(handle, pSmartRemoteEndPoint));
|
||||
if (!insertResult.second)
|
||||
{
|
||||
// Insertion failed
|
||||
DbgTrace(0, "IpcClientOpenInetRemoteEndPoint- Unable to insert RemoteEndPoint into REP\n", 0);
|
||||
delete pSmartRemoteEndPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RemoteEndPoint inserted in the REP map, success.
|
||||
*pEndPointHandle = handle;
|
||||
retStatus = 0;
|
||||
}
|
||||
} catch (...) {
|
||||
DbgTrace(0, "IpcClientOpenInetRemoteEndPoint- Exception caught\n", 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientOpenInetRemoteEndPoint- Not initialized\n", 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
DbgTrace(1, "IpcClientOpenInetRemoteEndPoint- End, status = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
int
|
||||
IpcClientCloseRemoteEndPoint(
|
||||
IN uint32_t endPointHandle)
|
||||
//
|
||||
// Arguments In: endpointHandle - Handle of the endpoint being closed.
|
||||
//
|
||||
//
|
||||
// Arguments Out: None.
|
||||
// the endpoint handle.
|
||||
//
|
||||
// Returns: 0 == Success
|
||||
// -1 == Failure
|
||||
//
|
||||
// Abstract: Method to close a remote endpoint.
|
||||
//
|
||||
// Note: The service should have been initialized before calling
|
||||
// this procedure.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus = -1;
|
||||
|
||||
DbgTrace(1, "IpcClientCloseRemoteEndPoint- Start\n", 0);
|
||||
|
||||
// Verify that we have been initialized
|
||||
if (svcInitialized)
|
||||
{
|
||||
// Acquire our mutex
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
|
||||
// Find the appropriate RemoteEndPoint object in the REP Map using
|
||||
// the handle provided by the caller.
|
||||
REPMapIter iter = repMap.find(endPointHandle);
|
||||
if (iter != repMap.end())
|
||||
{
|
||||
// Object was found in the map, remove it.
|
||||
SmartRemoteEndPoint *pSmartRemoteEndPoint = iter->second;
|
||||
repMap.erase(iter);
|
||||
|
||||
// Release our mutex before deleting the endpoint
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
|
||||
// Close the endpoint
|
||||
delete pSmartRemoteEndPoint;
|
||||
|
||||
// Success
|
||||
retStatus = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientCloseRemoteEndPoint- Invalid handle\n", 0);
|
||||
|
||||
// Release our mutex
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientCloseRemoteEndPoint- Not initialized\n", 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
DbgTrace(1, "IpcClientCloseRemoteEndPoint- End, status = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
int
|
||||
IpcClientSubmitReq(
|
||||
IN uint32_t endPointHandle,
|
||||
IN char *pClientData,
|
||||
IN int clientDataLen,
|
||||
INOUT char **ppServerData,
|
||||
INOUT int *pServerDataLen)
|
||||
//
|
||||
// Arguments In: endPointHandle - Handle of the remote endpoint that will
|
||||
// be the target of the request.
|
||||
//
|
||||
// pClientData - Pointer to client data that must be sent to
|
||||
// the server. Buffer is NEVER released by the
|
||||
// procedure.
|
||||
//
|
||||
// clientDataLen - Length of the client data.
|
||||
//
|
||||
// Arguments Out: ppServerData - Pointer to variable that will receive a
|
||||
// pointer to the buffer containing the data
|
||||
// received from the server.
|
||||
//
|
||||
// The returned buffer always contains a NULL after the
|
||||
// data indicated. You may be able to leverage this to
|
||||
// treat the data as a NULL terminated string in cases
|
||||
// where the request consists of ASCII characters.
|
||||
//
|
||||
// pServerDataLen - Pointer to variable that will receive the
|
||||
// length of the data received from the server.
|
||||
//
|
||||
// Returns: 0 == Request completed gracefully
|
||||
// -1 == Request did not complete gracefully
|
||||
//
|
||||
// Abstract: Method to submit a request.
|
||||
//
|
||||
// Notes: The routine blocks until the request completes.
|
||||
//
|
||||
// The buffer returned with the server data must be released
|
||||
// by the calling application by calling free().
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus = -1;
|
||||
|
||||
DbgTrace(1, "IpcClientSubmitReq- Start\n", 0);
|
||||
|
||||
// Verify that we have been initialized
|
||||
if (svcInitialized)
|
||||
{
|
||||
// Acquire our mutex
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
|
||||
// Find the appropriate RemoteEndPoint object in the REP Map using
|
||||
// the handle provided by the caller.
|
||||
REPMapIter iter = repMap.find(endPointHandle);
|
||||
if (iter != repMap.end())
|
||||
{
|
||||
// Object was found in the map, use it to submit
|
||||
// the request.
|
||||
SmartRemoteEndPoint *pSmartRemoteEndPoint = new SmartRemoteEndPoint(*(iter->second));
|
||||
|
||||
// Release our mutex before deleting the endpoint
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
|
||||
// Submit the request
|
||||
retStatus = (*pSmartRemoteEndPoint)->submitReq(pClientData,
|
||||
clientDataLen,
|
||||
ppServerData,
|
||||
pServerDataLen);
|
||||
|
||||
// Get rid of the reference to the remote endpoint
|
||||
delete pSmartRemoteEndPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientSubmitReq- Invalid handle\n", 0);
|
||||
|
||||
// Release our mutex
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientSubmitReq- Not initialized\n", 0);
|
||||
}
|
||||
|
||||
DbgTrace(1, "IpcClientSubmitReq- End, retStatus = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
int
|
||||
IpcClientInit(
|
||||
IN char *pName,
|
||||
IN bool multithreaded,
|
||||
IN int debugLevel,
|
||||
IN bool useSyslog)
|
||||
//
|
||||
// Arguments In: pName - Pointer to string containing the name that the
|
||||
// calling application wants associated with the
|
||||
// debug logs emitted by the library.
|
||||
//
|
||||
// multithreaded - Set to TRUE if the process is
|
||||
// multithreaded.
|
||||
//
|
||||
// debugLevel - The level that the library should use for
|
||||
// determining what information should be logged
|
||||
// for debugging purposes. 0 being the lowest
|
||||
// level.
|
||||
//
|
||||
// useSyslog - Set to TRUE to log debug statements using Syslog,
|
||||
// else debugs are log to stderr.
|
||||
//
|
||||
// Arguments Out: None.
|
||||
//
|
||||
// Returns: 0 == Success
|
||||
// -1 == Failure
|
||||
//
|
||||
// Abstract: Method to initialize the IPC infrastructure for process.
|
||||
//
|
||||
// Note: It is necessary to call the appropriate function to
|
||||
// set the server address before a request can be submitted.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
int retStatus = -1;
|
||||
|
||||
DbgTrace(1, "IpcClientInit- Start\n", 0);
|
||||
|
||||
// Check input parameters
|
||||
if (pAppName == NULL)
|
||||
{
|
||||
DbgTrace(0, "IpcClientInit- Invalid parameter\n", 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Verify that we have not been initialized already
|
||||
if (!svcInitialized)
|
||||
{
|
||||
// Save a copy of the application name
|
||||
pAppName = new char[strlen(pName) + 1];
|
||||
if (pAppName == NULL)
|
||||
{
|
||||
DbgTrace(0, "IpcClientInit- Memory allocation failure\n", 0);
|
||||
goto exit;
|
||||
}
|
||||
strcpy(pAppName, pName);
|
||||
|
||||
// Save the app multithreaded information
|
||||
appMultithreaded = multithreaded;
|
||||
|
||||
// Save the rest of the debug settings
|
||||
DebugLevel = debugLevel;
|
||||
UseSyslog = useSyslog;
|
||||
|
||||
// Initialize our mutexes
|
||||
pthread_mutex_init(&clientMutex, NULL);
|
||||
pthread_mutex_init(&interlockedMutex, NULL);
|
||||
|
||||
// Success
|
||||
svcInitialized = true;
|
||||
retStatus = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientInit- Initialized already\n", 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
DbgTrace(1, "IpcClientInit- End, status = %08X\n", retStatus);
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
extern "C"
|
||||
void
|
||||
IpcClientShutdown(void)
|
||||
//
|
||||
// Arguments In: None.
|
||||
//
|
||||
// Arguments Out: None.
|
||||
//
|
||||
// Returns: Nothing.
|
||||
//
|
||||
// Abstract: Method to shutdown the IPC infrastructure for process.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
DbgTrace(1, "IpcClientShutdown- Start\n", 0);
|
||||
|
||||
// Verify that we have been initialized
|
||||
if (svcInitialized)
|
||||
{
|
||||
// Forget about having been initialized
|
||||
svcInitialized = false;
|
||||
|
||||
// Clean up the REP map
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
while (!repMap.empty())
|
||||
{
|
||||
REPMapIter iter = repMap.begin();
|
||||
SmartRemoteEndPoint *pSmartRemoteEndPoint = iter->second;
|
||||
repMap.erase(iter);
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
|
||||
delete pSmartRemoteEndPoint;
|
||||
pthread_mutex_lock(&clientMutex);
|
||||
}
|
||||
pthread_mutex_unlock(&clientMutex);
|
||||
|
||||
// Free the AppName string if necessary
|
||||
if (pAppName != unInitialized)
|
||||
{
|
||||
delete[] pAppName;
|
||||
pAppName = unInitialized;
|
||||
}
|
||||
|
||||
// Wait until all of the channels are gone
|
||||
while (numCChannelObjects)
|
||||
sleep(0); // Only suffer a time-slice
|
||||
sleep(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgTrace(0, "IpcClientShutdown- Not initialized\n", 0);
|
||||
}
|
||||
|
||||
DbgTrace(1, "IpcClientShutdown- End\n", 0);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
static void __attribute__((destructor))
|
||||
so_fini()
|
||||
//
|
||||
// Arguments In: None.
|
||||
//
|
||||
// Arguments Out: None.
|
||||
//
|
||||
// Returns: Nothing.
|
||||
//
|
||||
// Abstract: Library un-initialization routine.
|
||||
//
|
||||
// L2
|
||||
//=======================================================================--
|
||||
{
|
||||
DbgTrace(0, "so_fini- Start\n", 0);
|
||||
IpcClientShutdown();
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
//=========================================================================
|
||||
|
||||
Reference in New Issue
Block a user