bool CDatum::CreateFromAttributeList (const CAttributeList &Attribs, CDatum *retdDatum) // CreateFromAttributeList // // Creates a datum from an attribute list { int i; TArray<CString> AllAttribs; Attribs.GetAll(&AllAttribs); if (AllAttribs.GetCount() == 0) { *retdDatum = CDatum(); return true; } CComplexArray *pArray = new CComplexArray; for (i = 0; i < AllAttribs.GetCount(); i++) pArray->Insert(AllAttribs[i]); *retdDatum = CDatum(pArray); return true; }
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); }
CDatum CMnemosynthDb::Read (const CString &sCollection, const CString &sKey) const // Read // // Read an entry in a collection { CSmartLock Lock(m_cs); // Look for the collection. If we can't find it, then we return Nil SCollection *pCol = m_Collections.GetAt(sCollection); if (pCol == NULL) return CDatum(); // Look for the key. If we can't find it, then we return Nil SEntry *pEntry = pCol->Entries.GetAt(sKey); if (pEntry == NULL) return CDatum(); // Return the value return pEntry->dValue; }
CDatum CComplexDateTime::GetElement (int iIndex) const // GetElement // // Returns a dateTime component { switch (iIndex) { case partYear: return CDatum(m_DateTime.Year()); case partMonth: return CDatum(m_DateTime.Month()); case partDay: return CDatum(m_DateTime.Day()); case partHour: return CDatum(m_DateTime.Hour()); case partMinute: return CDatum(m_DateTime.Minute()); case partSecond: return CDatum(m_DateTime.Second()); case partMillisecond: return CDatum(m_DateTime.Millisecond()); default: return CDatum(); } }
CDatum CCryptosaurEngine::GenerateAuthToken (CDatum dData, DWORD dwLifetime) // GenerateAuthToken // // Generates an authToken for the given user, scope, and lifetime. // // If dwLifetime == 0 then the token does not expire. { // Calculate the expiration time CDateTime ExpireTime; if (dwLifetime > 0) { DWORD dwLifetimeDays = dwLifetime / SECONDS_PER_DAY; DWORD dwLifetimeSeconds = dwLifetime % SECONDS_PER_DAY; ExpireTime = timeAddTime(CDateTime(CDateTime::Now), CTimeSpan(dwLifetimeDays, dwLifetimeSeconds * 1000)); } else ExpireTime = CDateTime(CDateTime::BeginningOfTime); // Get the key to sign with (the key is guaranteed to exist because we // checked at boot time). CIPInteger *pAuthTokenKey = m_Keys.GetAt(KEY_CRYPTOSAUR_AUTH_TOKEN); // Create the token CString sToken; CCryptosaurInterface::CreateAuthToken(dData, ExpireTime, *pAuthTokenKey, &sToken); return CDatum(sToken); }
bool CUserInfoSession::OnStartSession (const SArchonMessage &Msg, DWORD dwTicket) // OnStartSession // // Start { // Send an Aeon message to get the user record CComplexArray *pPayload = new CComplexArray; pPayload->Insert(USERS_TABLE_NAME); pPayload->Insert(m_sUsernameKey); // Send message ISessionHandler::SendMessageCommand(ADDRESS_AEON_COMMAND, MSG_AEON_GET_VALUE, GenerateAddress(PORT_CRYPTOSAUR_COMMAND), CDatum(pPayload), MESSAGE_TIMEOUT); // Expect reply return true; }
CDatum CDatum::GetElement (int iIndex) const // GetElement // // Gets the appropriate element { ASSERT(iIndex >= 0); switch (m_dwData & AEON_TYPE_MASK) { case AEON_TYPE_COMPLEX: { if (iIndex == 0) { IComplexDatum *pComplex = raw_GetComplex(); if (pComplex->IsArray()) return raw_GetComplex()->GetElement(0); else return *this; } else return raw_GetComplex()->GetElement(iIndex); } default: return (iIndex == 0 ? *this : CDatum()); } }
void CAeonEngine::MsgDeleteView (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgDeleteView // // Aeon.deleteView {tableAndView} { CAeonTable *pTable; DWORD dwViewID; if (!ParseTableAndView(Msg, pSecurityCtx, Msg.dPayload.GetElement(0), &pTable, &dwViewID)) return; // Delete CString sError; if (!pTable->DeleteView(dwViewID, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Done SendMessageReply(MSG_OK, CDatum(), Msg); }
void CAeonEngine::MsgGetTables (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgGetTables // // Aeon.getTables { int i; if (!m_bReady) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_NOT_READY, Msg); return; } // Get a list of all tables TArray<CAeonTable *> AllTables; GetTables(&AllTables); // Return an array of table descriptors CComplexArray *pArray = new CComplexArray; for (i = 0; i < AllTables.GetCount(); i++) { if (pSecurityCtx && !pSecurityCtx->IsNamespaceAccessible(AllTables[i]->GetName())) continue; pArray->Insert(AllTables[i]->GetDesc()); } // Reply SendMessageReply(MSG_AEON_RESULT_TABLES, CDatum(pArray), Msg); }
void CAeonView::CreateSecondaryData (const CTableDimensions &PrimaryDims, const CRowKey &PrimaryKey, CDatum dFullData, SEQUENCENUMBER RowID, CDatum *retdData) // CreateSecondaryData // // Creates the data for a secondary view row. { int i, j; CComplexStruct *pData = new CComplexStruct; // If the list of columns is empty then we just add the primary key if (m_Columns.GetCount() == 0) pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims)); // Otherwise we add all the fields listed in the columns array else { for (i = 0; i < m_Columns.GetCount(); i++) { // The special string "primaryKey" means that we insert the // primary key as a special field. if (strEquals(m_Columns[i], FIELD_PRIMARY_KEY)) pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims)); // The special string "*" means that we insert all existing // fields. else if (strEquals(m_Columns[i], STR_ALL_COLUMNS)) { for (j = 0; j < dFullData.GetCount(); j++) { CDatum dKey = dFullData.GetKey(j); CDatum dValue = dFullData.GetElement(j); if (!dValue.IsNil()) pData->SetElement(dKey, dValue); } } // Add the field by name. else { CDatum dColData = dFullData.GetElement(m_Columns[i]); if (!dColData.IsNil()) pData->SetElement(m_Columns[i], dColData); } } } // Done *retdData = CDatum(pData); }
void CMnemosynthDb::Delete (const CString &sCollection, const CString &sKey) // Delete // // Delete an entry in a collection. This is just a write of Nil. { Write(sCollection, sKey, CDatum()); }
void CEsperEngine::SendMessageReplyDisconnect (const SArchonMessage &OriginalMsg) // SendMessageReplyDisconnect // // Reply with Esper.onDisconnect { m_pProcess->SendMessageReply(MSG_ESPER_ON_DISCONNECT, CDatum(), OriginalMsg); }
void CAeonEngine::MsgOnMachineStart (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgOnMachineStart // // Exarch.onMachineStart { CSmartLock Lock(m_cs); // If we've already started, then nothing to do. if (m_bMachineStarted) return; // Check to see if we're listed in the module list. If we're not, then we // continue waiting. if (!Msg.dPayload.IsNil() && !Msg.dPayload.Find(GetProcessCtx()->GetModuleName())) return; // Aeon starting Log(MSG_LOG_INFO, STR_AEON_STARTING); // Make a list of local volumes if (!OpenLocalVolumes()) return; // We've at least gotten to onMachineStart. From now on if we get any // storage added, we have to deal with it differently. m_bMachineStarted = true; // If we have no local volumes then we cannot proceed. We wait until we // have storage to send Aeon.onStart. if (m_LocalVolumes.GetCount() == 0) { Log(MSG_LOG_INFO, STR_ERROR_NO_LOCAL_STORAGE); return; } // Make sure the database is open if (!Open()) return; // Tell any listeners that the database is ready SendMessageNotify(ADDRESS_AEON_NOTIFY, MSG_AEON_ON_START, CDatum()); // Done Log(MSG_LOG_INFO, STR_DATABASE_OPEN); }
bool CDatum::CreateFromStringValue (const CString &sValue, CDatum *retdDatum) // CreateFromStringValue // // Creates either a string or a number depending on the value. { CDatum dDatum; switch (GetStringValueType(sValue)) { case typeNil: break; case typeInteger32: dDatum = CDatum(strToInt(sValue, 0)); break; case typeIntegerIP: { CIPInteger Value; Value.InitFromString(sValue); CDatum::CreateIPIntegerFromHandoff(Value, &dDatum); break; } case typeDouble: dDatum = CDatum(strToDouble(sValue)); break; case typeString: dDatum = CDatum(sValue); break; default: return false; } if (retdDatum) *retdDatum = dDatum; return true; }
bool CDatum::CreateBinary (IByteStream &Stream, int iSize, CDatum *retDatum) // CreateBinary // // Creates a string datum containing binary data from the stream. // If iSize is -1 then we read as much as the stream has. // Otherwise we read up to iSize. { // LATER: Handle streams more than 2GB. Instead of asking how much space // is left, maybe we should just ask to truncate the size that we're // requesting. int iDataRemaining = Stream.GetStreamLength() - Stream.GetPos(); int iBinarySize = (iSize < 0 ? iDataRemaining : Min(iDataRemaining, iSize)); // 0-size if (iBinarySize == 0) { *retDatum = CDatum(); return true; } // Read the stream CComplexBinary *pBinary; try { pBinary = new CComplexBinary(Stream, iBinarySize); } catch (...) { return false; } // Done *retDatum = CDatum(pBinary); // Done return true; }
CDatum::CDatum (Types iType) // CDatum constructor { switch (iType) { case typeNil: m_dwData = 0; break; case typeTrue: m_dwData = constTrue; break; case typeInteger32: *this = CDatum((int)0); break; case typeString: *this = CDatum(NULL_STR); break; case typeArray: *this = CDatum(new CComplexArray); break; case typeDouble: *this = CDatum((double)0.0); break; case typeStruct: *this = CDatum(new CComplexStruct); break; case typeDateTime: *this = CDatum(CDateTime(CDateTime::Now)); break; case typeIntegerIP: *this = CDatum(CIPInteger(0)); break; case typeInteger64: *this = CDatum((DWORDLONG)0); break; default: ASSERT(false); m_dwData = 0; break; } }
void CCryptosaurEngine::MsgValidateAuthToken (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgValidateAuthToken // // Cryptosaur.validateAuthToken {authToken} { // Any service can validate a token if (!ValidateMessage(Msg, pSecurityCtx, false)) return; // Get the key to sign with (the key is guaranteed to exist because we // checked at boot time). CIPInteger *pAuthTokenKey = m_Keys.GetAt(KEY_CRYPTOSAUR_AUTH_TOKEN); // Validate CDatum dData; if (!CCryptosaurInterface::ValidateAuthToken(Msg.dPayload.GetElement(0), *pAuthTokenKey, &dData)) { SendMessageReply(MSG_REPLY_DATA, CDatum(), Msg); return; } // A sandboxed authtoken is not valid outside of its scope. // (But it is valid in admin services). const CString &sScope = dData.GetElement(FIELD_SCOPE); if (!sScope.IsEmpty() && pSecurityCtx && !pSecurityCtx->IsNamespaceAccessible(sScope)) { SendMessageReply(MSG_REPLY_DATA, CDatum(), Msg); return; } // Return the data in the auth token SendMessageReply(MSG_REPLY_DATA, dData, Msg); }
bool CDatum::CreateIPInteger (const CIPInteger &Value, CDatum *retdDatum) // CreateIPInteger // // Creates an IPInteger datum { CComplexInteger *pIPInt = new CComplexInteger(Value); *retdDatum = CDatum(pIPInt); return true; }
void CAeonEngine::MsgInsertNew (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgInsertNew // // Aeon.insertNew {tableName} {rowPath} {data} // // {rowPath} is an array with as many elements as the table dimensions { AEONERR error; const CString &sTable = Msg.dPayload.GetElement(0); CDatum dRowPath = Msg.dPayload.GetElement(1); CDatum dData = Msg.dPayload.GetElement(2); // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // If the table doesn't exist, then we can't continue CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Parse the path CString sError; CRowKey Path; if (!pTable->ParseDimensionPathForCreate(dRowPath, &Path, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Insert if (error = pTable->Insert(Path, dData, true, &sError)) { if (error == AEONERR_ALREADY_EXISTS) SendMessageReplyError(MSG_ERROR_ALREADY_EXISTS, sError, Msg); else SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Done SendMessageReply(MSG_OK, CDatum(), Msg); }
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 CDatum::CreateBinaryFromHandoff (CStringBuffer &Buffer, CDatum *retDatum) // CreateBinaryFromHandoff // // Creates a binary datum { CComplexBinary *pBinary = new CComplexBinary; pBinary->TakeHandoff(Buffer); *retDatum = CDatum(pBinary); return true; }
void CEsperEngine::MsgGetStatus (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgGetStatus // // Arc.getStatus { // Ask the connections for a status CEsperConnection::SStatus Status; m_Connections.GetStatus(&Status); // Compose into a struct CComplexStruct *pResult = new CComplexStruct; pResult->SetElement(CString("Esper/connectionActive"), CDatum(Status.iActive)); pResult->SetElement(CString("Esper/connectionCount"), CDatum(Status.iTotalObjects)); pResult->SetElement(CString("Esper/connectionsIdle"), CDatum(Status.iIdle)); pResult->SetElement(CString("Esper/connectionsReading"), CDatum(Status.iWaitingForRead)); pResult->SetElement(CString("Esper/connectionsWriting"), CDatum(Status.iWaitingForWrite)); // Done m_pProcess->SendMessageReply(MSG_REPLY_DATA, CDatum(pResult), Msg); }
bool CUserInfoSession::UpdateLoginFailure (void) // UpdateLoginFailure // // Update the user record with the most recent failure { // Set our state m_iState = stateWaitingForFailureUpdate; // Mutate the record to set the login date CComplexStruct *pRecord = new CComplexStruct; pRecord->SetElement(FIELD_LOGIN_FAILURE_COUNT, CDatum((int)1)); CComplexStruct *pMutation = new CComplexStruct; pMutation->SetElement(FIELD_LAST_LOGIN_FAILURE_ON, MUTATE_DATE_MODIFIED); pMutation->SetElement(FIELD_LOGIN_FAILURE_COUNT, MUTATE_INCREMENT); // Create a payload CComplexArray *pPayload = new CComplexArray; pPayload->Insert(USERS_TABLE_NAME); pPayload->Insert(m_sUsernameKey); pPayload->Insert(CDatum(pRecord)); pPayload->Insert(CDatum(pMutation)); // Send message ISessionHandler::SendMessageCommand(ADDRESS_AEON_COMMAND, MSG_AEON_MUTATE, GenerateAddress(PORT_CRYPTOSAUR_COMMAND), CDatum(pPayload), MESSAGE_TIMEOUT); // Expect reply return true; }
bool CDatum::CreateIPIntegerFromHandoff (CIPInteger &Value, CDatum *retdDatum) // CreateIPInteger // // Creates an IPInteger by taking a handoff { CComplexInteger *pIPInt = new CComplexInteger; pIPInt->TakeHandoff(Value); *retdDatum = CDatum(pIPInt); return true; }
CDatum CEsperEngine::GetPortStatus (void) const // GetPortStatus // // Returns a struct with well-known fields for status. { CDatum dStatus = CDatum(CDatum::typeStruct); dStatus.SetElement(FIELD_CLASS, STR_ESPER_ENGINE); dStatus.SetElement(FIELD_STATUS, NULL_STR); return dStatus; }
void CEsperEngine::SendMessageReplyOnWrite (CDatum dConnection, DWORD dwBytesTransferred, const SArchonMessage &OriginalMsg) // SendMessageReplyOnWrite // // Reply with Esper.onWrite { CComplexArray *pPayload = new CComplexArray; pPayload->Insert(dwBytesTransferred); pPayload->Insert(dConnection); m_pProcess->SendMessageReply(MSG_ESPER_ON_WRITE, CDatum(pPayload), OriginalMsg); }
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 CComplexDateTime::CreateFromString (const CString &sString, CDatum *retdDatum) // CreateFromString // // Creates a datum from a string { CDateTime DateTime; if (!CreateFromString(sString, &DateTime)) return false; *retdDatum = CDatum(DateTime); return true; }
CDatum CDatum::GetArrayElement (int iIndex) const // GetArrayElement // // Gets the appropriate element { ASSERT(iIndex >= 0); switch (m_dwData & AEON_TYPE_MASK) { case AEON_TYPE_COMPLEX: { if (GetBasicType() == typeArray) return raw_GetComplex()->GetElement(iIndex); else return (iIndex == 0 ? *this : CDatum()); } default: return (iIndex == 0 ? *this : CDatum()); } }
void CAeonEngine::MsgDeleteTable (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgDeleteTable // // Aeon.deleteTable {tableName} { // Parameters const CString &sTable = Msg.dPayload.GetElement(0); // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // Lock while we remove the table CSmartLock Lock(m_cs); // If the table doesn't exist, then we can't continue int iTablePos; if (!m_Tables.FindPos(sTable, &iTablePos)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Remove the table from the array CAeonTable *pTable = m_Tables.GetValue(iTablePos); m_Tables.Delete(iTablePos); // Clean up the table if (!pTable->Delete()) Log(MSG_LOG_ERROR, STR_UNABLE_TO_DELETE_TABLE_FILES); delete pTable; // We can unlock now Lock.Unlock(); // Done SendMessageReply(MSG_OK, CDatum(), Msg); }