void deliverDispatch(DISPATCH_PTR dispatch) { char *data; DATA_MSG_PTR newDataMsg; X_IPC_MSG_CLASS_TYPE msg_class; CLASS_FORM_PTR classForm; data = NULL; dispatchUpdateAndDisplay(AttendingDispatch, dispatch); if (dispatch->des == GET_S_GLOBAL(x_ipcServerModGlobal)) { if (monitorClass(dispatch->msg->msgData->msg_class)) { data = dispatch->classData; } else { data = (char *)x_ipc_dataMsgDecodeMsg(dispatch->msg->msgData->msgFormat, DISPATCH_MSG_DATA(dispatch),TRUE); } (*dispatch->hnd->hndProc)(dispatch, data); if (dispatch->msg_class == InformClass) { dispatchUpdateAndDisplay(HandledDispatch, dispatch); } } else { if (dispatch->hnd->msg != dispatch->msg) { /* handler to recieve new message */ msg_class = ExecHndClass; classForm = GET_CLASS_FORMAT(&msg_class); if (!classForm) X_IPC_ERROR("ERROR: deliverDispatch: missing ExecHndClass class format."); newDataMsg = x_ipc_dataMsgReplaceClassData(classForm->format, (char*)&dispatch->msg->msgData->name, dispatch->msgData, dispatch->msg->msgData->msgFormat ); /* 31-Oct-90: fedor: the x_ipc_dataMsgReplaceClassData routine calls x_ipc_dataMsgFree - this avoids calling it twice and gets the refs correct. blah! */ dispatch->msgData = NULL; dispatchSetMsgData(newDataMsg, dispatch); } else { /* The datamags may already have old class data. Since class data follows message data, this will prevent old class data from being sent. */ dispatch->msgData->classTotal = 0; } dispatch->msgData->intent = dispatch->hnd->hndData->refId; dispatch->msgData->msgRef = dispatch->locId; (void)x_ipc_dataMsgSend(dispatch->desId, dispatch->msgData); } }
static void formatterSend(int sd, CONST_FORMAT_PTR form) { DATA_MSG_PTR dataMsg; NAMED_FORMAT_PTR formatFormat; formatFormat = (NAMED_FORMAT_PTR)x_ipc_hashTableFind("format", GET_M_GLOBAL(formatNamesTable)); if (!formatFormat) { X_IPC_ERROR("ERROR: formatterSend: no formatFormat"); } dataMsg = x_ipc_dataMsgCreate(0, 0, 0, 0, 0, formatFormat->format, (void *)&form, (FORMAT_PTR)NULL, (void *)NULL); (void)x_ipc_dataMsgSend(sd, dataMsg); x_ipc_dataMsgFree(dataMsg); }
DISPATCH_PTR buildDispatchInternal(MSG_PTR msg, DATA_MSG_PTR dataMsg, void *classData, DISPATCH_PTR parentDispatch, RESP_PROC_FN resProc, void *resData) { int32 savedRef; DISPATCH_PTR dispatch; if (!msg) { X_IPC_ERROR("ERROR: sendDataMsg: NULL msg.\n"); } /* save the message ref to use in case x_ipc_msgFind triggers a recursive call to x_ipc_sendMessage */ savedRef = x_ipc_nextSendMessageRef(); dispatch = dispatchAllocate(); dispatch->msg = msg; dispatch->org = GET_S_GLOBAL(x_ipcServerModGlobal); dispatch->orgId = GET_C_GLOBAL(serverWrite); dispatch->refId = savedRef; dispatchSetMsgData(dataMsg, dispatch); if (resProc) { dispatch->respProc = resProc; dispatch->respData = (char *)resData; } if (parentDispatch) dispatch->pRef = parentDispatch->locId; dispatch->msg_class = msg->msgData->msg_class; dispatch->classData = (char *)classData; return dispatch; }
/* The straightforward way to do this would be using "centralReply", but that calls "recvMessage" recursively, which breaks things. */ static void sendMultiQueryTermination (DISPATCH_PTR dispatch) { static DATA_MSG_PTR nullReplyData = NULL; if (!nullReplyData) { nullReplyData = x_ipc_dataMsgCreate(0, QUERY_REPLY_INTENT, 0, 0, 0, (FORMAT_PTR)NULL, (char *)NULL, (FORMAT_PTR)NULL, (char *)NULL); } nullReplyData->msgRef = dispatch->refId; if (!dispatch->org) X_IPC_ERROR("Error: sendMultiQueryTermination: No query origin."); else { if (dispatch->org->alive) { (void)x_ipc_dataMsgSend(dispatch->org->writeSd, nullReplyData); } else if (!dispatch->org->repliesPending) { moduleFree(dispatch->org); } } }
int main(int argc, char **argv) #endif { int expectedMods = 0; #ifdef macintosh doSiouxStuff(); argc = ccommand(&argv); #endif /* Added by Bob Goode/Tam Ngo, 5/21/97, for WINSOCK option. */ #ifdef OS2 sock_init(); #elif defined(_WINSOCK_) startWinsock(); #endif /* Winsock DLL loading */ x_ipcModuleInitialize(); #ifdef VXWORKS /* Do this only after the socket is set up (in case there is an old central lying around that needs killed */ centralTID = taskIdSelf(); #endif globalSInit(); #if !defined(THINK_C) && !defined(macintosh) && !defined(__TURBOC__) && !defined(OS2) && !defined(_WIN95_MSC_) && !defined(WINNT) && !defined(WIN32) (void)signal(SIGINT, abortCentral); (void)signal(SIGBUS, abortCentral); (void)signal(SIGSEGV, abortCentral); (void)signal(SIGPIPE, pipeClosedHnd); (void)signal(SIGTERM, abortCentral); #endif /* !THINK_C && !macintosh */ #ifndef VXWORKS if ((argc > 1) && (STREQ(argv[1], "-v"))) displayVersion(); else if ((argc > 1) && (STREQ(argv[1], "-h"))) { displayOptions(argv[0]); #ifdef macintosh SIOUXSettings.autocloseonquit = FALSE; #endif } else { parseExpectedMods(argc, argv, &expectedMods); parseCommandLineOptions(argc, argv); #else if ((options!= NULL) && (strstr(options, "-v") || strstr(options, "-V"))) { displayVersion(); } else if ((options!= NULL) && (strstr(options, "-h") || strstr(options, "-H"))) { displayOptions("central"); } else { parseOpsFromStr(options, &expectedMods, FALSE); #endif if (expectedMods < 1) expectedMods = 1; if (!serverInitialize(expectedMods)) { X_IPC_ERROR("ERROR: Unable to start server, Is one already running?\n"); } #ifndef VXWORKS /* Register a method for freeing memory in an emergency. */ x_ipcRegisterFreeMemHnd(centralFreeMemory,3); if (GET_S_GLOBAL(listenToStdin)) printPrompt(); #endif #ifndef DEFAULT_OPTIONS fprintf(stderr, "central running...\n"); #endif listenLoop(); } #ifdef _WINSOCK_ WSACleanup(); printf("Socket cleaned up."); #endif /* Unload Winsock DLL */ #ifndef VXWORKS return 1; #endif }
void classInitialize(void) { registerClass(GoalClass, "int"); registerClass(CommandClass, "{int, int}"); registerClass(ExceptionClass, "int"); registerClass(PointMonitorClass, "int"); registerClass(ExecHndClass, "string"); registerClass(FailureClass, "string"); if (sizeof(int32) != sizeof(X_IPC_POINT_CLASS_TYPE)) { X_IPC_ERROR("INTERNAL ERROR: X_IPC_POINT_CLASS_TYPE is not of size `int'\n"); } else { centralRegisterNamedFormatter("X_IPC_POINT_CLASS_TYPE", "int"); /* 19-Aug-93: fedor: see search_hash_table_for_format for error in printData.c */ /* RTG - this causes problems with byte order between machines. * since these are just integers, use "int" for now. The method * used to do printing should be fixed. It should not have to scan * the hash table looking for structurally similar formats. */ /* centralRegisterLengthFormatter("X_IPC_POINT_CLASS_TYPE", * sizeof(int32)); */ } if (sizeof(int32) != sizeof(X_IPC_INTERVAL_CLASS_TYPE)) { X_IPC_ERROR("INTERNAL ERROR: X_IPC_INTERVAL_CLASS_TYPE is not of size `int'\n"); } else { centralRegisterNamedFormatter("X_IPC_INTERVAL_CLASS_TYPE", "int"); /* 19-Aug-93: fedor: see search_hash_table_for_format for error in printData.c */ /* RTG - this causes problems with byte order between machines. * since these are just integers, use "int" for now. The method * used to do printing should be fixed. It should not have to scan * the hash table looking for structurally similar formats. */ /* centralRegisterLengthFormatter("X_IPC_INTERVAL_CLASS_TYPE", * sizeof(int32)); */ } centralRegisterNamedFormatter("X_IPC_INTERVAL_TYPE", "{X_IPC_INTERVAL_CLASS_TYPE, int}"); /* centralRegisterNamedFormatter("X_IPC_INTERVAL_TYPE",*/ /* "{int, int}");*/ centralRegisterNamedFormatter("X_IPC_TIME_POINT_TYPE", "{X_IPC_POINT_CLASS_TYPE, X_IPC_INTERVAL_TYPE}"); /* centralRegisterNamedFormatter("X_IPC_TIME_POINT_TYPE",*/ /* "{int, X_IPC_INTERVAL_TYPE}");*/ centralRegisterNamedFormatter("INTERVAL_MONITOR_OPTIONS_PTR", "*{int, int, int, int, int}"); centralRegisterNamedFormatter("INT_MON_CLASS_TYPE", "{X_IPC_TIME_POINT_TYPE, X_IPC_TIME_POINT_TYPE, INTERVAL_MONITOR_OPTIONS_PTR}"); registerClass(PollingMonitorClass, "INT_MON_CLASS_TYPE"); registerClass(DemonMonitorClass, "INT_MON_CLASS_TYPE"); registerClass(FireDemonClass, "int"); registerClass(MultiQueryClass, "{int, int}"); }
X_IPC_RETURN_VALUE_TYPE centralSendMessage(X_IPC_REF_PTR ref, MSG_PTR msg, void *msgData, void *classData) { int32 refId, savedRef; DATA_MSG_PTR msgDataMsg; X_IPC_MSG_CLASS_TYPE msg_class; CLASS_FORM_PTR classForm; CONST_FORMAT_PTR classFormat; classFormat = NULL; if (!msg) { X_IPC_ERROR("ERROR: x_ipc_sendMessage: NULL msg.\n"); } /* save the message ref to use in case x_ipc_msgFind triggers a recursive call to x_ipc_sendMessage */ savedRef = x_ipc_nextSendMessageRef(); msg_class = msg->msgData->msg_class; classForm = GET_CLASS_FORMAT(&msg_class); if (classForm) classFormat = classForm->format; if (ref) refId = ref->refId; else refId = NO_REF; /* 8-Oct-90: fedor: parentRefGlobal problem!!! ** it is initialized to -1 in behaviors.c so maybe this will not be a problem */ msgDataMsg = x_ipc_dataMsgCreate(GET_C_GLOBAL(parentRefGlobal), msg->msgData->refId, (int32)msg_class, refId, savedRef, msg->msgData->msgFormat, msgData, classFormat, classData); if (msgDataMsg == NULL) return Failure; /* RTG - must set datastruct to be null so message does not get decoded * into the same memory location. We also have to copy the message * buffer if it is the same as the original data structure because * the original data structure can change, if the message is queued. */ if (msgDataMsg->msgData == msgData) { /* Need to copy the data, in case the messages gets queued. */ char *newCopy = NULL; newCopy = (char *)x_ipcMalloc(msgDataMsg->msgTotal); BCOPY(msgDataMsg->msgData, newCopy,msgDataMsg->msgTotal); msgDataMsg->msgData = newCopy; msgDataMsg->dataStruct = NULL; } else msgDataMsg->dataStruct = NULL; recvMessageBuild(GET_S_GLOBAL(x_ipcServerModGlobal), msgDataMsg); return Success; }