CDatum CHyperionScheduler::GetTaskList (void) // GetTaskList // // Returns a list of tasks { CSmartLock Lock(m_cs); int i; CComplexArray *pResult = new CComplexArray; for (i = 0; i < m_Tasks.GetCount(); i++) { CComplexStruct *pTask = new CComplexStruct; pTask->SetElement(FIELD_NAME, m_Tasks[i].sName); pTask->SetElement(FIELD_STATUS, (m_Tasks[i].bRunning ? STATUS_RUNNING : STATUS_READY)); pTask->SetElement(FIELD_LAST_RAN_ON, m_Tasks[i].LastRun); pTask->SetElement(FIELD_WILL_RUN_ON, m_Tasks[i].NextRun); pTask->SetElement(FIELD_RUN_FREQUENCY, m_Tasks[i].iInterval); pResult->Append(CDatum(pTask)); } return CDatum(pResult); }
void CArchonProcess::TranspaceDownload (const CString &sAddress, const CString &sReplyAddr, DWORD dwTicket, CDatum dDownloadDesc, const CHexeSecurityCtx *pSecurityCtx) // TranspaceDownload // // Downloads a file by Transpace address. { // Compose a proper download command payload CComplexArray *pPayload = new CComplexArray; pPayload->Append(sAddress); pPayload->Append(sAddress); pPayload->Append(dDownloadDesc); CDatum dPayload(pPayload); // Transform the address into a message and a new address CString sDestMsgAddress; CString sDestMsg; CDatum dDestPayload; CString sError; if (!TransformAddress(sAddress, MSG_TRANSPACE_DOWNLOAD, dPayload, &sDestMsgAddress, &sDestMsg, &dDestPayload, &sError)) { SendMessageCommand(sReplyAddr, MSG_ERROR_UNABLE_TO_COMPLY, NULL_STR, dwTicket, CDatum(sError)); return; } // Send the message if (pSecurityCtx) { CString sWrappedMsg; CDatum dWrappedPayload; CHexeProcess::ComposeHexarcMessage(*pSecurityCtx, sDestMsg, dDestPayload, &sWrappedMsg, &dWrappedPayload); SendMessageCommand(sDestMsgAddress, sWrappedMsg, sReplyAddr, dwTicket, dWrappedPayload); } else SendMessageCommand(sDestMsgAddress, sDestMsg, sReplyAddr, dwTicket, dDestPayload); }
CDatum CAeonView::DebugDump (void) const // DebugDump // // Returns data about the view. { int i; CComplexStruct *pData = new CComplexStruct; pData->SetElement(FIELD_RECOVERY_FILESPEC, m_Recovery.GetFilespec()); CComplexArray *pSegments = new CComplexArray; for (i = 0; i < m_Segments.GetCount(); i++) pSegments->Append(m_Segments[i]->DebugDump()); pData->SetElement(FIELD_SEGMENTS, CDatum(pSegments)); return CDatum(pData); }
bool CAddModuleSession::OnStartSession (const SArchonMessage &Msg, DWORD dwTicket) // OnStartSession // // Start the session { // Payload CComplexArray *pPayload = new CComplexArray; pPayload->Append(m_sModule); // Connect to the machine with a command. m_iState = stateWaitForMsg; SendMessageCommand(m_sAddress, MSG_EXARCH_ADD_MODULE, ADDRESS_EXARCH_COMMAND, CDatum(pPayload)); // Expect reply return true; }
void CMnemosynthDb::GenerateEndpointList (CDatum *retdList) // GenerateEndpointList // // Returns data about all endpoints { CSmartLock Lock(m_cs); int i; CComplexArray *pList = new CComplexArray; for (i = 0; i < m_Endpoints.GetCount(); i++) { CComplexStruct *pData = new CComplexStruct; pData->SetElement(FIELD_ID, m_Endpoints[i].sName); pData->SetElement(FIELD_SEQ_RECV, m_Endpoints[i].dwSeqRecv); pData->SetElement(FIELD_SEQ_SENT, m_Endpoints[i].dwSeqSent); pList->Append(CDatum(pData)); } *retdList = CDatum(pList); }
bool CArchonProcess::TransformAddress (const CString &sAddress, const CString &sMsg, CDatum dPayload, CString *retsDestMsgAddress, CString *retsDestMsg, CDatum *retdPayload, CString *retsError) // TransformAddress // // Transforms a Transpace Address. { CString sNamespace; if (!CTranspaceInterface::ParseAddress(sAddress, &sNamespace)) { *retsError = strPattern(ERR_BAD_TRANSPACE_ADDRESS, sAddress); return false; } // Is this a message namespace? char *pPos = sNamespace.GetParsePointer(); if (*pPos == '@') { // Send the message directly to the port specified by the namespace *retsDestMsgAddress = CString(pPos + 1); *retsDestMsg = sMsg; *retdPayload = dPayload; } // Is this a service namespace? else if (*pPos == '#') { // Parse the service endpoint CString sService(pPos + 1); // Encode into the proper payload CComplexArray *pPayload = new CComplexArray; pPayload->Append(sService); pPayload->Append(sMsg); pPayload->Append(dPayload); // Done *retsDestMsgAddress = ADDRESS_HYPERION_COMMAND; *retsDestMsg = MSG_HYPERION_SERVICE_MSG; *retdPayload = CDatum(pPayload); } // If this is a slash, then convert to Aeon else if (*pPos == '/') { *retsDestMsgAddress = ADDRESS_AEON_COMMAND; *retsDestMsg = sMsg; *retdPayload = dPayload; } // Otherwise, can't parse else { *retsError = strPattern(ERR_BAD_TRANSPACE_ADDRESS, sAddress); return false; } return true; }
void CExarchEngine::MsgAddModule (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgAddModule // // Exarch.addModule [{machineName}] {filePath} [{debug}] { CSmartLock Lock(m_cs); CString sError; // Must be admin service if (!ValidateSandboxAdmin(Msg, pSecurityCtx)) return; // Get parameters bool bHasMachineName = (Msg.dPayload.GetCount() >= 2 && !strEndsWith(strToLower(Msg.dPayload.GetElement(0)), STR_EXE_SUFFIX)); int iArg = 0; CString sMachineName = (bHasMachineName ? Msg.dPayload.GetElement(iArg++) : NULL_STR); CString sModuleFilePath = Msg.dPayload.GetElement(iArg++); CDatum dDebug = Msg.dPayload.GetElement(iArg++); // If we have a machine name, try to parse it in case the user gave us // a partial name. if (bHasMachineName) { if (!ParseMachineName(sMachineName, &sMachineName)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern("Unknown machine: %s", sMachineName), Msg); return; } } // If this is not for our machine, then we need to send a message to the // other machine. if (!sMachineName.IsEmpty() && !strEqualsNoCase(GetMachineName(), sMachineName)) { CString sAddress = GenerateMachineAddress(sMachineName, ADDRESS_EXARCH_COMMAND); if (sAddress.IsEmpty()) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern("Unable to generate address for: %s", sMachineName), Msg); return; } StartSession(Msg, new CAddModuleSession(this, sAddress, sModuleFilePath)); } // Otherwise, we add a local module else { // Add the module CString sModuleName; if (!AddModule(sModuleFilePath, strEqualsNoCase(dDebug, FIELD_DEBUG), &sModuleName, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Add it to our list of modules CComplexArray *pModuleList = new CComplexArray(m_dMachineConfig.GetElement(FIELD_MODULES)); pModuleList->Append(CDatum(sModuleName)); CComplexStruct *pConfig = new CComplexStruct(m_dMachineConfig); pConfig->SetElement(FIELD_MODULES, CDatum(pModuleList)); m_dMachineConfig = CDatum(pConfig); // Save it WriteConfig(); // Done SendMessageReply(MSG_OK, CDatum(), Msg); } }
bool CAeonInterface::ParseFilePath (const CString &sFilePath, const CString &sRoot, int iOffset, const CDateTime &IfModifiedAfter, CString *retsAddr, CString *retsMsg, CDatum *retdPayload) // ParseFilePath // // Parses a filePath of the form: // // @Aeon.command/Arc.services/TransPackage.ars // /Arc.services/TransPackage.ars // ./TransPackage.ars // // Returns FALSE if error. { char *pPos = sFilePath.GetParsePointer(); char *pPosEnd = pPos + sFilePath.GetLength(); // Create a fileDownloadDesc to specify that we not read more than 100K // at a time (so that we don't overload our IPC buffer). CComplexStruct *pFDDesc = new CComplexStruct; pFDDesc->SetElement(FIELD_PARTIAL_MAX_SIZE, 100000); pFDDesc->SetElement(FIELD_PARTIAL_POS, iOffset); if (IfModifiedAfter.IsValid()) pFDDesc->SetElement(FIELD_IF_MODIFIED_AFTER, IfModifiedAfter); CDatum dFileDownloadDesc(pFDDesc); // If the path starts with @ then this is an absolute path CString sParsedPath; if (*pPos == '@') { // LATER return false; } // Is this a service namespace? else if (*pPos == '#') { CString sNamespace; if (!CTranspaceInterface::ParseAddress(sFilePath, &sNamespace)) return false; // Compose a proper download command payload CComplexArray *pPayload = new CComplexArray; pPayload->Append(sFilePath); pPayload->Append(sFilePath); pPayload->Append(dFileDownloadDesc); CDatum dPayload(pPayload); // Parse the service endpoint CString sService(sNamespace.GetParsePointer() + 1); // Encode into the proper payload CComplexArray *pPayload2 = new CComplexArray; pPayload2->Append(sService); pPayload2->Append(MSG_TRANSPACE_DOWNLOAD); pPayload2->Append(dPayload); // Done *retsAddr = ADDRESS_HYPERION_COMMAND; *retsMsg = MSG_HYPERION_SERVICE_MSG; *retdPayload = CDatum(pPayload2); return true; } // If it starts with a slash then it is an Aeon path else if (*pPos == '/') { sParsedPath = sFilePath; *retsAddr = ADDR_AEON; *retsMsg = MSG_AEON_FILE_DOWNLOAD; // Generate a message for Aeon to load the file CComplexArray *pPayload = new CComplexArray; pPayload->Insert(sParsedPath); pPayload->Insert(dFileDownloadDesc); // Done *retdPayload = CDatum(pPayload); } // If it starts with a ./ then this is a relative path else if (*pPos == '.') { pPos++; if (pPos == pPosEnd || *pPos != '/') return false; // Root must be valid if (sRoot.IsEmpty()) return false; // If the root already ends in '/' then skip. if (*(sRoot.GetParsePointer() + sRoot.GetLength() - 1) == '/') pPos++; sParsedPath = sRoot + CString(pPos); *retsAddr = ADDR_AEON; *retsMsg = MSG_AEON_FILE_DOWNLOAD; // Generate a message for Aeon to load the file CComplexArray *pPayload = new CComplexArray; pPayload->Insert(sParsedPath); pPayload->Insert(dFileDownloadDesc); // Done *retdPayload = CDatum(pPayload); } // Otherwise this is a relative path. else { // Root must be valid if (sRoot.IsEmpty()) return false; // Add '/' separator if (*(sRoot.GetParsePointer() + sRoot.GetLength() - 1) == '/') sParsedPath = sRoot + sFilePath; else sParsedPath = sRoot + SEPARATOR_SLASH, sFilePath; *retsAddr = ADDR_AEON; *retsMsg = MSG_AEON_FILE_DOWNLOAD; // Generate a message for Aeon to load the file CComplexArray *pPayload = new CComplexArray; pPayload->Insert(sParsedPath); pPayload->Insert(dFileDownloadDesc); // Done *retdPayload = CDatum(pPayload); } return true; }