initial version of CLIENT_INFO support

This commit is contained in:
darin%netscape.com 2002-11-11 06:32:27 +00:00
Родитель 913dcd68e8
Коммит 01c4e12a0a
7 изменённых файлов: 401 добавлений и 219 удалений

Просмотреть файл

@ -47,27 +47,6 @@ const nsID IPCM_TARGET =
{0xb1, 0x15, 0x8c, 0x29, 0x44, 0xda, 0x11, 0x50}
};
//
// +--------------------+
// | DWORD : MSG_TYPE |
// +--------------------+
// | (variable) |
// +--------------------+
//
int
IPCM_GetMsgType(const ipcMessage *msg)
{
// make sure message topic matches
if (msg->Target().Equals(IPCM_TARGET)) {
// the type is encoded as the first byte
PRUint32 type = * (PRUint32 *) msg->Data();
if (type < IPCM_MSG_TYPE_UNKNOWN)
return type;
}
return IPCM_MSG_TYPE_UNKNOWN;
}
//
// MSG_TYPE values
//
@ -75,80 +54,169 @@ const PRUint32 ipcmMessagePing::MSG_TYPE = IPCM_MSG_TYPE_PING;
const PRUint32 ipcmMessageError::MSG_TYPE = IPCM_MSG_TYPE_ERROR;
const PRUint32 ipcmMessageClientHello::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_HELLO;
const PRUint32 ipcmMessageClientID::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ID;
//const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
const PRUint32 ipcmMessageClientAddName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_NAME;
const PRUint32 ipcmMessageClientDelName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_NAME;
const PRUint32 ipcmMessageClientAddTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_TARGET;
const PRUint32 ipcmMessageClientDelTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_TARGET;
const PRUint32 ipcmMessageQueryClientByName::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME;
const PRUint32 ipcmMessageQueryClientInfo::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_INFO;
const PRUint32 ipcmMessageForward::MSG_TYPE = IPCM_MSG_TYPE_FORWARD;
#if 0
//
// CLIST message
// CLIENT_INFO message
//
// +-----------------------+
// | BYTE - IPCM_MSG_CLIST |
// +-----------------------+
// | cname[0] |
// +-----------------------+
// | null |
// +-----------------------+
// . .
// . .
// +-----------------------+
// | cname[num - 1] |
// +-----------------------+
// | null |
// +-----------------------+
// +-----------------------------------------+
// | DWORD : MSG_TYPE |
// +--------------------+--------------------+
// | DWORD : clientID |
// +--------------------+--------------------+
// | WORD : nameStart | WORD : nameCount |
// +--------------------+--------------------+
// | WORD : targetStart | WORD : targetCount |
// +--------------------+--------------------+
// | name[0] | (null byte) |
// +--------------------+--------------------+
// . . .
// . . .
// +--------------------+--------------------+
// | name[count - 1] | (null byte) |
// +--------------------+--------------------+
// | target[0] |
// +-----------------------------------------+
// . . .
// . . .
// +-----------------------------------------+
// | target[count - 1] |
// +-----------------------------------------+
//
const char ipcmMessageCLIST::MSG_TYPE = (char) IPCM_MSG_CLIST;
ipcmMessageCLIST::ipcmMessageCLIST(const char *cNames[], PRUint32 num)
struct ipcmClientInfoHeader
{
PRUint32 i, dataLen = 1;
PRUint32 mType;
PRUint32 mID;
PRUint16 mNameStart;
PRUint16 mNameCount;
PRUint16 mTargetStart;
PRUint16 mTargetCount;
};
for (i = 0; i < num; ++i) {
dataLen += strlen(cNames[i]);
dataLen ++;
ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, const char *names[], const nsID *targets[])
{
ipcmClientInfoHeader hdr = {0};
hdr.mType = MSG_TYPE;
hdr.mID = cID;
hdr.mNameStart = sizeof(hdr);
PRUint32 i, namesLen = 0;
i = 0;
while (names[i]) {
namesLen += (strlen(names[i]) + 1);
++hdr.mNameCount;
++i;
}
i = 0;
while (targets[i]) {
++hdr.mTargetCount;
++i;
}
//
// compute target array starting offset
//
hdr.mTargetStart = hdr.mNameStart + namesLen;
//
// compute message length
//
PRUint32 dataLen = sizeof(hdr) + namesLen + hdr.mTargetCount * sizeof(nsID);
Init(IPCM_TARGET, NULL, dataLen);
PRUint32 offset = 1;
for (i = 0; i < num; ++i) {
PRUint32 len = strlen(cNames[i]);
SetData(offset, cNames[i], len + 1);
offset += len + 1;
//
// write message data
//
SetData(0, (const char *) &hdr, sizeof(hdr));
PRUint32 offset = sizeof(hdr);
for (i = 0; names[i]; ++i) {
PRUint32 len = strlen(names[i]) + 1;
SetData(offset, names[i], len);
offset += len;
}
for (i = 0; targets[i]; ++i) {
PRUint32 len = sizeof(nsID);
SetData(offset, (const char *) targets[i], len);
offset += len;
}
}
const char *
ipcmMessageCLIST::NextClientName(const char *cName) const
PRUint32
ipcmMessageClientInfo::ClientID() const
{
if (!cName)
return Data() + 1;
cName += strlen(cName) + 1;
if (cName == MsgBuf() + MsgLen())
cName = NULL;
return cName;
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
return hdr->mID;
}
PRUint32
ipcmMessageClientInfo::NameCount() const
{
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
return hdr->mNameCount;
}
PRUint32
ipcmMessageClientInfo::TargetCount() const
{
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
return hdr->mTargetCount;
}
const char *
ipcmMessageClientInfo::NextName(const char *name) const
{
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
if (!name)
return (const char *) hdr + hdr->mNameStart;
name += strlen(name) + 1;
if (name == (const char *) hdr + hdr->mTargetStart)
name = NULL;
return name;
}
const nsID *
ipcmMessageClientInfo::NextTarget(const nsID *target) const
{
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
if (!target)
return (const nsID *) hdr + hdr->mTargetStart;
target += sizeof(nsID);
if (target == (const nsID *) MsgBuf() + MsgLen())
target = NULL;
return target;
}
#endif
//
// FWD message
// FORWARD message
//
// +-------------------------------+
// | DWORD : IPCM_MSG_TYPE_FORWARD |
// +-------------------------------+
// | clientID |
// +-------------------------------+
// | innerMsgHeader |
// +-------------------------------+
// | innerMsgData |
// +-------------------------------+
// +-------------------------+
// | DWORD : MSG_TYPE |
// +-------------------------+
// | clientID |
// +-------------------------+
// | innerMsgHeader |
// +-------------------------+
// | innerMsgData |
// +-------------------------+
//
ipcmMessageForward::ipcmMessageForward(PRUint32 cID,

Просмотреть файл

@ -67,7 +67,11 @@ enum {
//
// returns IPCM message type.
//
int IPCM_GetMsgType(const ipcMessage *msg);
static inline int
IPCM_GetMsgType(const ipcMessage *msg)
{
return ((const ipcMessage_DWORD *) msg)->First();
}
//
// NOTE: this file declares some helper classes that simplify construction
@ -170,6 +174,23 @@ public:
//
// IPCM_MSG_TYPE_CLIENT_INFO
//
// this message is sent from the daemon to provide the list of names
// and targets for a particular client.
//
class ipcmMessageClientInfo : public ipcMessage
{
public:
static const PRUint32 MSG_TYPE;
ipcmMessageClientInfo(PRUint32 clientID, const char **names, const nsID **targets);
PRUint32 ClientID() const;
PRUint32 NameCount() const;
PRUint32 TargetCount() const;
const char *NextName(const char *name) const;
const nsID *NextTarget(const nsID *target) const;
};
//
// IPCM_MSG_TYPE_CLIENT_ADD_NAME
@ -231,8 +252,8 @@ public:
// IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME
//
// this message is sent from a client to the daemon to request the ID of the
// client corresponding to the given name or alias. in response the daemon
// will either send a CLIENT_ID or ERROR message.
// client corresponding to the given name. in response the daemon will either
// send a CLIENT_ID or ERROR message.
//
class ipcmMessageQueryClientByName : public ipcMessage_DWORD_STR
{
@ -245,6 +266,24 @@ public:
const char *Name() const { return Second(); }
};
//
// IPCM_MSG_TYPE_QUERY_CLIENT_INFO
//
// thie message is sent from a client to the daemon to request complete
// information about the client corresponding to the given client ID. in
// response the daemon will either send a CLIENT_INFO or ERROR message.
//
class ipcmMessageQueryClientInfo : public ipcMessage_DWORD_DWORD
{
public:
static const PRUint32 MSG_TYPE;
ipcmMessageQueryClientInfo(PRUint32 clientID)
: ipcMessage_DWORD_DWORD(IPCM_TARGET, MSG_TYPE, clientID) {}
PRUint32 ClientID() const { return Second(); }
};
//
// IPCM_MSG_TYPE_FORWARD
//

Просмотреть файл

@ -35,6 +35,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include <string.h>
#include "ipcLog.h"
#include "ipcCommandModule.h"
@ -47,6 +48,52 @@
typedef void (* ipcmMsgHandler)(ipcClient *, const ipcMessage *);
//
// helpers
//
static char **
ipcm_BuildStringArray(const ipcStringNode *nodes)
{
size_t count = 0;
const ipcStringNode *node;
for (node = nodes; node; node = node->mNext)
count++;
char **strs = (char **) calloc(count + 1, sizeof(char *));
if (!strs)
return NULL;
count = 0;
for (node = nodes; node; node = node->mNext, ++count)
strs[count] = (char *) node->Value();
return strs;
}
static nsID **
ipcm_BuildIDArray(const ipcIDNode *nodes)
{
size_t count = 0;
const ipcIDNode *node;
for (node = nodes; node; node = node->mNext)
count++;
nsID **ids = (nsID **) calloc(count + 1, sizeof(nsID *));
if (!ids)
return NULL;
count = 0;
for (node = nodes; node; node = node->mNext, ++count)
ids[count] = (nsID *) &node->Value();
return ids;
}
//
// message handlers
//
@ -129,6 +176,28 @@ ipcm_OnQueryClientByName(ipcClient *client, const ipcMessage *rawMsg)
}
}
static void
ipcm_OnQueryClientInfo(ipcClient *client, const ipcMessage *rawMsg)
{
LOG(("got QUERY_CLIENT_INFO\n"));
ipcMessageCast<ipcmMessageQueryClientInfo> msg(rawMsg);
ipcClient *result = IPC_GetClientByID(msg->ClientID());
if (result) {
char **names = ipcm_BuildStringArray(result->Names());
nsID **targets = ipcm_BuildIDArray(result->Targets());
IPC_SendMsg(client, new ipcmMessageClientInfo(result->ID(),
(const char **) names,
(const nsID **)targets));
free(names);
free(targets);
}
else {
LOG((" client does not exist\n"));
IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_CLIENT_NOT_FOUND));
}
}
static void
ipcm_OnForward(ipcClient *client, const ipcMessage *rawMsg)
{
@ -162,7 +231,7 @@ IPCM_HandleMsg(ipcClient *client, const ipcMessage *rawMsg)
ipcm_OnClientAddTarget,
ipcm_OnClientDelTarget,
ipcm_OnQueryClientByName,
NULL, // QUERY_CLIENT_INFO
ipcm_OnQueryClientInfo,
ipcm_OnForward,
};

Просмотреть файл

@ -100,18 +100,24 @@ interface ipcIService : nsISupports
void removeClientName(in ACString aName);
/**
* query info about a particular client given its client name.
* query info about a particular client given its client name. the
* observer's onClientInfo method is called with the result of the lookup,
* or if there is no client matching the given name, the observer's
* onClientDown method will be called instead.
*
* @param aNameOrAlias name or alias of the client being queried.
* @param aObserver client observer to be notified.
* @param aName name or alias of the client being queried.
* @param aObserver client observer to be notified.
*
* @return integer token identifying this request.
*/
unsigned long queryClientByName(in ACString aNameOrAlias,
unsigned long queryClientByName(in ACString aName,
in ipcIClientObserver aObserver);
/**
* query info about a particular client given its client ID.
* query info about a particular client given its client ID. the observer's
* onClientInfo method is called with the result of the lookup, or if there
* is no client matching the given name, the observer's onClientDown method
* will be called instead.
*
* @return integer token identifying this request.
*/
@ -119,14 +125,13 @@ interface ipcIService : nsISupports
in ipcIClientObserver aObserver);
/**
* set client observer. observer is notified whenever the status of
* a client changes.
* set client observer. observer's onClientUp method is called whenever
* a new client comes online, and the observer's onClientDown method is
* called whenever a client goes offline.
*
* @param aClientID the ID of the client to observe.
* @param aObserver the client observer.
*/
void setClientObserver(in unsigned long aClientID,
in ipcIClientObserver aObserver);
void setClientObserver(in ipcIClientObserver aObserver);
/**
* set a message observer for a particular message target.
@ -176,38 +181,23 @@ interface ipcIMessageObserver : nsISupports
in unsigned long aDataLen);
};
[scriptable, uuid(e858d450-62b2-482d-99bb-3b5425aa28cc)]
interface ipcIClientInfo : nsISupports
{
readonly attribute unsigned long ID;
readonly attribute ACString name;
readonly attribute nsISimpleEnumerator aliases;
readonly attribute nsISimpleEnumerator targets;
};
[scriptable, uuid(42283079-030c-4b13-b069-a08b7ad5eab2)]
interface ipcIClientObserver : nsISupports
{
/**
* client status values
*/
const unsigned long CLIENT_UP = 1;
const unsigned long CLIENT_DOWN = 2;
void onClientUp (in unsigned long aReqToken,
in unsigned long aClientID);
/**
* @param aRequestToken the request token returned from the call that
* initiated this observation. 0 if initiated
* from a setClientObserver call.
* @param aClientInfo client info.
* @param aStatus client status (e.g. CLIENT_UP).
*/
void onClientStatus(in unsigned long aRequestToken,
in unsigned long aClientStatus,
in unsigned long aClientID,
in ipcIClientInfo aClientInfo);
void onClientDown (in unsigned long aReqToken,
in unsigned long aClientID);
// XXX do we care about changes to the aliases and targets supported
// by a client? if so, how should we pass this information up?
void onClientInfo (in unsigned long aReqToken,
in unsigned long aClientID,
[array, size_is(aNameCount)]
in string aClientNames,
in unsigned long aNameCount,
[array, const, size_is(aTargetCount)]
in nsIDPtr aClientTargets,
in unsigned long aTargetCount);
};
%{C++

Просмотреть файл

@ -35,6 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include "plstr.h"
#include "nsIServiceManager.h"
@ -62,38 +64,6 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
return PR_TRUE;
}
//-----------------------------------------------------------------------------
// ipcClientInfo
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS1(ipcClientInfo, ipcIClientInfo)
NS_IMETHODIMP
ipcClientInfo::GetID(PRUint32 *aID)
{
*aID = mID;
return NS_OK;
}
NS_IMETHODIMP
ipcClientInfo::GetName(nsACString &aName)
{
aName = mName;
return NS_OK;
}
NS_IMETHODIMP
ipcClientInfo::GetAliases(nsISimpleEnumerator **aliases)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ipcClientInfo::GetTargets(nsISimpleEnumerator **targets)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//-----------------------------------------------------------------------------
// ipcService
//-----------------------------------------------------------------------------
@ -153,44 +123,85 @@ ipcService::Init()
}
void
ipcService::HandleQueryResult(const ipcMessage *rawMsg, PRBool succeeded)
ipcService::OnIPCMClientID(const ipcmMessageClientID *msg)
{
LOG(("ipcService::OnIPCMClientID\n"));
ipcClientQuery *query = mQueryQ.First();
if (!query) {
NS_ERROR("no pending query; ignoring message.");
NS_WARNING("no pending query; ignoring message.");
return;
}
PRUint32 cStatus;
PRUint32 cID;
ipcClientInfo *info;
//
// (1) store client ID in query
// (2) move query to end of queue
// (3) issue CLIENT_INFO request
//
query->mID = msg->ClientID();
if (succeeded) {
cStatus = ipcIClientObserver::CLIENT_UP;
mQueryQ.RemoveFirst();
mQueryQ.Append(query);
ipcMessageCast<ipcmMessageClientID> msg(rawMsg);
info = new ipcClientInfo();
if (info) {
NS_ADDREF(info);
info->Init(msg->ClientID(), query->mName);
}
cID = msg->ClientID();
}
else {
cStatus = ipcIClientObserver::CLIENT_DOWN;
cID = 0;
info = nsnull;
}
query->mObserver->OnClientStatus(query->mReqToken,
cStatus,
cID,
info);
NS_IF_RELEASE(info);
mQueryQ.DeleteFirst();
mTransport->SendMsg(new ipcmMessageQueryClientInfo(query->mID));
}
void
ipcService::OnIPCMClientInfo(const ipcmMessageClientInfo *msg)
{
LOG(("ipcService::OnIPCMClientInfo\n"));
ipcClientQuery *query = mQueryQ.First();
if (!query) {
NS_WARNING("no pending query; ignoring message.");
return;
}
PRUint32 nameCount = msg->NameCount();
PRUint32 targetCount = msg->TargetCount();
PRUint32 i;
const char **names = (const char **) calloc(nameCount + 1, sizeof(const char *));
const char *lastName = NULL;
for (i = 0; i < nameCount; ++i) {
lastName = msg->NextName(lastName);
names[i] = lastName;
}
const nsID **targets = (const nsID **) calloc(targetCount + 1, sizeof(const nsID *));
const nsID *lastTarget = NULL;
for (i = 0; i < targetCount; ++i) {
lastTarget = msg->NextTarget(lastTarget);
targets[i] = lastTarget;
}
query->mObserver->OnClientInfo(query->mReqToken,
query->mID,
names, nameCount,
targets, targetCount);
mQueryQ.DeleteFirst();
free(names);
free(targets);
}
void
ipcService::OnIPCMError(const ipcmMessageError *msg)
{
LOG(("ipcService::OnIPCMError\n"));
ipcClientQuery *query = mQueryQ.First();
if (!query) {
NS_WARNING("no pending query; ignoring message.");
return;
}
query->mObserver->OnClientDown(query->mReqToken,
query->mID);
mQueryQ.DeleteFirst();
}
//-----------------------------------------------------------------------------
// interface impl
//-----------------------------------------------------------------------------
@ -277,8 +288,7 @@ ipcService::QueryClientByID(PRUint32 clientID,
}
NS_IMETHODIMP
ipcService::SetClientObserver(PRUint32 clientID,
ipcIClientObserver *observer)
ipcService::SetClientObserver(ipcIClientObserver *observer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -369,9 +379,7 @@ ipcService::OnConnectionLost()
//
while (mQueryQ.First()) {
ipcClientQuery *query = mQueryQ.First();
query->mObserver->OnClientStatus(query->mReqToken,
ipcIClientObserver::CLIENT_DOWN,
query->mID, nsnull);
query->mObserver->OnClientDown(query->mReqToken, query->mID);
mQueryQ.DeleteFirst();
}
@ -392,12 +400,16 @@ ipcService::OnMessageAvailable(const ipcMessage *msg)
//
// all IPCM messages stop here.
//
switch (IPCM_GetMsgType(msg)) {
PRUint32 type = IPCM_GetMsgType(msg);
switch (type) {
case IPCM_MSG_TYPE_CLIENT_ID:
HandleQueryResult(msg, PR_TRUE);
OnIPCMClientID((const ipcmMessageClientID *) msg);
break;
case IPCM_MSG_TYPE_CLIENT_INFO:
OnIPCMClientInfo((const ipcmMessageClientInfo *) msg);
break;
case IPCM_MSG_TYPE_ERROR:
HandleQueryResult(msg, PR_FALSE);
OnIPCMError((const ipcmMessageError *) msg);
break;
}
}

Просмотреть файл

@ -38,40 +38,18 @@
#ifndef ipcService_h__
#define ipcService_h__
#include "ipcIService.h"
#include "ipcTransport.h"
#include "ipcList.h"
#include "ipcMessage.h"
#include "ipcMessageQ.h"
#include "nsIRequest.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsCOMPtr.h"
#include "nsHashtable.h"
//----------------------------------------------------------------------------
// ipcClientInfo
//----------------------------------------------------------------------------
class ipcClientInfo : public ipcIClientInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IPCICLIENTINFO
ipcClientInfo() : mID(0) { NS_INIT_ISUPPORTS(); }
virtual ~ipcClientInfo() {}
void Init(PRUint32 cID, const nsACString &cName)
{
mID = cID;
mName = cName;
}
private:
PRUint32 mID;
nsCString mName;
};
#include "ipcIService.h"
#include "ipcTransport.h"
#include "ipcList.h"
#include "ipcMessage.h"
#include "ipcMessageQ.h"
#include "ipcm.h"
//----------------------------------------------------------------------------
// ipcClientQuery
@ -113,7 +91,9 @@ public:
private:
nsresult ErrorAccordingToIPCM(PRUint32 err);
void HandleQueryResult(const ipcMessage *, PRBool succeeded);
void OnIPCMClientID(const ipcmMessageClientID *);
void OnIPCMClientInfo(const ipcmMessageClientInfo *);
void OnIPCMError(const ipcmMessageError *);
// ipcTransportObserver:
void OnConnectionEstablished(PRUint32 clientID);

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsIServiceManager.h"
#include "nsIComponentRegistrar.h"
#include "nsString.h"
#include "prmem.h"
static const nsID kTestTargetID =
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
@ -112,20 +113,43 @@ public:
NS_IMPL_ISUPPORTS1(myIpcClientObserver, ipcIClientObserver)
NS_IMETHODIMP
myIpcClientObserver::OnClientStatus(PRUint32 aReqToken,
PRUint32 aStatus,
PRUint32 aClientID,
ipcIClientInfo *aClientInfo)
myIpcClientObserver::OnClientUp(PRUint32 aReqToken,
PRUint32 aClientID)
{
printf("*** got client status [token=%u status=%u info=%p]\n",
aReqToken, aStatus, (void *) aClientInfo);
printf("*** got client up [token=%u clientID=%u]\n", aReqToken, aClientID);
return NS_OK;
}
NS_IMETHODIMP
myIpcClientObserver::OnClientDown(PRUint32 aReqToken,
PRUint32 aClientID)
{
printf("*** got client down [token=%u clientID=%u]\n", aReqToken, aClientID);
return NS_OK;
}
NS_IMETHODIMP
myIpcClientObserver::OnClientInfo(PRUint32 aReqToken,
PRUint32 aClientID,
const char **aNames,
PRUint32 aNameCount,
const nsID **aTargets,
PRUint32 aTargetCount)
{
printf("*** got client info [token=%u clientID=%u]\n", aReqToken, aClientID);
PRUint32 i;
printf("*** names:\n");
for (i = 0; i < aNameCount; ++i)
printf("*** %d={%s}\n", i, aNames[i]);
printf("*** targets:\n");
for (i = 0; i < aTargetCount; ++i) {
char *str = aTargets[i]->ToString();
printf("*** %d=%s\n", i, str);
PR_Free(str);
}
if (aClientID != 0) {
if (aClientInfo) {
nsCAutoString cName;
if (NS_SUCCEEDED(aClientInfo->GetName(cName)))
printf("*** name:%s --> ID:%u\n", cName.get(), aClientID);
}
const char hello[] = "hello friend!";
SendMsg(gIpcServ, aClientID, kTestTargetID, hello, sizeof(hello));
}