diff options
Diffstat (limited to 'src/libs/xpcom18a4/ipc/ipcd/shared')
19 files changed, 2833 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/.cvsignore b/src/libs/xpcom18a4/ipc/ipcd/shared/src/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/shared/src/Makefile.in new file mode 100644 index 00000000..ffcaa10c --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/Makefile.in @@ -0,0 +1,65 @@ +# vim: noexpandtab ts=4 sw=4 +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Mozilla IPC. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2002 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Darin Fisher <darin@netscape.com> +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = ipcd +LIBRARY_NAME = ipcdshared_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = ipcd + +# required for #include "nsID.h" +REQUIRES = \ + xpcom \ + $(NULL) + +CPPSRCS = \ + ipcLog.cpp \ + ipcConfig.cpp \ + ipcMessage.cpp \ + ipcMessagePrimitives.cpp \ + ipcStringList.cpp \ + ipcIDList.cpp \ + ipcm.cpp + +include $(topsrcdir)/config/rules.mk diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.cpp new file mode 100644 index 00000000..5f829626 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.cpp @@ -0,0 +1,104 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#if defined(XP_WIN) +#elif defined(XP_OS2) && defined(XP_OS2_NATIVEIPC) +#else +#include <string.h> +#ifdef XP_UNIX +#include <unistd.h> +#include <sys/types.h> +#include <pwd.h> +#endif +#include "ipcConfig.h" +#include "ipcLog.h" +#include "prenv.h" +#include "plstr.h" + +#if defined(XP_OS2) && !defined(XP_OS2_NATIVEIPC) +#ifdef VBOX +static const char kDefaultSocketPrefix[] = "\\socket\\vbox-"; +#else +static const char kDefaultSocketPrefix[] = "\\socket\\mozilla-"; +#endif +static const char kDefaultSocketSuffix[] = "-ipc\\ipcd"; +#else +#ifdef VBOX +static const char kDefaultSocketPrefix[] = "/tmp/.vbox-"; +#else +static const char kDefaultSocketPrefix[] = "/tmp/.mozilla-"; +#endif +static const char kDefaultSocketSuffix[] = "-ipc/ipcd"; +#endif + +void IPC_GetDefaultSocketPath(char *buf, PRUint32 bufLen) +{ + const char *logName; + int len; + + PL_strncpyz(buf, kDefaultSocketPrefix, bufLen); + buf += (sizeof(kDefaultSocketPrefix) - 1); + bufLen -= (sizeof(kDefaultSocketPrefix) - 1); + + logName = PR_GetEnv("VBOX_IPC_SOCKETID"); +#if defined(VBOX) && defined(XP_UNIX) + if (!logName || !logName[0]) { + struct passwd *passStruct = getpwuid(getuid()); + if (passStruct) + logName = passStruct->pw_name; + } +#endif + if (!logName || !logName[0]) { + logName = PR_GetEnv("LOGNAME"); + if (!logName || !logName[0]) { + logName = PR_GetEnv("USER"); + if (!logName || !logName[0]) { + LOG(("could not determine username from environment\n")); + goto end; + } + } + } + PL_strncpyz(buf, logName, bufLen); + len = strlen(logName); + buf += len; + bufLen -= len; + +end: + PL_strncpyz(buf, kDefaultSocketSuffix, bufLen); +} + +#endif diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.h new file mode 100644 index 00000000..ab8b10e5 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.h @@ -0,0 +1,98 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcProto_h__ +#define ipcProto_h__ + +#if defined(XP_WIN) +// +// use WM_COPYDATA messages +// +#include "prprf.h" + +#define IPC_WINDOW_CLASS "Mozilla:IPCWindowClass" +#define IPC_WINDOW_NAME "Mozilla:IPCWindow" +#define IPC_CLIENT_WINDOW_CLASS "Mozilla:IPCAppWindowClass" +#define IPC_CLIENT_WINDOW_NAME_PREFIX "Mozilla:IPCAppWindow:" +#define IPC_SYNC_EVENT_NAME "Local\\MozillaIPCSyncEvent" +#ifndef IPC_DAEMON_APP_NAME +#define IPC_DAEMON_APP_NAME "mozilla-ipcd.exe" +#endif +#define IPC_PATH_SEP_CHAR '\\' +#define IPC_MODULES_DIR "ipc\\modules" + +#define IPC_CLIENT_WINDOW_NAME_MAXLEN (sizeof(IPC_CLIENT_WINDOW_NAME_PREFIX) + 20) + +// writes client name into buf. buf must be at least +// IPC_CLIENT_WINDOW_NAME_MAXLEN bytes in length. +inline void IPC_GetClientWindowName(PRUint32 pid, char *buf) +{ + PR_snprintf(buf, IPC_CLIENT_WINDOW_NAME_MAXLEN, "%s%u", + IPC_CLIENT_WINDOW_NAME_PREFIX, pid); +} + +#else +#include "nscore.h" +// +// use UNIX domain socket +// +#define IPC_PORT 0 +#define IPC_SOCKET_TYPE "ipc" +#if defined(XP_OS2) +#ifndef IPC_DAEMON_APP_NAME +#define IPC_DAEMON_APP_NAME "mozilla-ipcd.exe" +#endif +#define IPC_PATH_SEP_CHAR '\\' +#define IPC_MODULES_DIR "ipc\\modules" +#else +#ifndef IPC_DAEMON_APP_NAME +#define IPC_DAEMON_APP_NAME "mozilla-ipcd" +#endif +#define IPC_PATH_SEP_CHAR '/' +#define IPC_MODULES_DIR "ipc/modules" +#endif + +NS_HIDDEN_(void) IPC_GetDefaultSocketPath(char *buf, PRUint32 bufLen); + +#endif + +// common shared configuration values + +#define IPC_STARTUP_PIPE_NAME "ipc:startup-pipe" +#define IPC_STARTUP_PIPE_MAGIC 0x1C + +#endif // !ipcProto_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.cpp new file mode 100644 index 00000000..0f64a3a0 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.cpp @@ -0,0 +1,62 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ipcIDList.h" + +ipcIDNode * +ipcIDList::FindNode(ipcIDNode *node, const nsID &id) +{ + while (node) { + if (node->Equals(id)) + return node; + node = node->mNext; + } + return NULL; +} + +ipcIDNode * +ipcIDList::FindNodeBefore(ipcIDNode *node, const nsID &id) +{ + ipcIDNode *prev = NULL; + while (node) { + if (node->Equals(id)) + return prev; + prev = node; + node = node->mNext; + } + return NULL; +} diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.h new file mode 100644 index 00000000..b4fd1512 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.h @@ -0,0 +1,108 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcIDList_h__ +#define ipcIDList_h__ + +#include "nsID.h" +#include "ipcList.h" + +//----------------------------------------------------------------------------- +// nsID node +//----------------------------------------------------------------------------- + +class ipcIDNode +{ +public: + ipcIDNode(const nsID &id) + : mID(id) + { } + + const nsID &Value() const { return mID; } + + PRBool Equals(const nsID &id) const { return mID.Equals(id); } + + class ipcIDNode *mNext; +private: + nsID mID; +}; + +//----------------------------------------------------------------------------- +// singly-linked list of nsIDs +//----------------------------------------------------------------------------- + +class ipcIDList : public ipcList<ipcIDNode> +{ +public: + typedef ipcList<ipcIDNode> Super; + + void Prepend(const nsID &id) + { + Super::Prepend(new ipcIDNode(id)); + } + + void Append(const nsID &id) + { + Super::Append(new ipcIDNode(id)); + } + + const ipcIDNode *Find(const nsID &id) const + { + return FindNode(mHead, id); + } + + PRBool FindAndDelete(const nsID &id) + { + ipcIDNode *node = FindNodeBefore(mHead, id); + if (node) { + DeleteAfter(node); + return PR_TRUE; + } + else if (!IsEmpty()) { + DeleteFirst(); + return PR_TRUE; + } + + return PR_FALSE; + } + +private: + static NS_HIDDEN_(ipcIDNode *) FindNode (ipcIDNode *head, const nsID &id); + static NS_HIDDEN_(ipcIDNode *) FindNodeBefore(ipcIDNode *head, const nsID &id); +}; + +#endif // !ipcIDList_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h new file mode 100644 index 00000000..a9b9c959 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h @@ -0,0 +1,211 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcList_h__ +#define ipcList_h__ + +#include "prtypes.h" + +//----------------------------------------------------------------------------- +// simple list of singly-linked objects. class T must have the following +// structure: +// +// class T { +// ... +// public: +// T *mNext; +// }; +// +// objects added to the list must be allocated with operator new. class T may +// optionally inherit from ipcListNode<T> if it doesn't wish to define mNext +// explicitly. +//----------------------------------------------------------------------------- + +template<class T> +class ipcList +{ +public: + ipcList() + : mHead(NULL) + , mTail(NULL) + { } + ~ipcList() { DeleteAll(); } + + // + // prepends obj at the beginning of the list. + // + void Prepend(T *obj) + { + obj->mNext = mHead; + mHead = obj; + if (!mTail) + mTail = mHead; + } + + // + // appends obj to the end of the list. + // + void Append(T *obj) + { + obj->mNext = NULL; + if (mTail) { + mTail->mNext = obj; + mTail = obj; + } + else + mTail = mHead = obj; + } + + // + // inserts b into the list after a. + // + void InsertAfter(T *a, T *b) + { + b->mNext = a->mNext; + a->mNext = b; + if (mTail == a) + mTail = b; + } + + // + // removes first element w/o deleting it + // + void RemoveFirst() + { + if (mHead) + AdvanceHead(); + } + + // + // removes element after the given element w/o deleting it + // + void RemoveAfter(T *obj) + { + T *rej = obj->mNext; + if (rej) { + obj->mNext = rej->mNext; + if (rej == mTail) + mTail = obj; + } + } + + // + // deletes first element + // + void DeleteFirst() + { + T *first = mHead; + if (first) { + AdvanceHead(); + delete first; + } + } + + // + // deletes element after the given element + // + void DeleteAfter(T *obj) + { + T *rej = obj->mNext; + if (rej) { + RemoveAfter(obj); + delete rej; + } + } + + // + // deletes all elements + // + void DeleteAll() + { + while (mHead) + DeleteFirst(); + } + + const T *First() const { return mHead; } + T *First() { return mHead; } + const T *Last() const { return mTail; } + T *Last() { return mTail; } + + PRBool IsEmpty() const { return mHead == NULL; } + + // + // moves contents of list to another list + // + void MoveTo(ipcList<T> &other) + { + other.mHead = mHead; + other.mTail = mTail; + mHead = NULL; + mTail = NULL; + } + + // gets count of list elements + PRUint32 Count() + { + T *obj = mHead; + PRUint32 count = 0; + while (obj) { + count++; + obj = obj->mNext; + } + + return count; + } + +protected: + void AdvanceHead() + { + mHead = mHead->mNext; + if (!mHead) + mTail = NULL; + } + + T *mHead; + T *mTail; +}; + +template<class T> +class ipcListNode +{ +public: + ipcListNode() : mNext(nsnull) {} + + T *mNext; +}; + +#endif // !ipcList_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.cpp new file mode 100644 index 00000000..340b211c --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.cpp @@ -0,0 +1,181 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ipcLog.h" + +#ifdef IPC_LOGGING + +#include <string.h> +#include <ctype.h> + +#include "prenv.h" +#include "prprf.h" +#include "prthread.h" +#include "plstr.h" + +#ifdef VBOX +# if defined(__OS2__) && defined(PAGE_SIZE) +# undef PAGE_SIZE +# endif +# include <iprt/initterm.h> // for RTR3InitDll +#else // !VBOX +PRBool ipcLogEnabled = PR_FALSE; +#endif // !VBOX + +char ipcLogPrefix[10] = {0}; + +#ifndef VBOX + +//----------------------------------------------------------------------------- +// UNIX +//----------------------------------------------------------------------------- +#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) + +#include <sys/types.h> +#include <unistd.h> + +static inline PRUint32 +WritePrefix(char *buf, PRUint32 bufLen) +{ + return PR_snprintf(buf, bufLen, "[%u:%p] %s ", + (unsigned) getpid(), + PR_GetCurrentThread(), + ipcLogPrefix); +} +#endif + +//----------------------------------------------------------------------------- +// WIN32 +//----------------------------------------------------------------------------- +#ifdef XP_WIN +#include <windows.h> + +static inline PRUint32 +WritePrefix(char *buf, PRUint32 bufLen) +{ + return PR_snprintf(buf, bufLen, "[%u:%p] %s ", + GetCurrentProcessId(), + PR_GetCurrentThread(), + ipcLogPrefix); +} +#endif + +#endif // !VBOX + +//----------------------------------------------------------------------------- +// logging API impl +//----------------------------------------------------------------------------- + +void +IPC_InitLog(const char *prefix) +{ +#ifdef VBOX + // initialize VBox Runtime + RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); + + PL_strncpyz(ipcLogPrefix, prefix, sizeof(ipcLogPrefix)); +#else + if (PR_GetEnv("IPC_LOG_ENABLE")) { + ipcLogEnabled = PR_TRUE; + PL_strncpyz(ipcLogPrefix, prefix, sizeof(ipcLogPrefix)); + } +#endif +} + +void +IPC_Log(const char *fmt, ... ) +{ + va_list ap; + va_start(ap, fmt); + PRUint32 nb = 0; + char buf[512]; + +#ifdef VBOX + if (ipcLogPrefix[0]) { + nb = strlen(ipcLogPrefix); + if (nb > sizeof(buf) - 2) + nb = sizeof(buf) - 2; + PL_strncpy(buf, ipcLogPrefix, nb); + buf[nb++] = ' '; + } +#else + if (ipcLogPrefix[0]) + nb = WritePrefix(buf, sizeof(buf)); +#endif + + PR_vsnprintf(buf + nb, sizeof(buf) - nb, fmt, ap); + buf[sizeof(buf) - 1] = '\0'; + +#ifdef VBOX + LogFlow(("%s", buf)); +#else + fwrite(buf, strlen(buf), 1, stdout); +#endif + + va_end(ap); +} + +void +IPC_LogBinary(const PRUint8 *data, PRUint32 len) +{ + PRUint32 i, j, ln; + for (i=0; i<len; ) { + char line[100] = ""; + const PRUint8 *p; + + ln = 0; + + p = &data[i]; + for (j=0; j<PR_MIN(8, len - i); ++j, ++p) + ln += PR_snprintf(line + ln, sizeof(line) - ln, "%02x ", *p); + + for (; ln < 32; ++ln) + line[ln] = ' '; + + p = &data[i]; + for (j=0; j<PR_MIN(8, len - i); ++j, ++p) + ln += PR_snprintf(line + ln, sizeof(line) - ln, "%c", isprint(*p) ? *p : '.'); + + line[ln] = '\0'; + + i += (p - &data[i]); + + LOG(("%s\n", line)); + } +} + +#endif // IPC_LOGGING diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.h new file mode 100644 index 00000000..e21f6211 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcLog.h @@ -0,0 +1,111 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcLog_h__ +#define ipcLog_h__ + +#include "nscore.h" +#include "prtypes.h" + +#ifndef VBOX +#ifdef DEBUG +#define IPC_LOGGING +#endif +#endif + +#ifdef IPC_LOGGING + +#ifdef VBOX + +/* Redefine logging group to IPC */ +# ifdef LOG_GROUP +# undef LOG_GROUP +# endif +# define LOG_GROUP LOG_GROUP_IPC + +/* Ensure log macros are enabled */ +# ifndef LOG_ENABLED +# define LOG_ENABLED +# endif + +#include <VBox/log.h> + +extern NS_HIDDEN_(void) IPC_InitLog(const char *prefix); +extern NS_HIDDEN_(void) IPC_Log(const char *fmt, ...); +extern NS_HIDDEN_(void) IPC_LogBinary(const PRUint8 *data, PRUint32 len); + +# define IPC_LOG(_args) \ + PR_BEGIN_MACRO \ + if (IPC_LOG_ENABLED()) \ + IPC_Log _args; \ + PR_END_MACRO + +/* IPC_Log() internally uses LogFlow() so use LogIsFlowEnabled() below */ +# define IPC_LOG_ENABLED() (LogIsFlowEnabled()) + +# define LOG(args) IPC_LOG(args) + +#else /* !VBOX */ + +extern PRBool ipcLogEnabled; +extern NS_HIDDEN_(void) IPC_InitLog(const char *prefix); +extern NS_HIDDEN_(void) IPC_Log(const char *fmt, ...); +extern NS_HIDDEN_(void) IPC_LogBinary(const PRUint8 *data, PRUint32 len); + +#define IPC_LOG(_args) \ + PR_BEGIN_MACRO \ + if (ipcLogEnabled) \ + IPC_Log _args; \ + PR_END_MACRO + +#define IPC_LOG_ENABLED() ipcLogEnabled + +#define LOG(args) IPC_LOG(args) + +#endif /* !VBOX */ + +#else // IPC_LOGGING + +#define IPC_InitLog(prefix) PR_BEGIN_MACRO PR_END_MACRO +#define IPC_LogBinary(data, len) PR_BEGIN_MACRO PR_END_MACRO +#define IPC_LOG(_args) PR_BEGIN_MACRO PR_END_MACRO +#define IPC_LOG_ENABLED() (0) +#define LOG(args) PR_BEGIN_MACRO PR_END_MACRO + +#endif // IPC_LOGGING + +#endif // !ipcLog_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp new file mode 100644 index 00000000..bfdc7efe --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.cpp @@ -0,0 +1,280 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include <stdlib.h> +#include <string.h> +#include "prlog.h" +#include "ipcMessage.h" +#ifdef VBOX_USE_IPRT_IN_XPCOM +# include <iprt/mem.h> +#endif + +ipcMessage::~ipcMessage() +{ + if (mMsgHdr) +#ifdef VBOX_USE_IPRT_IN_XPCOM + RTMemFree(mMsgHdr); +#else + free(mMsgHdr); +#endif +} + +void +ipcMessage::Reset() +{ + if (mMsgHdr) { +#ifdef VBOX_USE_IPRT_IN_XPCOM + RTMemFree(mMsgHdr); +#else + free(mMsgHdr); +#endif + mMsgHdr = NULL; + } + + mMsgOffset = 0; + mMsgComplete = PR_FALSE; +} + +ipcMessage * +ipcMessage::Clone() const +{ + ipcMessage *clone = new ipcMessage(); + if (!clone) + return NULL; + + // copy buf if non-null + if (mMsgHdr) { +#ifdef VBOX_USE_IPRT_IN_XPCOM + clone->mMsgHdr = (ipcMessageHeader *) RTMemDup(mMsgHdr, mMsgHdr->mLen); +#else + clone->mMsgHdr = (ipcMessageHeader *) malloc(mMsgHdr->mLen); + memcpy(clone->mMsgHdr, mMsgHdr, mMsgHdr->mLen); +#endif + } + else + clone->mMsgHdr = NULL; + + clone->mMsgOffset = mMsgOffset; + clone->mMsgComplete = mMsgComplete; + + return clone; +} + +PRStatus +ipcMessage::Init(const nsID &target, const char *data, PRUint32 dataLen) +{ + if (mMsgHdr) +#ifdef VBOX_USE_IPRT_IN_XPCOM + RTMemFree(mMsgHdr); +#else + free(mMsgHdr); +#endif + mMsgComplete = PR_FALSE; + + // allocate message data + PRUint32 msgLen = IPC_MSG_HEADER_SIZE + dataLen; +#ifdef VBOX_USE_IPRT_IN_XPCOM + mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen); +#else + mMsgHdr = (ipcMessageHeader *) malloc(msgLen); +#endif + if (!mMsgHdr) { + mMsgHdr = NULL; + return PR_FAILURE; + } + + // fill in message data + mMsgHdr->mLen = msgLen; + mMsgHdr->mVersion = IPC_MSG_VERSION; + mMsgHdr->mFlags = 0; + mMsgHdr->mTarget = target; + + if (data) + SetData(0, data, dataLen); + + mMsgComplete = PR_TRUE; + return PR_SUCCESS; +} + +PRStatus +ipcMessage::SetData(PRUint32 offset, const char *data, PRUint32 dataLen) +{ + PR_ASSERT(mMsgHdr != NULL); + + if (offset + dataLen > DataLen()) + return PR_FAILURE; + + memcpy((char *) Data() + offset, data, dataLen); + return PR_SUCCESS; +} + +PRBool +ipcMessage::Equals(const nsID &target, const char *data, PRUint32 dataLen) const +{ + return mMsgComplete && + mMsgHdr->mTarget.Equals(target) && + DataLen() == dataLen && + memcmp(Data(), data, dataLen) == 0; +} + +PRBool +ipcMessage::Equals(const ipcMessage *msg) const +{ + PRUint32 msgLen = MsgLen(); + return mMsgComplete && msg->mMsgComplete && + msgLen == msg->MsgLen() && + memcmp(MsgBuf(), msg->MsgBuf(), msgLen) == 0; +} + +PRStatus +ipcMessage::WriteTo(char *buf, + PRUint32 bufLen, + PRUint32 *bytesWritten, + PRBool *complete) +{ + if (!mMsgComplete) + return PR_FAILURE; + + if (mMsgOffset == MsgLen()) { + *bytesWritten = 0; + *complete = PR_TRUE; + return PR_SUCCESS; + } + + PRUint32 count = MsgLen() - mMsgOffset; + if (count > bufLen) + count = bufLen; + + memcpy(buf, MsgBuf() + mMsgOffset, count); + mMsgOffset += count; + + *bytesWritten = count; + *complete = (mMsgOffset == MsgLen()); + + return PR_SUCCESS; +} + +PRStatus +ipcMessage::ReadFrom(const char *buf, + PRUint32 bufLen, + PRUint32 *bytesRead, + PRBool *complete) +{ + *bytesRead = 0; + + if (mMsgComplete) { + *complete = PR_TRUE; + return PR_SUCCESS; + } + + if (mMsgHdr) { + // appending data to buffer + if (mMsgOffset < sizeof(PRUint32)) { + // we haven't learned the message length yet + if (mMsgOffset + bufLen < sizeof(PRUint32)) { + // we still don't know the length of the message! + memcpy((char *) mMsgHdr + mMsgOffset, buf, bufLen); + mMsgOffset += bufLen; + *bytesRead = bufLen; + *complete = PR_FALSE; + return PR_SUCCESS; + } + else { + // we now have enough data to determine the message length + PRUint32 count = sizeof(PRUint32) - mMsgOffset; + memcpy((char *) MsgBuf() + mMsgOffset, buf, count); + mMsgOffset += count; + buf += count; + bufLen -= count; + *bytesRead = count; + + if (MsgLen() > IPC_MSG_GUESSED_SIZE) { + // realloc message buffer to the correct size +#ifdef VBOX_USE_IPRT_IN_XPCOM + mMsgHdr = (ipcMessageHeader *) RTMemRealloc(mMsgHdr, MsgLen()); +#else + mMsgHdr = (ipcMessageHeader *) realloc(mMsgHdr, MsgLen()); +#endif + } + } + } + } + else { + if (bufLen < sizeof(PRUint32)) { + // not enough data available in buffer to determine allocation size + // allocate a partial buffer + PRUint32 msgLen = IPC_MSG_GUESSED_SIZE; +#ifdef VBOX_USE_IPRT_IN_XPCOM + mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen); +#else + mMsgHdr = (ipcMessageHeader *) malloc(msgLen); +#endif + if (!mMsgHdr) + return PR_FAILURE; + memcpy(mMsgHdr, buf, bufLen); + mMsgOffset = bufLen; + *bytesRead = bufLen; + *complete = PR_FALSE; + return PR_SUCCESS; + } + else { + PRUint32 msgLen = *(PRUint32 *) buf; +#ifdef VBOX_USE_IPRT_IN_XPCOM + mMsgHdr = (ipcMessageHeader *) RTMemAlloc(msgLen); +#else + mMsgHdr = (ipcMessageHeader *) malloc(msgLen); +#endif + if (!mMsgHdr) + return PR_FAILURE; + mMsgHdr->mLen = msgLen; + mMsgOffset = 0; + } + } + + // have mMsgHdr at this point + + PRUint32 count = MsgLen() - mMsgOffset; + if (count > bufLen) + count = bufLen; + + memcpy((char *) mMsgHdr + mMsgOffset, buf, count); + mMsgOffset += count; + *bytesRead += count; + + *complete = mMsgComplete = (mMsgOffset == MsgLen()); + return PR_SUCCESS; +} diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.h new file mode 100644 index 00000000..c9f8f184 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessage.h @@ -0,0 +1,214 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcMessage_h__ +#define ipcMessage_h__ + +#include "nsID.h" + +// +// ipc message format: +// +// +------------------------------------+ +// | DWORD : length | +// +------------------+-----------------+ +// | WORD : version | WORD : flags | +// +------------------+-----------------+ +// | nsID : target | +// +------------------------------------+ +// | data | +// +------------------------------------+ +// +// header is 24 bytes. flags are defined below. default value of flags is +// zero. protocol implementations should ignore unrecognized flags. target +// is a 16 byte UUID indicating the intended receiver of this message. +// + +struct ipcMessageHeader +{ + PRUint32 mLen; + PRUint16 mVersion; + PRUint16 mFlags; + nsID mTarget; +}; + +#define IPC_MSG_VERSION (0x1) +#define IPC_MSG_HEADER_SIZE (sizeof(ipcMessageHeader)) +#define IPC_MSG_GUESSED_SIZE (IPC_MSG_HEADER_SIZE + 64) + +// +// the IPC message protocol supports synchronous messages. these messages can +// only be sent from a client to the daemon. a daemon module cannot send a +// synchronous message. the client sets the SYNC_QUERY flag to indicate that +// it is expecting a response with the SYNC_REPLY flag set. +// +#define IPC_MSG_FLAG_SYNC_QUERY (0x1) +#define IPC_MSG_FLAG_SYNC_REPLY (0x2) + +// +// a special flag to prevent repeated processing of the same message by two +// or more selectors when walking through the queue of pending messages +// in WaitTarget(). +// +#define IPC_MSG_FLAG_IN_PROCESS (0x4) + +//----------------------------------------------------------------------------- +// ipcMessage +//----------------------------------------------------------------------------- + +class ipcMessage +{ +public: + ipcMessage() + : mNext(NULL) + , mMetaData(0) + , mMsgHdr(NULL) + , mMsgOffset(0) + , mMsgComplete(PR_FALSE) + { } + ipcMessage(const nsID &target, const char *data, PRUint32 dataLen) + : mNext(NULL) + , mMetaData(0) + , mMsgHdr(NULL) + , mMsgOffset(0) + { Init(target, data, dataLen); } + ~ipcMessage() NS_HIDDEN; + + // + // reset message to uninitialized state + // + NS_HIDDEN_(void) Reset(); + + // + // create a copy of this message + // + NS_HIDDEN_(ipcMessage *) Clone() const; + + // + // initialize message + // + // param: + // topic - message topic string + // data - message data (may be null to leave data uninitialized) + // dataLen - message data len + // + NS_HIDDEN_(PRStatus) Init(const nsID &target, const char *data, PRUint32 dataLen); + + // + // copy data into the message's data section, starting from offset. this + // function can be used to write any portion of the message's data. + // + // param: + // offset - destination offset + // data - data to write + // dataLen - number of bytes to write + // + NS_HIDDEN_(PRStatus) SetData(PRUint32 offset, const char *data, PRUint32 dataLen); + + // + // access message flags + // + void SetFlag(PRUint16 flag) { mMsgHdr->mFlags |= flag; } + void ClearFlag(PRUint16 flag) { mMsgHdr->mFlags &= ~flag; } + PRBool TestFlag(PRUint16 flag) const { return mMsgHdr->mFlags & flag; } + + // + // if true, the message is complete and the members of the message + // can be accessed. + // + PRBool IsComplete() const { return mMsgComplete; } + + // + // readonly accessors + // + const ipcMessageHeader *Header() const { return mMsgHdr; } + const nsID &Target() const { return mMsgHdr->mTarget; } + const char *Data() const { return (char *) mMsgHdr + IPC_MSG_HEADER_SIZE; } + PRUint32 DataLen() const { return mMsgHdr->mLen - IPC_MSG_HEADER_SIZE; } + const char *MsgBuf() const { return (char *) mMsgHdr; } + PRUint32 MsgLen() const { return mMsgHdr->mLen; } + + // + // message comparison functions + // + // param: + // topic - message topic (may be null) + // data - message data (must not be null) + // dataLen - message data length + // + NS_HIDDEN_(PRBool) Equals(const nsID &target, const char *data, PRUint32 dataLen) const; + NS_HIDDEN_(PRBool) Equals(const ipcMessage *msg) const; + + // + // write the message to a buffer segment; segment need not be large + // enough to hold entire message. called repeatedly. + // + NS_HIDDEN_(PRStatus) WriteTo(char *buf, + PRUint32 bufLen, + PRUint32 *bytesWritten, + PRBool *complete); + + // + // read the message from a buffer segment; segment need not contain + // the entire messgae. called repeatedly. + // + NS_HIDDEN_(PRStatus) ReadFrom(const char *buf, + PRUint32 bufLen, + PRUint32 *bytesRead, + PRBool *complete); + + // + // a message can be added to a singly-linked list. + // + class ipcMessage *mNext; + + // + // meta data associated with this message object. the owner of the + // ipcMessage object is free to use this field for any purpose. by + // default, it is initialized to 0. + // + PRUint32 mMetaData; + +private: + ipcMessageHeader *mMsgHdr; + + // XXX document me + PRUint32 mMsgOffset; + PRPackedBool mMsgComplete; +}; + +#endif // !ipcMessage_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.cpp new file mode 100644 index 00000000..08753ddb --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.cpp @@ -0,0 +1,81 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include <string.h> +#include "ipcMessagePrimitives.h" + +ipcMessage_DWORD_STR::ipcMessage_DWORD_STR(const nsID &target, + PRUint32 first, + const char *second) +{ + int sLen = strlen(second); + Init(target, NULL, 4 + sLen + 1); + SetData(0, (char *) &first, 4); + SetData(4, second, sLen + 1); +} + +ipcMessage_DWORD_DWORD_STR::ipcMessage_DWORD_DWORD_STR(const nsID &target, + PRUint32 first, + PRUint32 second, + const char *third) +{ + int sLen = strlen(third); + Init(target, NULL, 8 + sLen + 1); + SetData(0, (char *) &first, 4); + SetData(4, (char *) &second, 4); + SetData(8, third, sLen + 1); +} + +ipcMessage_DWORD_ID::ipcMessage_DWORD_ID(const nsID &target, + PRUint32 first, + const nsID &second) +{ + Init(target, NULL, 4 + sizeof(nsID)); + SetData(0, (char *) &first, 4); + SetData(4, (char *) &second, sizeof(nsID)); +} + +ipcMessage_DWORD_DWORD_ID::ipcMessage_DWORD_DWORD_ID(const nsID &target, + PRUint32 first, + PRUint32 second, + const nsID &third) +{ + Init(target, NULL, 8 + sizeof(nsID)); + SetData(0, (char *) &first, 4); + SetData(4, (char *) &second, 4); + SetData(8, (char *) &third, sizeof(nsID)); +} diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.h new file mode 100644 index 00000000..abfa7d69 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessagePrimitives.h @@ -0,0 +1,206 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcMessagePrimitives_h__ +#define ipcMessagePrimitives_h__ + +#include "ipcMessage.h" + +class ipcMessage_DWORD : public ipcMessage +{ +public: + ipcMessage_DWORD(const nsID &target, PRUint32 first) + { + Init(target, (char *) &first, sizeof(first)); + } + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } +}; + +class ipcMessage_DWORD_DWORD : public ipcMessage +{ +public: + ipcMessage_DWORD_DWORD(const nsID &target, PRUint32 first, PRUint32 second) + { + PRUint32 data[2] = { first, second }; + Init(target, (char *) data, sizeof(data)); + } + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + PRUint32 Second() const + { + return ((PRUint32 *) Data())[1]; + } +}; + +class ipcMessage_DWORD_DWORD_DWORD : public ipcMessage +{ +public: + ipcMessage_DWORD_DWORD_DWORD(const nsID &target, PRUint32 first, PRUint32 second, PRUint32 third) + { + PRUint32 data[3] = { first, second, third }; + Init(target, (char *) data, sizeof(data)); + } + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + PRUint32 Second() const + { + return ((PRUint32 *) Data())[1]; + } + + PRUint32 Third() const + { + return ((PRUint32 *) Data())[2]; + } +}; + +class ipcMessage_DWORD_DWORD_DWORD_DWORD : public ipcMessage +{ +public: + ipcMessage_DWORD_DWORD_DWORD_DWORD(const nsID &target, PRUint32 first, PRUint32 second, PRUint32 third, PRUint32 fourth) + { + PRUint32 data[4] = { first, second, third, fourth }; + Init(target, (char *) data, sizeof(data)); + } + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + PRUint32 Second() const + { + return ((PRUint32 *) Data())[1]; + } + + PRUint32 Third() const + { + return ((PRUint32 *) Data())[2]; + } + + PRUint32 Fourth() const + { + return ((PRUint32 *) Data())[3]; + } +}; + +class ipcMessage_DWORD_STR : public ipcMessage +{ +public: + ipcMessage_DWORD_STR(const nsID &target, PRUint32 first, const char *second) NS_HIDDEN; + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + const char *Second() const + { + return Data() + sizeof(PRUint32); + } +}; + +class ipcMessage_DWORD_DWORD_STR : public ipcMessage +{ +public: + ipcMessage_DWORD_DWORD_STR(const nsID &target, PRUint32 first, PRUint32 second, const char *third) NS_HIDDEN; + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + PRUint32 Second() const + { + return ((PRUint32 *) Data())[1]; + } + + const char *Third() const + { + return Data() + 2 * sizeof(PRUint32); + } +}; + +class ipcMessage_DWORD_ID : public ipcMessage +{ +public: + ipcMessage_DWORD_ID(const nsID &target, PRUint32 first, const nsID &second) NS_HIDDEN; + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + const nsID &Second() const + { + return * (const nsID *) (Data() + sizeof(PRUint32)); + } +}; + +class ipcMessage_DWORD_DWORD_ID : public ipcMessage +{ +public: + ipcMessage_DWORD_DWORD_ID(const nsID &target, PRUint32 first, PRUint32 second, const nsID &third) NS_HIDDEN; + + PRUint32 First() const + { + return ((PRUint32 *) Data())[0]; + } + + PRUint32 Second() const + { + return ((PRUint32 *) Data())[1]; + } + + const nsID &Third() const + { + return * (const nsID *) (Data() + 2 * sizeof(PRUint32)); + } +}; + +#endif // !ipcMessagePrimitives_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageQ.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageQ.h new file mode 100644 index 00000000..d372713e --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageQ.h @@ -0,0 +1,46 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcMessageQ_h__ +#define ipcMessageQ_h__ + +#include "ipcMessage.h" +#include "ipcList.h" + +typedef ipcList<ipcMessage> ipcMessageQ; + +#endif // !ipcMessageQ_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageUtils.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageUtils.h new file mode 100644 index 00000000..99e3e6b8 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageUtils.h @@ -0,0 +1,66 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcMessageUtils_h__ +#define ipcMessageUtils_h__ + +class ipcMessage; + +// +// given code like this: +// +// const ipcmMessageClientID *msg = (const ipcmMessageClientID *) rawMsg; +// +// we can write: +// +// ipcMessageCast<ipcmMessageClientID> msg(rawMsg); +// +// XXX ipcMessageCast is probably not the best name for this class. +// +template<class T> +class ipcMessageCast +{ +public: + ipcMessageCast() : mPtr(NULL) {} + ipcMessageCast(const ipcMessage *ptr) : mPtr((const T *) ptr) {} + void operator=(const ipcMessage *ptr) { mPtr = (const T *) ptr; } + const T *operator->() { return mPtr; } +private: + const T *mPtr; +}; + +#endif // !ipcMessageUtils_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.cpp new file mode 100644 index 00000000..5464f9a7 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.cpp @@ -0,0 +1,80 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "ipcStringList.h" + +void * +ipcStringNode::operator new(size_t size, const char *str) CPP_THROW_NEW +{ + int len = strlen(str); + + size += len; + + ipcStringNode *node = (ipcStringNode *) ::operator new(size); + if (!node) + return NULL; + + node->mNext = NULL; + memcpy(node->mData, str, len); + node->mData[len] = '\0'; + + return node; +} + +ipcStringNode * +ipcStringList::FindNode(ipcStringNode *node, const char *str) +{ + while (node) { + if (node->Equals(str)) + return node; + node = node->mNext; + } + return NULL; +} + +ipcStringNode * +ipcStringList::FindNodeBefore(ipcStringNode *node, const char *str) +{ + ipcStringNode *prev = NULL; + while (node) { + if (node->Equals(str)) + return prev; + prev = node; + node = node->mNext; + } + return NULL; +} diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.h new file mode 100644 index 00000000..2a2316b6 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.h @@ -0,0 +1,114 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcStringList_h__ +#define ipcStringList_h__ + +#include <string.h> +#include "plstr.h" +#include "nscore.h" +#include "ipcList.h" + +//----------------------------------------------------------------------------- +// string node +//----------------------------------------------------------------------------- + +class ipcStringNode +{ +public: + ipcStringNode() {} + + const char *Value() const { return mData; } + + PRBool Equals(const char *val) const { return strcmp(mData, val) == 0; } + PRBool EqualsIgnoreCase(const char *val) const { return PL_strcasecmp(mData, val) == 0; } + + class ipcStringNode *mNext; +private: + void *operator new(size_t size, const char *str) CPP_THROW_NEW; + + // this is actually bigger + char mData[1]; + + friend class ipcStringList; +}; + +//----------------------------------------------------------------------------- +// singly-linked list of strings +//----------------------------------------------------------------------------- + +class ipcStringList : public ipcList<ipcStringNode> +{ +public: + typedef ipcList<ipcStringNode> Super; + + void Prepend(const char *str) + { + Super::Prepend(new (str) ipcStringNode()); + } + + void Append(const char *str) + { + Super::Append(new (str) ipcStringNode()); + } + + const ipcStringNode *Find(const char *str) const + { + return FindNode(mHead, str); + } + + PRBool FindAndDelete(const char *str) + { + ipcStringNode *node = FindNodeBefore(mHead, str); + if (node) { + DeleteAfter(node); + return PR_TRUE; + } + else if (!IsEmpty()) { + DeleteFirst(); + return PR_TRUE; + } + + return PR_FALSE; + } + +private: + static NS_HIDDEN_(ipcStringNode *) FindNode (ipcStringNode *head, const char *str); + static NS_HIDDEN_(ipcStringNode *) FindNodeBefore(ipcStringNode *head, const char *str); +}; + +#endif // !ipcStringList_h__ diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.cpp b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.cpp new file mode 100644 index 00000000..7f7ed060 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.cpp @@ -0,0 +1,303 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include <string.h> +#include "ipcm.h" +#include "pratom.h" + +const nsID IPCM_TARGET = +{ /* 753ca8ff-c8c2-4601-b115-8c2944da1150 */ + 0x753ca8ff, + 0xc8c2, + 0x4601, + {0xb1, 0x15, 0x8c, 0x29, 0x44, 0xda, 0x11, 0x50} +}; + +PRUint32 +IPCM_NewRequestIndex() +{ + static PRInt32 sRequestIndex; + return (PRUint32) PR_AtomicIncrement(&sRequestIndex); +} + +#if 0 + +// +// MSG_TYPE values +// +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 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; +const PRUint32 ipcmMessageClientStatus::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_STATUS; + +// +// CLIENT_INFO message +// +// +-----------------------------------------+ +// | DWORD : MSG_TYPE | +// +--------------------+--------------------+ +// | DWORD : clientID | +// +--------------------+--------------------+ +// | DWORD : requestIndex | +// +--------------------+--------------------+ +// | WORD : nameStart | WORD : nameCount | +// +--------------------+--------------------+ +// | WORD : targetStart | WORD : targetCount | +// +--------------------+--------------------+ +// | name[0] | (null byte) | +// +--------------------+--------------------+ +// . . . +// . . . +// +--------------------+--------------------+ +// | name[count - 1] | (null byte) | +// +--------------------+--------------------+ +// | target[0] | +// +-----------------------------------------+ +// . . . +// . . . +// +-----------------------------------------+ +// | target[count - 1] | +// +-----------------------------------------+ +// + +struct ipcmClientInfoHeader +{ + PRUint32 mType; + PRUint32 mID; + PRUint32 mRequestIndex; + PRUint16 mNameStart; + PRUint16 mNameCount; + PRUint16 mTargetStart; + PRUint16 mTargetCount; +}; + +ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, PRUint32 rIdx, const char *names[], const nsID *targets[]) +{ + ipcmClientInfoHeader hdr = {0}; + + hdr.mType = MSG_TYPE; + hdr.mID = cID; + hdr.mRequestIndex = rIdx; + 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); + + // + // 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; + } +} + +PRUint32 +ipcmMessageClientInfo::ClientID() const +{ + ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data(); + return hdr->mID; +} + +PRUint32 +ipcmMessageClientInfo::RequestIndex() const +{ + ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data(); + return hdr->mRequestIndex; +} + +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 *) (Data() + hdr->mTargetStart); + + if (++target == (const nsID *) (MsgBuf() + MsgLen())) + target = NULL; + return target; +} +#endif + +// +// FORWARD message +// +// +-------------------------+ +// | DWORD : MSG_TYPE | +// +-------------------------+ +// | clientID | +// +-------------------------+ +// | innerMsgHeader | +// +-------------------------+ +// | innerMsgData | +// +-------------------------+ +// + +ipcmMessageForward::ipcmMessageForward(PRUint32 type, + PRUint32 cID, + const nsID &target, + const char *data, + PRUint32 dataLen) +{ + int len = sizeof(ipcmMessageHeader) + // IPCM header + sizeof(cID) + // cID + IPC_MSG_HEADER_SIZE + // innerMsgHeader + dataLen; // innerMsgData + + Init(IPCM_TARGET, NULL, len); + + ipcmMessageHeader ipcmHdr = + { type, IPCM_NewRequestIndex() }; + + SetData(0, (char *) &ipcmHdr, sizeof(ipcmHdr)); + SetData(sizeof(ipcmHdr), (char *) &cID, sizeof(cID)); + + ipcMessageHeader hdr; + hdr.mLen = IPC_MSG_HEADER_SIZE + dataLen; + hdr.mVersion = IPC_MSG_VERSION; + hdr.mFlags = 0; + hdr.mTarget = target; + + SetData(sizeof(ipcmHdr) + sizeof(cID), (char *) &hdr, IPC_MSG_HEADER_SIZE); + if (data) + SetInnerData(0, data, dataLen); +} + +void +ipcmMessageForward::SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen) +{ + SetData(sizeof(ipcmMessageHeader) + 4 + IPC_MSG_HEADER_SIZE + offset, data, dataLen); +} + +PRUint32 +ipcmMessageForward::ClientID() const +{ + return ((PRUint32 *) Data())[2]; +} + +const nsID & +ipcmMessageForward::InnerTarget() const +{ + ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12); + return hdr->mTarget; +} + +const char * +ipcmMessageForward::InnerData() const +{ + return Data() + 12 + IPC_MSG_HEADER_SIZE; +} + +PRUint32 +ipcmMessageForward::InnerDataLen() const +{ + ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12); + return hdr->mLen - IPC_MSG_HEADER_SIZE; +} diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h new file mode 100644 index 00000000..a6445654 --- /dev/null +++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h @@ -0,0 +1,502 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla IPC. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef ipcm_h__ +#define ipcm_h__ + +#include "ipcMessage.h" +#include "ipcMessagePrimitives.h" + +//----------------------------------------------------------------------------- + +// +// IPCM (IPC Manager) protocol support +// + +// The IPCM message target identifier: +extern const nsID IPCM_TARGET; + +// +// Every IPCM message has the following structure: +// +// +-----------------------------------------+ +// | (ipc message header) | +// +-----------------------------------------+ +// | DWORD : type | +// +-----------------------------------------+ +// | DWORD : requestIndex | +// +-----------------------------------------+ +// . . +// . (payload) . +// . . +// +-----------------------------------------+ +// +// where |type| is an integer uniquely identifying the message. the type is +// composed of a message class identifier and a message number. there are 3 +// message classes: +// +// ACK - acknowledging a request +// REQ - making a request +// PSH - providing unrequested, "pushed" information +// +// The requestIndex field is initialized when a request is made. An +// acknowledgement's requestIndex is equal to that of its corresponding +// request message. This enables the requesting side of the message exchange +// to match acknowledgements to requests. The requestIndex field is ignored +// for PSH messages. +// + +// The IPCM message class is stored in the most significant byte. +#define IPCM_MSG_CLASS_REQ (1 << 24) +#define IPCM_MSG_CLASS_ACK (2 << 24) +#define IPCM_MSG_CLASS_PSH (4 << 24) + +// Requests +#define IPCM_MSG_REQ_PING (IPCM_MSG_CLASS_REQ | 1) +#define IPCM_MSG_REQ_FORWARD (IPCM_MSG_CLASS_REQ | 2) +#define IPCM_MSG_REQ_CLIENT_HELLO (IPCM_MSG_CLASS_REQ | 3) +#define IPCM_MSG_REQ_CLIENT_ADD_NAME (IPCM_MSG_CLASS_REQ | 4) +#define IPCM_MSG_REQ_CLIENT_DEL_NAME (IPCM_MSG_CLASS_REQ | 5) +#define IPCM_MSG_REQ_CLIENT_ADD_TARGET (IPCM_MSG_CLASS_REQ | 6) +#define IPCM_MSG_REQ_CLIENT_DEL_TARGET (IPCM_MSG_CLASS_REQ | 7) +#define IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME (IPCM_MSG_CLASS_REQ | 8) +#define IPCM_MSG_REQ_QUERY_CLIENT_NAMES (IPCM_MSG_CLASS_REQ | 9) // TODO +#define IPCM_MSG_REQ_QUERY_CLIENT_TARGETS (IPCM_MSG_CLASS_REQ | 10) // TODO + +// Acknowledgements +#define IPCM_MSG_ACK_RESULT (IPCM_MSG_CLASS_ACK | 1) +#define IPCM_MSG_ACK_CLIENT_ID (IPCM_MSG_CLASS_ACK | 2) +#define IPCM_MSG_ACK_CLIENT_NAMES (IPCM_MSG_CLASS_ACK | 3) // TODO +#define IPCM_MSG_ACK_CLIENT_TARGETS (IPCM_MSG_CLASS_ACK | 4) // TODO + +// Push messages +#define IPCM_MSG_PSH_CLIENT_STATE (IPCM_MSG_CLASS_PSH | 1) +#define IPCM_MSG_PSH_FORWARD (IPCM_MSG_CLASS_PSH | 2) + +//----------------------------------------------------------------------------- + +// +// IPCM header +// +struct ipcmMessageHeader +{ + PRUint32 mType; + PRUint32 mRequestIndex; +}; + +// +// returns IPCM message type. +// +static inline int +IPCM_GetType(const ipcMessage *msg) +{ + return ((const ipcmMessageHeader *) msg->Data())->mType; +} + +// +// return IPCM message request index. +// +static inline PRUint32 +IPCM_GetRequestIndex(const ipcMessage *msg) +{ + return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex; +} + +// +// return a request index that is unique to this process. +// +NS_HIDDEN_(PRUint32) +IPCM_NewRequestIndex(); + +//----------------------------------------------------------------------------- + +// +// The IPCM protocol is detailed below: +// + +// REQUESTS + +// +// req: IPCM_MSG_REQ_PING +// ack: IPCM_MSG_ACK_RESULT +// +// A PING can be sent from either a client to the daemon, or from the daemon +// to a client. The expected acknowledgement is a RESULT message with a status +// code of 0. +// +// This request message has no payload. +// + +// +// req: IPCM_MSG_REQ_FORWARD +// ack: IPCM_MSG_ACK_RESULT +// +// A FORWARD is sent when a client wishes to send a message to another client. +// The payload of this message is another message that should be forwarded by +// the daemon's IPCM to the specified client. The expected acknowledgment is +// a RESULT message with a status code indicating success or failure. +// +// When the daemon receives a FORWARD message, it creates a PSH_FORWARD message +// and sends that on to the destination client. +// +// This request message has as its payload: +// +// +-----------------------------------------+ +// | DWORD : clientID | +// +-----------------------------------------+ +// | (innerMsgHeader) | +// +-----------------------------------------+ +// | (innerMsgData) | +// +-----------------------------------------+ +// + +// +// req: IPCM_MSG_REQ_CLIENT_HELLO +// ack: IPCM_MSG_REQ_CLIENT_ID <or> IPCM_MSG_REQ_RESULT +// +// A CLIENT_HELLO is sent when a client connects to the IPC daemon. The +// expected acknowledgement is a CLIENT_ID message informing the new client of +// its ClientID. If for some reason the IPC daemon cannot accept the new +// client, it returns a RESULT message with a failure status code. +// +// This request message has no payload. +// + +// +// req: IPCM_MSG_REQ_CLIENT_ADD_NAME +// ack: IPCM_MSG_ACK_RESULT +// +// A CLIENT_ADD_NAME is sent when a client wishes to register an additional +// name for itself. The expected acknowledgement is a RESULT message with a +// status code indicating success or failure. +// +// This request message has as its payload a null-terminated ASCII character +// string indicating the name of the client. +// + +// +// req: IPCM_MSG_REQ_CLIENT_DEL_NAME +// ack: IPCM_MSG_ACK_RESULT +// +// A CLIENT_DEL_NAME is sent when a client wishes to unregister a name that it +// has registered. The expected acknowledgement is a RESULT message with a +// status code indicating success or failure. +// +// This request message has as its payload a null-terminated ASCII character +// string indicating the name of the client. +// + +// +// req: IPCM_MSG_REQ_CLIENT_ADD_TARGET +// ack: IPCM_MSG_ACK_RESULT +// +// A CLIENT_ADD_TARGET is sent when a client wishes to register an additional +// target that it supports. The expected acknowledgement is a RESULT message +// with a status code indicating success or failure. +// +// This request message has as its payload a 128-bit UUID indicating the +// target to add. +// + +// +// req: IPCM_MSG_REQ_CLIENT_DEL_TARGET +// ack: IPCM_MSG_ACK_RESULT +// +// A CLIENT_DEL_TARGET is sent when a client wishes to unregister a target +// that it has registered. The expected acknowledgement is a RESULT message +// with a status code indicating success or failure. +// +// This request message has as its payload a 128-bit UUID indicating the +// target to remove. +// + +// +// req: IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME +// ack: IPCM_MSG_ACK_CLIENT_ID <or> IPCM_MSG_ACK_RESULT +// +// A QUERY_CLIENT_BY_NAME may be sent by a client to discover the client that +// is known by a common name. If more than one client matches the name, then +// only the ID of the more recently registered client is returned. The +// expected acknowledgement is a CLIENT_ID message carrying the ID of the +// corresponding client. If no client matches the given name or if some error +// occurs, then a RESULT message with a failure status code is returned. +// +// This request message has as its payload a null-terminated ASCII character +// string indicating the client name to query. +// + +// ACKNOWLEDGEMENTS + +// +// ack: IPCM_MSG_ACK_RESULT +// +// This acknowledgement is returned to indicate a success or failure status. +// +// The payload consists of a single DWORD value. +// +// Possible status codes are listed below (negative values indicate failure +// codes): +// +#define IPCM_OK 0 // success: generic +#define IPCM_ERROR_GENERIC -1 // failure: generic +#define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist +#define IPCM_ERROR_INVALID_ARG -3 // failure: invalid request argument +#define IPCM_ERROR_NO_SUCH_DATA -4 // failure: requested data does not exist +#define IPCM_ERROR_ALREADY_EXISTS -5 // failure: data to set already exists + +// +// ack: IPCM_MSG_ACK_CLIENT_ID +// +// This acknowledgement is returned to specify a client ID. +// +// The payload consists of a single DWORD value. +// + +// PUSH MESSAGES + +// +// psh: ICPM_MSG_PSH_CLIENT_STATE +// +// This message is sent to clients to indicate the status of other clients. +// +// The payload consists of: +// +// +-----------------------------------------+ +// | DWORD : clientID | +// +-----------------------------------------+ +// | DWORD : clientState | +// +-----------------------------------------+ +// +// where, clientState is one of the following values indicating whether the +// client has recently connected (up) or disconnected (down): +// +#define IPCM_CLIENT_STATE_UP 1 +#define IPCM_CLIENT_STATE_DOWN 2 + +// +// psh: IPCM_MSG_PSH_FORWARD +// +// This message is sent by the daemon to a client on behalf of another client. +// The recipient is expected to unpack the contained message and process it. +// +// The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD, +// with the exception that the clientID field is set to the clientID of the +// sender of the IPCM_MSG_REQ_FORWARD message. +// + +//----------------------------------------------------------------------------- + +// +// NOTE: This file declares some helper classes that simplify constructing +// and parsing IPCM messages. Each class subclasses ipcMessage, but +// adds no additional member variables. |operator new| should be used +// to allocate one of the IPCM helper classes, e.g.: +// +// ipcMessage *msg = new ipcmMessageClientHello("foo"); +// +// Given an arbitrary ipcMessage, it can be parsed using logic similar +// to the following: +// +// void func(const ipcMessage *unknown) +// { +// if (unknown->Topic().Equals(IPCM_TARGET)) { +// if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) { +// ipcMessageCast<ipcmMessageClientID> msg(unknown); +// printf("Client ID: %u\n", msg->ClientID()); +// } +// } +// } +// + +// REQUESTS + +class ipcmMessagePing : public ipcMessage_DWORD_DWORD +{ +public: + ipcmMessagePing() + : ipcMessage_DWORD_DWORD( + IPCM_TARGET, + IPCM_MSG_REQ_PING, + IPCM_NewRequestIndex()) {} +}; + +class ipcmMessageForward : public ipcMessage +{ +public: + // @param type the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD + // @param clientID the client id of the sender or receiver + // @param target the message target + // @param data the message data + // @param dataLen the message data length + ipcmMessageForward(PRUint32 type, + PRUint32 clientID, + const nsID &target, + const char *data, + PRUint32 dataLen) NS_HIDDEN; + + // set inner message data, constrained to the data length passed + // to this class's constructor. + NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen); + + NS_HIDDEN_(PRUint32) ClientID() const; + NS_HIDDEN_(const nsID &) InnerTarget() const; + NS_HIDDEN_(const char *) InnerData() const; + NS_HIDDEN_(PRUint32) InnerDataLen() const; +}; + +class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD +{ +public: + ipcmMessageClientHello() + : ipcMessage_DWORD_DWORD( + IPCM_TARGET, + IPCM_MSG_REQ_CLIENT_HELLO, + IPCM_NewRequestIndex()) {} +}; + +class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR +{ +public: + ipcmMessageClientAddName(const char *name) + : ipcMessage_DWORD_DWORD_STR( + IPCM_TARGET, + IPCM_MSG_REQ_CLIENT_ADD_NAME, + IPCM_NewRequestIndex(), + name) {} + + const char *Name() const { return Third(); } +}; + +class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR +{ +public: + ipcmMessageClientDelName(const char *name) + : ipcMessage_DWORD_DWORD_STR( + IPCM_TARGET, + IPCM_MSG_REQ_CLIENT_DEL_NAME, + IPCM_NewRequestIndex(), + name) {} + + const char *Name() const { return Third(); } +}; + +class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID +{ +public: + ipcmMessageClientAddTarget(const nsID &target) + : ipcMessage_DWORD_DWORD_ID( + IPCM_TARGET, + IPCM_MSG_REQ_CLIENT_ADD_TARGET, + IPCM_NewRequestIndex(), + target) {} + + const nsID &Target() const { return Third(); } +}; + +class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID +{ +public: + ipcmMessageClientDelTarget(const nsID &target) + : ipcMessage_DWORD_DWORD_ID( + IPCM_TARGET, + IPCM_MSG_REQ_CLIENT_ADD_TARGET, + IPCM_NewRequestIndex(), + target) {} + + const nsID &Target() const { return Third(); } +}; + +class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR +{ +public: + ipcmMessageQueryClientByName(const char *name) + : ipcMessage_DWORD_DWORD_STR( + IPCM_TARGET, + IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, + IPCM_NewRequestIndex(), + name) {} + + const char *Name() const { return Third(); } + PRUint32 RequestIndex() const { return Second(); } +}; + +// ACKNOWLEDGEMENTS + +class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD +{ +public: + ipcmMessageResult(PRUint32 requestIndex, PRInt32 status) + : ipcMessage_DWORD_DWORD_DWORD( + IPCM_TARGET, + IPCM_MSG_ACK_RESULT, + requestIndex, + (PRUint32) status) {} + + PRInt32 Status() const { return (PRInt32) Third(); } +}; + +class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD +{ +public: + ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID) + : ipcMessage_DWORD_DWORD_DWORD( + IPCM_TARGET, + IPCM_MSG_ACK_CLIENT_ID, + requestIndex, + clientID) {} + + PRUint32 ClientID() const { return Third(); } +}; + +// PUSH MESSAGES + +class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD +{ +public: + ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus) + : ipcMessage_DWORD_DWORD_DWORD_DWORD( + IPCM_TARGET, + IPCM_MSG_PSH_CLIENT_STATE, + 0, + clientID, + clientStatus) {} + + PRUint32 ClientID() const { return Third(); } + PRUint32 ClientState() const { return Fourth(); } +}; + +#endif // !ipcm_h__ |