Beispiel #1
0
CDatum CAeonView::ComputeColumns (CHexeProcess &Process, CDatum dRowData)

//	ComputeColumns
//
//	Returns a new row struct containing any computed columns.

	{
	if (m_ComputedColumns.IsNil() || !m_ComputedColumns.CanInvoke())
		return dRowData;

	//	Compute columns. We should get back a struct of all new columns.

	TArray<CDatum> Args;
	Args.Insert(dRowData);

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = Process.Run(m_ComputedColumns, Args, &dResult);

	switch (iRun)
		{
		case CHexeProcess::runOK:
			{
			//	dResult is a struct containing zero or more columns

			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.Append(dResult);
			return dNewRowData;
			}

		case CHexeProcess::runError:
			{
			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.SetElement(FIELD_ERROR, strPattern("ERROR: %s", dResult.AsString()));
			return dNewRowData;
			}

		default:
			{
			CDatum dNewRowData(new CComplexStruct(dRowData));
			dNewRowData.SetElement(FIELD_ERROR, ERR_COMPUTED_COLUMN);
			return dNewRowData;
			}
		}
	}
Beispiel #2
0
CString ExecuteLispCommand (const CString &sInput)
	{
	CString sOutput;

	CDatum dExpression;
	if (!CHexeDocument::ParseLispExpression(sInput, &dExpression, &sOutput))
		return sOutput;

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = g_Process.Run(dExpression, &dResult);
	switch (iRun)
		{
		case CHexeProcess::runOK:
		case CHexeProcess::runError:
			return dResult.AsString();

		default:
			return CString("Unable to complete run.");
		}
	}
void CHexeMarkupEvaluator::OutputDatum (CDatum dValue)

//	OutputDatum
//
//	Outputs a datum to the resulting HTML page. NOTE: We expect the values to be
//	HTML compatible (i.e., caller is responsible for escaping).

	{
	int i;

	if (dValue.GetBasicType() == CDatum::typeArray)
		{
		for (i = 0; i < dValue.GetCount(); i++)
			OutputDatum(dValue.GetElement(i));
		}
	else
		{
		m_Output.Write(dValue.AsString());
		}
	}
void CHexeMarkupEvaluator::AddHeader (const CString &sField, CDatum dValue)

//	AddHeader
//
//	Adds the header

	{
	CHTTPMessage::SHeader *pNewHeader;

	switch (dValue.GetBasicType())
		{
		case CDatum::typeString:
			pNewHeader = m_Headers.Insert();
			pNewHeader->sField = sField;
			pNewHeader->sValue = dValue;
			break;

		default:
			pNewHeader = m_Headers.Insert();
			pNewHeader->sField = sField;
			pNewHeader->sValue = dValue.AsString();
		}
	}
Beispiel #5
0
CString ExecuteUpgrade (CSocket &theSocket, const CString &sCmd)
	{
	int i;

	CString sRoot = fileGetPath(fileGetExecutableFilespec());

	//	Make a list of all executable files to upgrade

	TArray<CString> FileList;
	if (!fileGetFileList(sRoot, NULL_STR, CString("*.exe"), FFL_FLAG_RELATIVE_FILESPEC, &FileList))
		return CString("ERROR: Unable to obtain a list of executable files to upgrade.");

	//	Prepare a request upgrade command

	CStringBuffer Output;
	Output.Write("requestUpgrade (", 16);

	for (i = 0; i < FileList.GetCount(); i++)
		{
		CString sFilespec = fileAppend(sRoot, FileList[i]);

		//	Version

		SFileVersionInfo Info;
		if (!fileGetVersionInfo(sFilespec, &Info))
			{
			printf("ERROR: Unable to get file version: %s\n", (LPSTR)sFilespec);
			continue;
			}

		CIPInteger Version(Info.dwProductVersion);
		CString sVersion = Version.AsString();

		//	Checksum

		DWORD dwChecksum = fileChecksumAdler32(sFilespec);
		if (dwChecksum == 0)
			{
			printf("ERROR: Unable to get file checksum: %s\n", (LPSTR)sFilespec);
			continue;
			}

		CString sOutput = strPattern("{filename:\"%s\" version:%s checksum:%d} ", FileList[i], sVersion, dwChecksum);
		Output.Write(sOutput);
		}

	Output.Write(")", 1);

	//	Send the command

	CString sSend = CString::CreateFromHandoff(Output);
	CString sResult;
	CDatum dResult;
	ExecuteArcologyCommand(theSocket, sSend, &sResult, &dResult);
	if (strEquals(sResult, CString("ERROR")))
		return dResult.AsString();

	//	Show all the files to upgrade

	CDatum dUpgradeDesc = dResult.GetElement(0).GetElement(FIELD_UPGRADE_DESC);
	for (i = 0; i < dUpgradeDesc.GetCount(); i++)
		{
		CDatum dFileDesc = dUpgradeDesc.GetElement(i);

		printf("Upgrading %s\n", (LPSTR)dFileDesc.GetElement(FIELD_FILENAME).AsString());
		}

	//	Confirm

	CString sConfirm = GetInputLine(CString("\nAre you sure you want to upgrade the arcology? [y/n] : "));
	if (*sConfirm.GetParsePointer() != 'y' && *sConfirm.GetParsePointer() != 'Y')
		return NULL_STR;

	//	Upload the new files.

	for (i = 0; i < dUpgradeDesc.GetCount(); i++)
		{
		CDatum dFileDesc = dUpgradeDesc.GetElement(i);
		const CString &sFilename = dFileDesc.GetElement(FIELD_FILENAME);
		CString sFilespec = fileAppend(sRoot, sFilename);

		CString sResult = UploadFile(theSocket, CMD_UPLOAD_UPGRADE, sFilename, sFilespec);
		printf("%s\n", (LPSTR)sResult);
		}

	//	Complete the upgrade

	return ExecuteArcologyCommand(theSocket, CMD_COMPLETE_UPGRADE);
	}
Beispiel #6
0
bool CAeonView::CreateSecondaryKeys (CHexeProcess &Process, CDatum dData, SEQUENCENUMBER RowID, TArray<CRowKey> *retKeys)

//	CreateSecondaryKeys
//
//	Creates a secondary key from the data and rowID. We return TRUE if all of 
//	the key values are non-nil. FALSE if one or more values are nil.

	{
	int i;
	bool bAllValid = true;

	//	Pull the dimensions from the data

	TArray<CDatum> KeyData;
	for (i = 0; i < m_Keys.GetCount(); i++)
		{
		CDatum dValue;
		CDatum dKeyDesc = m_Keys[i];

		//	If this is a function then we need to evaluate it.

		if (dKeyDesc.CanInvoke())
			{
			TArray<CDatum> Args;
			Args.Insert(dData);

			CHexeProcess::ERunCodes iRun = Process.Run(dKeyDesc, Args, &dValue);

			switch (iRun)
				{
				case CHexeProcess::runOK:
					//	dValue is a valid value for a key
					break;

				case CHexeProcess::runError:
					dValue = CDatum(strPattern("(%s)", dValue.AsString()));
					break;

				default:
					dValue = CDatum(STR_ERROR_KEY);
				}
			}

		//	Otherwise this specifies a field in the data to use as a key

		else
			dValue = dData.GetElement((const CString &)dKeyDesc);

		//	We don't support Nil keys, so we have to replace these with a
		//	a special value.

		if (dValue.IsNil())
			{
			dValue = CDatum(STR_EMPTY_KEY);

			//	If we're not valid if we're excluding nil keys

			if (m_bExcludeNil)
				bAllValid = false;
			}

		//	Add to list

		KeyData.Insert(dValue);
		}


	//	Generate the keys.
	//	If we use list keys then we need to create permuted keys

	retKeys->DeleteAll();
	if (m_bUsesListKeys)
		CreatePermutedKeys(KeyData, 0, TArray<CDatum>(), RowID, retKeys);

	//	Otherwise we just create the key normally

	else
		{
		CRowKey *pNewKey = retKeys->Insert();
		CRowKey::CreateFromDatumAndRowID(m_Dims, KeyData, RowID, pNewKey);
		}

	//	Done

	return bAllValid;
	}
bool CHexeMarkupEvaluator::ProcessResult (SHTTPRequestCtx &Ctx, CHexeProcess::ERunCodes iRun, CDatum dResult)

//	ProcessResult
//
//	Process the result of an evaluation. Returns TRUE if processing should 
//	continue; FALSE if we need RPC or are done processing.

	{
	//	If we have more async calls then return

	if (iRun == CHexeProcess::runAsyncRequest)
		{
		Ctx.iStatus = pstatRPCReady;
		Ctx.sRPCAddr = dResult.GetElement(0);
		Ctx.RPCMsg.sMsg = dResult.GetElement(1);
		Ctx.RPCMsg.dPayload = dResult.GetElement(2);
		Ctx.RPCMsg.dwTicket = 0;
		Ctx.RPCMsg.sReplyAddr = NULL_STR;

		return false;
		}

	//	Otherwise, process the result based on the directive that we're
	//	evaluating.

	bool bResult = true;
	switch (m_iProcessing)
		{
		case tagEval:
			OutputDatum(dResult);
			break;

		case tagFile:
			//	If this is an error, then we return with 404

			if (iRun == CHexeProcess::runError)
				{
				Ctx.iStatus = pstatResponseReady;
				Ctx.Response.InitResponse(http_NOT_FOUND, dResult.AsString());
				bResult = false;
				}

			//	If the result is a list then we expect a fileDesc and fileData.

			else if (dResult.GetCount() >= 2)
				{
				Ctx.iStatus = pstatFileDataReady;
				Ctx.dFileDesc = dResult.GetElement(0);
				Ctx.dFileData = dResult.GetElement(1);
				Ctx.AdditionalHeaders = m_Headers;
				bResult = false;
				}

			//	Otherwise we expect a filePath

			else
				{
				Ctx.iStatus = pstatFilePathReady;
				Ctx.sFilePath = dResult;
				Ctx.AdditionalHeaders = m_Headers;
				bResult = false;
				}
			break;

		case tagHeader:
			bResult = ProcessHeader(Ctx, dResult);
			break;

		case tagIf:
			m_iIfLevel++;
			if (dResult.IsNil())
				m_iIfLevelEnd = m_iIfLevel;
			break;

		case tagRedirect:
			//	If this is an error, then we return with 404

			if (iRun == CHexeProcess::runError)
				{
				Ctx.iStatus = pstatResponseReady;
				Ctx.Response.InitResponse(http_NOT_FOUND, dResult.AsString());
				bResult = false;
				}

			//	Otherwise, we expect a string containing the new address.

			else if (!dResult.IsNil())
				{
				m_dwResponseCode = http_MOVED_PERMANENTLY;
				m_sResponseMsg = STR_MOVED_PERMANENTLY;

				AddHeader(HEADER_LOCATION, dResult);
				}

			break;

		default:
			ASSERT(false);
		}

	m_iProcessing = tagNone;
	return bResult;
	}
bool CHexeMarkupEvaluator::ProcessHeader (SHTTPRequestCtx &Ctx, CDatum dResult)

//	ProcessHeader
//
//	Outputs the given header

	{
	//	Check for error

	if (dResult.IsError())
		{
		m_Output.Write(strPattern(ERR_PROCESSING_HEADER, dResult.AsString()));
		return true;
		}

	//	Processing depends on result type

	switch (dResult.GetBasicType())
		{
		case CDatum::typeNil:
			return true;

		//	If this is a string or anything else, we expect both field and value
		//	are in the same string and we need to parse it.

		default:
			{
			CString sData = dResult.AsString();

			//	Parse into field and value

			char *pPos = sData.GetParsePointer();
			while (strIsWhitespace(pPos))
				pPos++;

			//	Look for the field name

			char *pStart = pPos;
			while (*pPos != ':' && *pPos != '\0')
				pPos++;

			CString sField(pStart, pPos - pStart);
			if (sField.IsEmpty())
				{
				m_Output.Write(strPattern(ERR_NO_HEADER_FIELD, sData));
				return true;
				}

			//	Look for the value

			CString sValue;
			if (*pPos == ':')
				{
				pPos++;
				while (strIsWhitespace(pPos))
					pPos++;

				sValue = CString(pPos);
				}

			//	Done

			CHTTPMessage::SHeader *pNewHeader = m_Headers.Insert();
			pNewHeader->sField = sField;
			pNewHeader->sValue = sValue;
			}
		}

	return true;
	}
Beispiel #9
0
bool CAeonEngine::ParseTableAndView (const SArchonMessage &Msg, 
									 const CHexeSecurityCtx *pSecurityCtx, 
									 CDatum dTableAndView, 
									 CAeonTable **retpTable, 
									 DWORD *retdwViewID,
									 CDatum dKey,
									 CRowKey *retKey)

//	ParseTableAndView
//
//	Parses a datum as follows:
//
//	If a single string, it specifies a table and the default view.
//	If an array with two strings, the first is the table name; the second is the view name.

	{
	CString sError;

	//	If we're not ready, then error

	if (!m_bReady)
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_NOT_READY, Msg);
		return false;
		}

	//	Parse the table names

	CString sTable;
	CString sView;

	if (dTableAndView.GetCount() < 2)
		sTable = dTableAndView.AsString();
	else
		{
		sTable = dTableAndView.GetElement(0).AsString();
		sView = dTableAndView.GetElement(1).AsString();
		}

	//	Make sure we have access

	if (pSecurityCtx && !pSecurityCtx->IsNamespaceAccessible(sTable))
		{
		SendMessageReplyError(MSG_ERROR_NOT_ALLOWED, strPattern(ERR_NOT_IN_SANDBOX, sTable, pSecurityCtx->GetSandboxName()), Msg);
		return false;
		}

	//	Get the table

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return false;
		}

	//	Get the view. If we want a key, take this opportunity to parse it.

	DWORD dwViewID;
	if (retKey)
		{
		if (!pTable->FindViewAndPath(sView, &dwViewID, dKey, retKey, &sError))
			{
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
			return false;
			}
		}

	//	Otherwise just get the view.

	else
		{
		if (!pTable->FindView(sView, &dwViewID))
			{
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY,  strPattern(ERR_UNKNOWN_VIEW, sTable, sView), Msg);
			return false;
			}
		}

	//	Done

	if (retpTable)
		*retpTable = pTable;

	if (retdwViewID)
		*retdwViewID = dwViewID;

	return true;
	}